openfoodfacts / open-prices Goto Github PK
View Code? Open in Web Editor NEWAn open database of food prices - π§ΎπΈπ°π·οΈπ€π½οΈ
License: GNU Affero General Public License v3.0
An open database of food prices - π§ΎπΈπ°π·οΈπ€π½οΈ
License: GNU Affero General Public License v3.0
Admin / moderators could have an easy-to-use interface to make changes (edit or delete price, edit location data...).
Similar to the admin in Django.
see below
Similar to #154 , but for labels_tags
We'll need a PostgreSQL database to store data.
See an example of implementation here : https://github.com/openfoodfacts/folksonomy_api/blob/main/folksonomy/api.py
Idea of using peewee for the ORM
Currently the prices are available anonymously. There are filters available, but none on the "owner".
It would be interesting for the authenticated user to fetch prices that we're created by him (but not allow filtering on other owners to respect privacy) owner data is public, we can filter on any owner
We don't do any backup for now.
Given a proof_id, it is currently not easily possible to get the related prices (and it's price_count).
We could add an extra filter on the PriceFilter
, but there is a privacy risk for private proofs.
An alternative is to create a new route /proofs/<id>/prices
and make sure that the authenticated user is the owner of the proof
We will want to have each Price linked to a Proof.
Currently, we use a single user
table to store the associated token. It's not ideal as we can't be logged in on more than one device (error while uploading photos occur).
We should add a session
table and migrate the tokens to the new table.
The Price
model should store the basic fields :
product_code
price
currency
location_osm_id
& location_osm_type
date
For raw products (fruits, vegetables,...), origins is an information that's important to track (the price is usually different depending on the origin of the country).
The origin can be:
We can use the origin taxonomy (https://static.openfoodfacts.org/data/taxonomies/origins.full.json) and allow users to specific the origin of the product and save it along the price (only for products without barcode).
When fetching prices, we currently get the product_id
& location_id
.
To avoid having to make additional queries, we would like to return the full Product
& Location
objects.
Need to optimize queries to avoid N+1 calls to the DB
Currently, we can't delete a proof once uploaded.
Endpoint: DELETE /api/v1/proofs/:proof_id
This endpoint should deny deleting proofs if:
Currently we consider that a new barcode is necessarily a food product, and we fetch its data from Open Food Facts.
What if a user scans a book ? or a boardgame ? or a deodorant ?
Following #154
We need to add a new filter capability to find only products of a certain category. Bonus : allow filtering by multiple categories as well.
But I'm not exactly sure how to proceed with the fastapi-filter library. I opened an issue : arthurio/fastapi-filter#556
Or maybe I'm missing something ? π
When adding a price, we usually have the product label (e.g. BANANE CRF BIO MH 5 FRUITS IMP
) alongside.
This information could be useful, let's store it !
Price.product_label
? --> product_name
There is lots of interesting info in the proof images :
What if the server was able to do some image recognition, and return to the frontend all of that info ? π€©
Without the product EAN or barcode, how to link to the exact product in the OFF database ?
Price tag | Multiple price tags | Receipt |
---|---|---|
![]() |
![]() |
![]() |
Authenticate users via openfoodfacts.org
See an example of implementation here : https://github.com/openfoodfacts/folksonomy_api/blob/main/folksonomy/api.py
// auth server: https://world.openfoodfacts.org/cgi/auth.pl (pass user_id & password)
// table: auth
// fields: user_id (OFF username), token, last_use
CREATE TABLE auth (token varchar, user_id varchar, last_use timestamp);
CREATE INDEX ON auth (token);
We can't update prices, which starts to become cumbersome to users.
Add a PUT /api/v1/prices
endpoint, that allows to update all price information.
The user should only be allowed to update his/her prices.
When a new location is added, we fill a couple of fields in our database.
For the city field it is a bit tricky, we currently look at ["village", "town", "city", "municipality"]
Is it the best way to do it ?
Currently the landing page is available in only 2 languages :
See this PR - #155 - for an example (French translation).
Improve typing by adding types and if possible making it mypy compatible (no errors)
Some users log in with their e-mail. It is then used as their username. We should fetch their username instead.
From openfoodfacts-explorer I can't query the service, as there is a cross-domain request and the open prices server does not add "openfoodfacts-explorer.vercel.app" Access-Control-Allow-Origin
.
Example: https://openfoodfacts-explorer.vercel.app/products/3175681105423
Currently products are added in Open Prices on a per-scan basis, when a price is added.
What about having a list of the top 500 (or more ?) scanned products in Open Food Facts, and importing them in Open Prices.
We could then display them in the frontend, and nudge users to add prices for these products, displaying their price count :)
It would interesting to display the list of contributors, ranked by number of prices added.
For this, we need:
User
modelprice_count
field that calculates the number of prices added (real-time ? or updated every night ?)We currently have a price
field (mandatory, decimal) for all the items added to the database..
But for products currently discounted, we need an easy way to store the discount-related information.
I see 2 solutions :
1) The price field always stores the current price (full or discounted depending on the item)
price_is_discounted
which would be False by defaultprice_without_discount
which would be available to fill if the above field is True2) The price field always stores the full price
price_is_discounted
which would be False by defaultprice_discounted
which would be available to fill if the above field is TrueWe have the price (stored in Price.price
) and we have the quantity (stored in Product.product_quantity
).
It would interesting to compute and return the price per kg or L.
There seems to be an issue (not sure if a backend or a frontend problem), new prices show up with "1h ago" instead of "1m ago".
I suspect that the timestamps in the backend are stored without timezone.
We'll store the price's location info separately.
We'll fetch the data from OpenStreetMap.
Some fields to store :
osm_id
& osm_type
osm_display_name
osm_lat
osm_lon
For each new product we fetch from Open Food Facts its product_quantity
, a normalized number in g or mL.
We need to find a way to know if the product is a beverage (mL), or solid (g), so that we can display the information accordingly in the frontend (price per kg or price per L).
Linked to #77
What is the best strategy to efficiently get the last known price of a product ?
In the frontend, there are various places where we could display this information to the user :
Moderators are special users that will be allowed to delete/update prices or proofs of other users.
This is necessary to ensure database quality.
Tasks:
We use mimetypes.guess_extension()
to define the extension of the uploaded file
But image/webp
doesn't seem to be managed by the server (nor my local environment - Ubuntu 22.04)
In the frontend, it would be useful for users to fetch prices corresponding to a specific proof
Currently only prices with a EAN code are allowed
Need to add
category_tag
labels
We're starting to get feedback from frontend users who wish to edit or delete their prices (mistake, typos, wrong product...)
We'll store the price's product info separately.
We'll fetch the data from OpenFoodFacts.
Some fields to store :
code
in_off
?off_db
(off
or opf
or obf
or opff
)off_name
off_image_url
Issue to link commits & PRs related to this change
The requirements.txt
file mentionned in the INSTALL.md is wasn't added to the codebase.
Can you add it please ?
Thank you :)
For the v1 we went a bit fast, here is a list of known improvements :
crud.py
& utils.py
)Currently we fetch data from OpenFoodFacts when a price is added and the product is not yet in our database.
But if the product info changes on OFF, or if we add new fields to store, the existing products are not updated.
Idea of creating a new field Product.price_count
.
Helpful for :
How to update :
When we sync the products from OFF, we currently fetch the raw brands
field.
But if we fetched instead the brands_tags
we could have better search & filter capabilities for the Frontend.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.