pythonpython-3.xrestpython-requestsconfigparser

Getting 401 unauthorized status in an API


I was making a POST request in nutritionix API using requests module. In one of the API route which is https://trackapi.nutritionix.com/v2/natural/nutrients, which returns all the necessary details for any food item if we pass json as {"query": <any_name>} and headers as x-app-id and x-app-key.

It works fine in Postman, but in Python it shows 401 unauthorized status if I fetch the x-app-id and x-app-key from .cfg file.

The format of that cfg file is

[nutritionix]
API_ID=<api-id>
API_KEY=<api-key>

I am fetching all those keys using configparser module, I am able to print those keys in the terminal, but it shows 401 error. But if I directly paste these keys into the code directly (which is not recommended), it is showing 200 status.

I am pasting the code below for reference:

import requests
from configparser import ConfigParser

config = ConfigParser()
config.read('./secrets.cfg')

x_app_id = config['nutritionix']['API_ID']
x_app_key = config['nutritionix']['API_KEY']

headers = {
    'Accept':'application/json',
    'Content-Type': 'application/json',
    "x-app-id": x_app_id,
    "x-app-key": x_app_key,
}


url = 'https://trackapi.nutritionix.com/v2/natural/nutrients/'

def get_details(prompt: str):
    food_details = requests.post(url, headers=headers, json={"query": prompt})
    print(food_details)

I don't know why the API key and the ID is not fetching from cfg file, whereas in other files, it is fetching properly.

I was expecting to fetch the API keys from cfg and show the required result from the API.


Solution

  • This code will works

    import requests
    from configparser import ConfigParser
    import json
    
    config = ConfigParser()
    config.read('./secrets.cfg')
    
    x_app_id = config['nutritionix']['API_ID']
    x_app_key = config['nutritionix']['API_KEY']
    
    headers = {
        'Accept':'application/json',
        'Content-Type': 'application/json',
        "x-app-id": x_app_id,
        "x-app-key": x_app_key,
    }
    
    
    url = 'https://trackapi.nutritionix.com/v2/natural/nutrients/'
    
    def get_details(prompt: str):
        food_details = requests.post(url, headers=headers, json={"query": prompt})
        print(json.dumps(food_details.json(), indent=2))
    
    get_details('for breakfast i ate 2 eggs, bacon, and french toast')
    

    And credential without " or ' in secrets.cfg file.

    [nutritionix]
    API_ID=xxxxxxxx
    API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    

    Result

    $ python3 get-nutrients.py 
    Status Code 200
    JSON Response  {
      "foods": [
        {
          "food_name": "eggs",
          "brand_name": null,
          "serving_qty": 2,
          "serving_unit": "large",
          "serving_weight_grams": 100,
          "nf_calories": 143,
          "nf_total_fat": 9.51,
          "nf_saturated_fat": 3.13,
          "nf_cholesterol": 372,
          "nf_sodium": 142,
          "nf_total_carbohydrate": 0.72,
          "nf_dietary_fiber": 0,
          "nf_sugars": 0.37,
          "nf_protein": 12.56,
          "nf_potassium": 138,
          "nf_p": 198,
          "full_nutrients": [
            {
              "attr_id": 203,
              "value": 12.56
            },
    ...
    

    enter image description here