Home > Blockchain >  How to tell Python to ignore part of API request?
How to tell Python to ignore part of API request?

Time:02-20

had a few Python classes and tinkering with an old project. I'm using an API to help the user decide on a recipe to cook. One of the questions is if they have dietary/meal type requirements. The API documentation has parameters for the requirements but I don't know how to make it work if the user has no dietary/meal type requirements. I tried to do an if else statement but PyCharm got confused. This is my code:

import requests


def recipe_search(ingredient, mealtype, dietary):
    # You need to register as a developer with Edamame to get an Application ID and Key
    # These can be found in the applications section of the dashboard once you have signed in
    app_id = "INSERT APP ID"
    app_key = "INSERT APP KEY"
    result = requests.get(
        'https://api.edamam.com/search?q={}&app_id={}&app_key={}&mealType={}&health'.format(ingredient, app_id, app_key,
                                                                                            mealtype, dietary))
    data = result.json()

    return data["hits"]


def run():
    ingredient = input("Enter an ingredient: ")
    mealtype = input(
        "What type of meal do you want? \n Choose from breakfast/lunch/dinner/snack/teatime/any. You can input multiple meals but they must be seperated with commas.")
    dietary = input(
        'Do you have any dietary requirements? \n Choose and enter from vegan/vegetarian/paleo/dairy-free/gluten-free/wheat-free/fat-free/low-sugar/egg-free/peanut-free/tree-nut-free/soy-free/fish-free/shellfish-free. \n You can enter multiple dietary requirements, but they must be seperated with commas.')
    results = recipe_search(ingredient, mealtype, dietary)

    for result in results:
        recipe = result["recipe"]

        print(recipe["label"])
        print(recipe["uri"])
        print()


run()

This is the API that I'm using: https://developer.edamam.com/edamam-docs-recipe-api

CodePudding user response:

I might suggest building your list of URL params in such a way that any param with an empty value is omitted:

def recipe_search(ingredient, mealtype, dietary):
    params = "&".join(f"{param}={value}" for param, value in {
        'app_id': "INSERT APP ID",
        'app_key': "INSERT APP KEY",
        'q': ingredient,
        'mealType': mealtype,
        'health': dietary,
    }.items() if value)
    return requests.get(f"https://api.edamam.com/search?{params}").json()

That way if the user inputs an empty string, the corresponding param is omitted from the API call completely instead of being sent as an empty string.

CodePudding user response:

This sounds like a potential use case for the dataclass-wizard:

from dataclasses import dataclass
from dataclass_wizard import asdict, json_field


@dataclass
class RequestParams:
    app_id: str = json_field('app_id', all=True)
    app_key: str = json_field('app_key', all=True)
    q: str = ''
    meal_type: str = ''
    health: str = ''


def recipe_search(ingredient, mealtype, dietary):
    params = RequestParams("INSERT APP ID", "INSERT APP KEY",
                           ingredient, mealtype, dietary)

    return requests.get('https://api.edamam.com/search',
                        params=asdict(params, skip_defaults=True)).json()

Some notes for clarification:

  • The default key transform for serialization is camelCase, so mealType instead of meal_type.
  • skip_defaults is passed here to skip including fields that are blank in the serialized dict object (i.e. fields for which user provided no input)
  • json_field can be thought of as alias to dataclasses.field(). I'm using it here mainly to control the casing of the field in the serialized result.
  • Related