A FastAPI proxy for OpenFoodFacts
Project description
openfoodfacts-proxy
A FastAPI proxy for OpenFoodFacts
Supports:
- https://openfoodfacts.github.io/openfoodfacts-server/api/ref-v2/
- https://openfoodfacts.github.io/openfoodfacts-server/api/ref-v3/
- https://search.openfoodfacts.org/docs
Features
- Local-first product reads — serves product data from a local MongoDB cache with automatic upstream fallback
- API v2 and v3 support — compatible with both OFF API versions, including field projection
- Transparent upstream proxying — unrecognized requests are forwarded to the real OFF server
- Full and delta sync — import the complete OFF MongoDB dump or apply incremental delta updates
- Rate limiting — configurable per-endpoint rate limits (product reads, search)
- Search integration — local v2 search with upstream fallback; search-a-licious proxy support
- Taxonomy caching — periodic sync of categories, brands, countries, ingredients, and labels
- Image URL rewriting — rewrite OFF S3 image URLs through your own route/CDN
- Reference data endpoints — CGI-compatible and v2/v3 taxonomy/reference routes
- Facet browsing — serve facet-based product listings from the local cache
- CLI tooling —
serve,import-full, andimport-deltacommands
Installation
With pip:
python -m pip install openfoodfacts-proxy
With uv:
uv add openfoodfacts-proxy
How to use it
CLI
Start the proxy server:
openfoodfacts-proxy serve --host 0.0.0.0 --port 8000
Import the full OFF MongoDB dump:
openfoodfacts-proxy import-full
Apply delta updates:
openfoodfacts-proxy import-delta
Python
from openfoodfacts_proxy.app import create_app
app = create_app()
Supported endpoints
| Endpoint | Description |
|---|---|
GET /api/v2/product/{barcode} |
Product read (v2 format) with optional fields query |
GET /api/v3/product/{barcode} |
Product read (v3 format) with optional fields query |
GET /api/v2/search |
Search products with filters and pagination |
GET /{facet_type}/{facet_value}.json |
Facet-based product listings |
Configuration
All settings are configurable via environment variables with the OFF_PROXY_ prefix:
| Variable | Default | Description |
|---|---|---|
OFF_PROXY_MONGODB_URI |
mongodb://mongodb:27017 |
MongoDB connection string |
OFF_PROXY_MONGODB_DB |
openfoodfacts |
Database name |
OFF_PROXY_OFF_BASE_URL |
https://world.openfoodfacts.org |
Upstream OFF server |
OFF_PROXY_PRODUCT_RATE_LIMIT |
15 |
Max product requests per window |
OFF_PROXY_SEARCH_RATE_LIMIT |
10 |
Max search requests per window |
OFF_PROXY_RATE_LIMIT_WINDOW_SECONDS |
60 |
Rate limit window duration |
OFF_PROXY_UPSTREAM_TIMEOUT_SECONDS |
30.0 |
Timeout for upstream requests |
OFF_PROXY_STARTUP_SYNC_ENABLED |
true |
Run full sync on startup |
OFF_PROXY_SCHEDULER_ENABLED |
true |
Enable periodic delta/taxonomy sync |
OFF_PROXY_REWRITE_IMAGE_URLS |
true |
Rewrite OFF image URLs |
Docker
Dockerfile.aio builds the default all-in-one image and starts MongoDB inside the same container.
Dockerfile builds the app-only image and expects MongoDB to run in a separate container.
Build the all-in-one image:
docker build -f Dockerfile.aio -t openfoodfacts-proxy:aio .
Build the separate-DB image:
docker build -f Dockerfile -t openfoodfacts-proxy:app .
Run the default all-in-one container:
docker compose up --build
Run with a separate MongoDB container:
docker compose -f docker-compose.production.yml up --build
Image URL rewriting is configurable so OFF image URLs can be exposed through your own Cloudflare route instead of leaking S3 bucket details.
Set OFF_PROXY_REWRITE_IMAGE_URLS=false to disable rewriting completely.
The runtime settings are split into OFF_PROXY_IMAGE_ROUTE_BASE_URL, OFF_PROXY_IMAGE_BUCKET_NAME, OFF_PROXY_IMAGE_BUCKET_REGION, and OFF_PROXY_IMAGE_BUCKET_PREFIX.
With the defaults, a source URL like https://images.openfoodfacts.org/images/products/301/762/042/2003/front_en.820.400.jpg is rewritten to /images/data/301/762/042/2003/front_en.820.400.jpg.
If you want custom rewriting logic, pass your own OpenFoodFactsUrlMapper implementation into create_app(...).
OFF SDK E2E
The OFF SDK integration suite does not use a dedicated Compose file. It starts the proxy stack directly and always seeds MongoDB from the committed fixture dump plus fixture delta under tests/integration/off_sdk/fixtures/, not from the public OFF dataset.
Run it explicitly so normal test runs stay fast:
OFF_PROXY_RUN_SDK_E2E=1 uv run pytest tests/integration/test_off_sdk_proxy_e2e.py -m off_sdk_e2e
By default the test prefers a real local MongoDB process when mongod and mongosh are available, then falls back to Docker. You can force either mode explicitly:
OFF_PROXY_RUN_SDK_E2E=1 OFF_PROXY_SDK_E2E_MODE=local uv run pytest tests/integration/test_off_sdk_proxy_e2e.py -m off_sdk_e2e
OFF_PROXY_RUN_SDK_E2E=1 OFF_PROXY_SDK_E2E_MODE=docker uv run pytest tests/integration/test_off_sdk_proxy_e2e.py -m off_sdk_e2e
Local mode requires mongod and mongosh on PATH.
The committed fixtures live under tests/integration/off_sdk/fixtures/. The data/off-sdk-e2e/ directory is disposable gitignored runtime state written by the test harness.
Docs
uv run mkdocs build -f ./mkdocs.yml -d ./_build/
Update template
copier update --trust -A --vcs-ref=HEAD
Credits
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file openfoodfacts_proxy-0.1.0.tar.gz.
File metadata
- Download URL: openfoodfacts_proxy-0.1.0.tar.gz
- Upload date:
- Size: 46.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.11 {"installer":{"name":"uv","version":"0.11.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
391257022a2c8c88a35f40018cfa50008de71bccd8c5143b4df40ddcacf4c489
|
|
| MD5 |
7681831cf6c1a8af4e236e4950c251e1
|
|
| BLAKE2b-256 |
5f90ab5f1bb3ca25210ee39008a0aefbf8f1ba0db556246baa8af882689f64ef
|
File details
Details for the file openfoodfacts_proxy-0.1.0-py3-none-any.whl.
File metadata
- Download URL: openfoodfacts_proxy-0.1.0-py3-none-any.whl
- Upload date:
- Size: 86.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.11 {"installer":{"name":"uv","version":"0.11.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c83b49c7218de20d9ac1da594b94e0bd1d7ce3ef3493db3367ae7e87ebc970ab
|
|
| MD5 |
49cfc09b5f1fec433693ef1dc0c713e1
|
|
| BLAKE2b-256 |
47175b94f89007a9fb418f62f322e1fe2f3609a538483e96caee20368b8e00c4
|