'How to tell Python to ignore part of API request?

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



Solution 1:[1]

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.

Solution 2:[2]

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.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2