-
-
Notifications
You must be signed in to change notification settings - Fork 68
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for API v3 Product WRITE requests to add / edit packaging components #617
Comments
curl -X POST https://off:off@world.openfoodfacts.dev/api/v3/product/12345678 -H "Content-Type: application/json" -d '{"product": { "packagings_add": [{"shape": "bottle"}]}, "fields": "updated"}' |
@teolemon I've managed to send the following query to dev from off-dart: {
"tags_lc": "fr",
"product": {
"packagings_add": [
{
"shape": "bottle",
"material": "glass",
"recycling": "recycler",
"number_of_units": 1,
}
],
},
"fields": "updated",
} In trial and error mode, I've got this reply from the server: {
"errors": [],
"product": {
"packagings": [{
"material": "en:glass",
"number_of_units": 1,
"recycling": "fr:recycling",
"shape": "en:bottle"
}, {
"material": "en:glass",
"number_of_units": 1,
"recycling": "fr:recyclage",
"shape": "en:bottle"
}, {
"material": "en:glass",
"number_of_units": 1,
"recycling": "en:recycle",
"shape": "en:bottle"
}]
},
"status": "success",
"warnings": []
} @stephanegigandet Still, I have some questions:
|
Instead of packagings_add, you can send the same structure in the packagings field, and it will replace the existing structure.
tags_lc is the language that you use in shape, materials etc. (if you send something like "bouteille", if you send the taxonomy id en:bottle, then it's not used) you can send the "lc" field to get localized warnings and errors messages, although as they are not translated yet, you will get English |
There is one version of the doc here: https://redocly.github.io/redoc/?url=https://raw.githubusercontent.com/openfoodfacts/openfoodfacts-server/packagings-api-2/docs/reference/api-v3.yml#operation/post-api-v3-product-barcode But the OpenAPI file to documentation is not showing the product fields unfortunately. :-( |
Thank you @stephanegigandet for your answers! In the context of Smoothie:
|
Btw it's very convenient to be able to get the resulting |
Yes, the "packagings_add" method is for things like Robotoff, which can detect that there is a plastic bottle, or some logo that says "Aluminium", or recycling instruction "Bottle to recycle".
Yes.
Right, hopefully v3 product write will be extended to support everything from v2, but it will take some time. |
@stephanegigandet What about READing packagings: will they all follow the new format, including history, regardless of having been written with an old format? |
We will convert the old format to the new format. |
@monsieurtanuki the new API is live on .net and .org |
@stephanegigandet Just checking:
cf. https://fr.openfoodfacts.org/api/v2/product/3661344723290?fields=all&lc=en "packaging": "",
"packaging_hierarchy": [],
"packaging_lc": "fr",
"packaging_old": "fr:carton",
"packaging_old_before_taxonomization": "carton",
"packaging_tags": [],
"packaging_text": "1 opercule en métal à recycler\r\n1 pot en papier à recycler\r\n1 couvercle en papier à recycler",
"packaging_text_fr": "1 opercule en métal à recycler\r\n1 pot en papier à recycler\r\n1 couvercle en papier à recycler",
"packagings": [{
"material": "en:metal",
"number": "1",
"recycling": "en:recycle",
"shape": "en:seal"
}, {
"material": "en:paper",
"number": "1",
"recycling": "en:recycle",
"shape": "en:pot"
}, {
"material": "en:paper",
"number": "1",
"recycling": "en:recycle",
"shape": "en:lid"
}], |
At this point, packaging and packaging_tags can still be written, and they can still be read. In the future, it's likely that will remove the write feature for packaging, and possibly use packaging_tags to return facets that would be derived from the new packagings structure. So the best thing I think would be to:
Yes. Anything written to it will be used as input for the new packagings structure.
Yes. |
@stephanegigandet Little problem: READing
[
{"shape": "en:seal", "material": "en:metal", "recycling": "en:recycle"},
{"shape": "en:pot", "material": "en:paper", "recycling": "en:recycle"},
{"shape": "en:lid", "material": "en:paper", "recycling": "en:recycle"}
]
|
@monsieurtanuki: good catch, I forgot to code this part. I'll add it. This is what is specified in the OpenAPI file: [ |
@monsieurtanuki here is the corresponding server side PR, could you review it? openfoodfacts/openfoodfacts-server#7749 If you want to test, it's currently live on the .dev server: Note that you have to use v3 to get the new format for packagings (so that apps using v2 don't break). The response format (the wrapper) has slightly changed to give more details about warnings, errors etc. |
@stephanegigandet Now I can READ ( How am I supposed to specify a new value for a shape? |
I'm leaving my feedback here on potential bugs I've encountered when testing the current version of the API. Overwriting packaging dataIt seems there is an issue when trying to overwrite packaging data. import requests
username = "raphael0202"
password = "*********"
barcode = "3273220180259"
tld = "net"
auth = ("off", "off") if tld == "net" else None
url = f"https://world.openfoodfacts.{tld}/api/v3/product/{barcode}"
json = {
"product": {
"packagings": [{"material": {"id": "en:pp-polypropylene"}, "shape": {"id": "en:lid"}}]
},
"username": username,
"password": password,
}
r = requests.patch(url=url, json=json, auth=auth)
r.raise_for_status()
response = r.json()
print(response["product"]["packagings"]) According to the documentation, the data is supposed to be overwritten, which isn't the case (packaging data is unchanged). Adding new packaging item in local languageimport requests
username = "raphael0202"
password = "Z4WcL2T9HZ8k2"
barcode = "3335880004990"
tld = "net"
auth = ("off", "off") if tld == "net" else None
url = f"https://world.openfoodfacts.{tld}/api/v3/product/{barcode}"
json = {
"product": {
"tags_lc": "fr",
"packagings_add": [
{
"material": {"lc_name": "verre"},
"shape": {"lc_name": "pot"},
"recycling": {"lc_name": "à recycler"},
"number_of_units": "1",
}
],
},
"username": username,
"password": password,
}
r = requests.patch(url=url, json=json, auth=auth)
r.raise_for_status()
response = r.json()
print(response["product"]["packagings"])
>>>[{'material': 'en:metal', 'shape': 'en:capsule'}, {'material': 'en:glass', 'shape': 'en:jar'}, {'material': 'en:HASH(0x559321f11308)', 'number_of_units': 1, 'recycling': 'en:HASH(0x55930cf56738)', 'shape': 'en:HASH(0x5592f7fd7dd8)'}] The |
@monsieurtanuki @raphael0202 |
@monsieurtanuki @raphael0202 It's fixed in the PR and on the .dev server: curl -k -X PATCH http://off:off@world.openfoodfacts.dev:8701/cgi/display.pl?api/v3/product/12345678977 -H "Content-Type: application/json" -d '{"product": { "packagings": [{"shape": {"lc_name": "bottle"}, "material": {"id": "en:plastic"}}]}, "fields": "updated"}' {"code":"12345678977","errors":[],"product":{"packagings":[{"material":{"id":"en:plastic","lc_name":"Plastic"},"shape":{"id":"en:bottle","lc_name":"Bottle"}}]},"status":"success_with_warnings","warnings":[{"field":{"default_value":"en","id":"tags_lc"},"impact":{"id":"warning","lc_name":"Warning","name":"Warning"},"message":{"id":"missing_field","lc_name":"Missing field","name":"Missing field"}},{"field":{"id":"number_of_units"},"impact":{"id":"field_ignored","lc_name":"Field ignored","name":"Field ignored"},"message":{"id":"missing_field","lc_name":"Missing field","name":"Missing field"}},{"field":{"id":"recycling","value":null},"impact":{"id":"field_ignored","lc_name":"Field ignored","name":"Field ignored"},"message":{"id":"missing_field","lc_name":"Missing field","name":"Missing field"}}]} |
@stephanegigandet I've tried this morning on
{
"errors": [{
"field": {
"id": "api_method",
"value": "POST"
},
"impact": {
"id": "failure",
"lc_name": "Failure",
"name": "Failure"
},
"message": {
"id": "invalid_api_method",
"lc_name": "Invalid API method",
"name": "Invalid API method"
}
}],
"status": "failure",
"warnings": []
}
{
"errors": [{
"field": {
"id": "product"
},
"impact": {
"id": "failure",
"lc_name": "Failure",
"name": "Failure"
},
"message": {
"id": "missing_field",
"lc_name": "Missing field",
"name": "Missing field"
}
}],
"status": "failure",
"warnings": []
} |
@monsieurtanuki: for v3 of the API, we decided to adopt the standard REST practices: the READ query must use GET, and the WRITE query must use PATCH. Both the WRITE and READ requests have the same path: /api/v3/[barcode] , they differ by the method GET or PATCH. |
@stephanegigandet I have no strong opinions regarding REST, but READ=GET goes against #414. That's possible to rollback, as long as we double-check that the user credentials are never in the URL. Currently in off-dart:
|
Yes, it's a change from #414 , there was a discussion about methods and moving towards the REST best practices. |
@stephanegigandet OK for using GET for Should we also consider changing current POST (but READ) queries in off-dart into GET, for consistency and in application of REST best practices? |
That's one point. The other point is about the discrepancies in .org between |
fields=all returns fields as they are stored internally, I will rename it to fields=raw or something, and make fields=all obey the v3 rules if sent |
Sounds perfect! |
@monsieurtanuki : the new version is live on .org and .net |
@stephanegigandet I'm almost done with coding, but I think there's something missing in WRITE, at least in PROD. For this one, I was logged in as monsieurtanuki:
|
@monsieurtanuki I think I forgot to take into account the user and password passed in the JSON body, I will add support for it, thanks for the report. |
@monsieurtanuki the authentification is fixed by this PR: openfoodfacts/openfoodfacts-server#7813 Please note that I renamed userid to user_id to be consistent with the field name used in v2. If you want to test, it's live on https://world.openfoodfacts.dev |
@stephanegigandet Thank you, it does work in DEV, now I see the user (https://world-fr.openfoodfacts.dev/produit/3330720237361/pate-a-tartiner-noisette-du-lot-et-garonne-cacao-lucien-georgelin): Not in PROD yet: please ping me when you roll out to NET and ORG. |
@monsieurtanuki it's now in prod |
@stephanegigandet Unfortunately my computer power cable crashed this morning. I won't be able to PR before days. If someone else feels like coding this issue, I won't be offended. |
@monsieurtanuki Sorry to hear that. :( |
@stephanegigandet I have a new cable now: I'm back ;) |
@monsieurtanuki Wonderful :) |
@stephanegigandet Regarding api v3 and "get products" queries, in Smoothie we sometimes use "user" queries (e.g. "the products I contributed to"), and for that we use a different syntax. Instead of
But it doesn't look like we can apply the |
@monsieurtanuki I also added recently a new field "packagings_complete" which takes values 0 or 1, to indicate if all the packaging components are listed: https://github.com/openfoodfacts/openfoodfacts-server/pull/7856/files |
@monsieurtanuki for the "user" queries, I will need to implement /api/v3/search but there won't be server deployments until the first week of January. There is a possible workaround: It works for editors, photographers, informers It doesn't work for contributor |
@stephanegigandet Actually I wouldn't call it a workaround but the solution! Of course, if it could work for "contributor" that would solve it all. For the moment I will make it work in off-dart for editors, photographers and informers. |
@stephanegigandet Actually there is probably a tag for "contributor": wouldn't it be And for "to be completed", I interpret that as "all the products I'm an informer for and with the state Therefore I'm done here, just about to PR: I got the same counts with the old v2 (and "different" URI) and with the new v3 (all with the "standard" |
The new API v3 to add/edit packaging components is almost finalized and implemented (but deployed only on the .dev server currently).
Server-side PR with the documentation and implementation: openfoodfacts/openfoodfacts-server#7614
There could still be minor changes (in particular, it is likely that we will use PATCH requests instead of POST requests). I will update this bug when it is merged, deployed on .net and then on .org
If you have feedback about the API, please let me know, we can still change things if needed.
Note that future v3 APIs will use the same model for reporting warnings and errors etc. so it would be good to have generic code for it. In particular, the API v3 for product READ is already implemented as well (with full v2 features support).
The API v3 product WRITE currently only supports packaging data, so we will need to keep the existing code for API v2 for some time.
The text was updated successfully, but these errors were encountered: