Skip to content

Commit

Permalink
docs: complete tutorial to write Nutri-Score data for a product (#7640)
Browse files Browse the repository at this point in the history
  • Loading branch information
Roxie-32 authored Nov 8, 2022
1 parent d0f1156 commit 0b13c40
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 38 deletions.
31 changes: 6 additions & 25 deletions docs/reference/api.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,9 @@ paths:
content:
multipart/form-data:
schema:
#TODO: Include all possible request body like comment, brand , label etc.
$ref: ./requestBodies/add_photo_to_existing_product.yaml
examples: {}
description: ''

/cgi/ingredients.pl:
parameters: []
get:
Expand Down Expand Up @@ -171,12 +169,10 @@ paths:
the OFF API allows you to make api calls to automate this process.
You can rotate existing photos by setting the angle to 90º, 180º, or 270º clockwise.
parameters:
#TODO: Describe these parameters
- $ref: '#/components/parameters/code'
- $ref: '#/components/parameters/id'
- $ref: '#/components/parameters/imgid'
- $ref: '#/components/parameters/angle'

tags:
- Write Requests
/cgi/product_jqm2.pl:
Expand All @@ -189,14 +185,12 @@ paths:
content:
application/json:
schema:
#TODO: Explain the different response fields
$ref: ./responses/add_or_edit_a_product.yaml
parameters: []
requestBody:
content:
multipart/form-data:
schema:
#TODO: Include all possible request body like comment, brand , label etc.
$ref: ./requestBodies/add_or_edit_a_product.yaml
tags:
- Write Requests
Expand Down Expand Up @@ -224,7 +218,6 @@ paths:
- $ref: '#/components/parameters/categories_tags_en'
- $ref: '#/components/parameters/labels_tags_en'
- $ref: '#/components/parameters/fields'

parameters: []
/cgi/suggest.pl:
get:
Expand All @@ -237,7 +230,6 @@ paths:
content:
application/json:
schema:
#TODO: Document example response properly
type: array
examples: {}
operationId: get-cgi-suggest.pl
Expand All @@ -254,15 +246,13 @@ components:
Product:
$ref: ./schemas/product.yaml
parameters:

id:
schema:
type: string
example: ingredients_en
in: query
name: id
required: true

code:
schema:
type: string
Expand All @@ -271,39 +261,34 @@ components:
name: code
description: Barcode of the product
required: true

process_image:
schema:
type: string
example: '1'
in: query
name: process_image
required: true

ocr_engine:
schema:
type: string
example: google_cloud_vision
in: query
name: ocr_engine
required: true

imgid:
schema:
type: string
example: '1'
type: string
example: '1'
in: query
name: imgid
required: true

angle:
schema:
type: string
example: '90'
type: string
example: '90'
in: query
name: angle
required: true

categories_tags_en:
schema:
type: string
Expand All @@ -312,33 +297,29 @@ components:
name: categories_tags_en
description: |
The category of products you are searching for.
labels_tags_en:
labels_tags_en:
schema:
type: string
example: organic
in: query
name: labels_tags_en
description: |
The labels of products you are searching for.
fields:
schema:
schema:
type: string
example: 'code,product_name'
in: query
name: fields
description: |
The fields to be returned from the product object can also be limited.
If not specified, it returns the entire product object response.
tagtype:
schema:
type: string
example: additives
in: query
name: tagtype

term:
schema:
type: string
Expand Down
145 changes: 132 additions & 13 deletions docs/tutorials/using-the-OFF-API-tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<!--Add a brief introduction of what the tutorial does -->
## Scan A Product To Get Nutri-score

This basic tutorial shows you can get the Nutri-score of a product, for instance, to display it in a mobile app after scanning the product barcode. Let's use [Nutella Ferrero](https://world.openfoodfacts.org/product/3017624010701/nutella-nutella-ferrero) as the product example for this tutorial.
This basic tutorial shows you can get the Nutri-score of a product, for instance, to display it in a mobile app after scanning the product barcode. Let's use [Nutella Ferrero](https://world.openfoodfacts.net/product/3017624010701/nutella-nutella-ferrero) as the product example for this tutorial.

<!-- Meet Dave. Dave is an active Open Food Facts contributor and a developer who wants to build HealthyFoodChoices, an Android app aimed at conscious consumers that buy healthy products. He has a consumer called Anna. Anna wants to know more on the nutritional facts of Nutella - Ferrero from the HealthyFoodChoices app. Dave needs his app to make an API call to provide her with this information. -->

Expand All @@ -16,14 +16,14 @@ No Authentication is required to make a query to Get A Product Nutri-score.

Make a `GET` request to the `Get A Product By Barcode` endpoint.

```bash
https://world.openfoodfacts.org/api/v2/product/{barcode}
```text
https://world.openfoodfacts.net/api/v2/product/{barcode}
```

The `{barcode}` is the barcode number of the product you are trying to get. The barcode for **Nutella Ferrero** is **3017624010701**. Then the request path to get product data for **Nutella Ferrero** will look like this:

```bash
https://world.openfoodfacts.org/api/v2/product/3017624010701
```text
https://world.openfoodfacts.net/api/v2/product/3017624010701
```

The response returns every data about Nutella Ferrero on the database. To get the nutriscore, we need to limit the response by specifying the nutriscore field, which is the `nutrition_grades` and `product_name`.
Expand All @@ -35,11 +35,11 @@ To limit the response of the Get A Product By Barcode response, use query parame

The request path will now look like this:

```bash
https://world.openfoodfacts.org/api/v2/product/3017624010701?fields=product_name,nutriscore_data
```text
https://world.openfoodfacts.net/api/v2/product/3017624010701?fields=product_name,nutriscore_data
```

### Nutri-score Response
### Nutri-Score Response

The response returned contains an object of the `code`, `product`, `status_verbose`, and `status`. The `product` object contains the fields specified in the query: the `product_name` and the `nutrition_grades`. The status also states if the product was found or not.

Expand All @@ -55,14 +55,14 @@ The response returned contains an object of the `code`, `product`, `status_verbo
}
```

### Nutri-score Computation
### Nutri-Score Computation

If you would like to be able to show how the score is computed, add some extra fields like `nutriscore_data` and `nutriments`.

The request path to get the nutriscore computation for Nutella-Ferroro will be :
The request path to get the Nutri-Score computation for Nutella-Ferroro will be :

```bash
https://world.openfoodfacts.org/api/v2/product/3017624010701?fields=product_name,nutriscore_data,nutriments,nutrition_grades
```text
https://world.openfoodfacts.net/api/v2/product/3017624010701?fields=product_name,nutriscore_data,nutriments,nutrition_grades
```

The `product` object in the response now contains the extra fields to show how the nutriscore was computed.
Expand Down Expand Up @@ -106,4 +106,123 @@ The `product` object in the response now contains the extra fields to show how t

For more details, see the reference documentation for [Get A Product By Barcode](https://openfoodfacts.github.io/openfoodfacts-server/reference/api.html#tag/Read-Requests/operation/get-product-by-barcode)

<!-- Probably have a conclusion that links to the next possible topic eg filter countries using lc and cc-->
<!-- Probably have a conclusion that links to the next possible topic eg filter countries using lc and cc-->

## Completing products to get the Nutri-Score

### Products without a Nutri-Score

When these fields are missing in a nutriscore computation response, it means that the product does not have a Nutri-Score computation due to some missing nutrition data.

Lets look at the [100% Real Orange Juice](https://world.openfoodfacts.net/api/v2/product/0180411000803/100-real-orange-juice?product_name,nutriscore_data,nutriments,nutrition_grades). If the product nutrition data is missing some fields, you can volunteer and contribute to it by getting the missing tags and writing to the OFF API to add them.

<!-- I dont know if using 100% Real Orange Juice is a good approach for now , should we state that it was not computed at the time of writing this article just incase it gets computed in future or there is a product we can use to test this that wont change in future ? -->

To know the missing tags, you need the `misc-tags` field from the response.

`https://world.openfoodfacts.net/api/v2/product/0180411000803/100-real-orange-juice?fields=misc_tags`

The response shows the missing fields and category needed to compute the Nutri-Score.

```json
{
"code": "0180411000803",
"product": {
"misc_tags": [
"en:nutriscore-not-computed",
"en:nutriscore-missing-category",
"en:nutrition-not-enough-data-to-compute-nutrition-score",
"en:nutriscore-missing-nutrition-data",
"en:nutriscore-missing-nutrition-data-sodium",
"en:ecoscore-extended-data-not-computed",
"en:ecoscore-not-computed",
"en:main-countries-new-product"
]
},
"status": 1,
"status_verbose": "product found"
}
```

The sample response above for 100% Real Orange Juice `misc_tags` shows that the Nutri-Score is missing category (`en:nutriscore-missing-category`) and sodium(salt) (`en:nutriscore-missing-nutrition-data-sodium`). Now you can write to the OFF API to provide these nutriment data (if you have them) so that the Nutri-Score can be computed.

### Write data to make Nutri-Score computation possible

The WRITE operations in the OFF API require authentication, therefore you need a valid `user_id` and `password` to write the missing nutriment data to 100% Real Orange Juice.

> Sign up on the [Open Food Facts App](https://world.openfoodfacts.net/), to get your `user_id` and `password` if you dont have.
To write data to a product, make a `POST` request to the [`Add or Edit A Product`](https://openfoodfacts.github.io/openfoodfacts-server/reference/api.html#tag/Write-Requests/operation/post-cgi-product_jqm2.pl) endpoint.

```text
https://world.openfoodfacts.net/cgi/product_jqm2.pl
```

For authentication, add your valid `user_id` and `password` as body parameters to your request. The `code` (barcode of the product to be added/edited), `user_id` and `password` are required fields when adding or editing a product. Then, include other product data to be added in the request body.

To write `sodium` and `category` to 100% Real Orange Juice so that the Nutri-Score can be computed, the request body should contain these fields :

| Key | Value | Description |
| ------------- |:-------------:| -----:|
| user_id | *** | A valid user_id |
| password | *** | A valid password |
| code | 0180411000803 | The barcode of the product to be added/edited |
| nutriment_sodium | 0.015 | Amount of sodium |
| nutriment_sodium_unit | g | Unit of sodium relative to the amount |
| categories | Orange Juice | Category of the Product |

Using curl:

```bash
curl -XPOST -u off:off -x POST https://world.openfoodfacts.net/cgi/product_jqm2.pl \
-F user_id=your_user_id -F password=your_password \
-F code=0180411000803 -F nutriment_sodium=0.015 -F nutriment_sodium_unit=g -F categories="Orange Juice"
```

If the request is succesful, it returns a response that indicated that the fields have been saved.

```json
{
"status_verbose": "fields saved",
"status": 1
}
```

### Read newly computed Nutri-Score

Now, let's check if the Nutri-Score for 100% Real Orange Juice has been computed now that we have provided the missing data. Make a GET request to `https://world.openfoodfacts.net/api/v2/product/0180411000803?fields=product_name,nutriscore_data,nutriments,nutrition_grades` for Nutri-Score of 100% Real Orange Juice. The response now contains the Nutri-Score computation:

```json
{
"code": "0180411000803",
"product": {
"nutriments": {
"carbohydrates": 11.864406779661,
.
.
.
"sugars_unit": "g",
"sugars_value": 11.864406779661
},
"nutriscore_data": {
"energy": 195,
"energy_points": 7,
"energy_value": 195,
.
.
.
"sugars_value": 11.86
},
"nutrition_grades": "c",
"product_name": "100% Real Orange Juice"
},
"status": 1,
"status_verbose": "product found"
}
```

For more details, see the reference documentation for [Add or Edit A Product](https://openfoodfacts.github.io/openfoodfacts-server/reference/api/#tag/Write-Requests/operation/post-cgi-product_jqm2.pl)

You can also check the reference cheatsheet to know how to add/edit other types of product data.

<!-- Include the link of the cheatsheet once it is published. -->

0 comments on commit 0b13c40

Please sign in to comment.