Spaces:
Sleeping
Sleeping
| import requests | |
| import json | |
| import os | |
| from dataclasses import dataclass | |
| from typing import List | |
| READ_KEY_FROM_FILE = True | |
| def read_json_to_dict(file_path) -> dict: | |
| try: | |
| with open(file_path, 'r') as file: | |
| data = json.load(file) | |
| return data | |
| except FileNotFoundError: | |
| print("File not found at the specified path.") | |
| return {} | |
| except json.JSONDecodeError: | |
| print("Error decoding JSON file.") | |
| return {} | |
| DietChoices = [ | |
| None, | |
| "balanced", | |
| "high-fiber", | |
| "high-protein", | |
| "low-carb", | |
| "low-fat", | |
| "low-sodium"] | |
| HealthChoices = [ | |
| None, | |
| "alcohol-cocktail", | |
| "alcohol-free", | |
| "celery-free", | |
| "crustacean-free", | |
| "dairy-free", | |
| "DASH", | |
| "egg-free", | |
| "fish-free", | |
| "fodmap-free", | |
| "gluten-free", | |
| "immuno-supportive", | |
| "keto-friendly", | |
| "kidney-friendly", | |
| "kosher", | |
| "low-fat-abs", | |
| "low-potassium", | |
| "low-sugar", | |
| "lupine-free", | |
| "Mediterranean", | |
| "mollusk-free", | |
| "mustard-free", | |
| "no-oil-added", | |
| "paleo", | |
| "peanut-free", | |
| "pescatarian", | |
| "pork-free", | |
| "red-meat-free", | |
| "sesame-free", | |
| "shellfish-free", | |
| "soy-free", | |
| "sugar-conscious", | |
| "sulfite-free", | |
| "tree-nut-free", | |
| "vegan", | |
| "vegetarian", | |
| "wheat-free"] | |
| CuisineTypeChoices = [ | |
| None, | |
| "American", | |
| "Asian", | |
| "British", | |
| "Caribbean", | |
| "Central Europe", | |
| "Chinese", | |
| "Eastern Europe", | |
| "French", | |
| "Indian", | |
| "Italian", | |
| "Japanese", | |
| "Kosher", | |
| "Mediterranean", | |
| "Mexican", | |
| "Middle Eastern", | |
| "Nordic", | |
| "South American", | |
| "South East Asian"] | |
| MealTypeChoices = [ | |
| None, | |
| "Breakfast", | |
| "Dinner", | |
| "Lunch", | |
| "Snack", | |
| "Teatime"] | |
| ParamQueryString = [ | |
| {"param": 'calories', "param_query_string": 'calories'}, | |
| {"param": 'protein', "param_query_string": 'nutrients[PROCNT]'}, | |
| {"param": 'carbs', "param_query_string": 'nutrients[CHOCDF.net]'}, | |
| {"param": 'fat', "param_query_string": 'nutrients[FAT]'}, | |
| {"param": 'added_sugar', "param_query_string": 'nutrients[SUGAR.added]'}, | |
| {"param": 'sodium', "param_query_string": 'nutrients[NA]'}, | |
| {"param": 'saturated_fat', "param_query_string": 'nutrients[FASAT]'}, | |
| {"param": 'fiber', "param_query_string": 'nutrients[FIBTG]'}, | |
| ] | |
| class Recipe: | |
| name: str | |
| cuisine_type: list | |
| calories: int | |
| protein_g: int | |
| carbs_g: int | |
| fat_g: int | |
| servings: int | |
| ingredients: list | |
| edamam_url: str | |
| source_url: str | |
| def get_param_query_string(param, param_query_string_list) -> str: | |
| for item in param_query_string_list: | |
| if item['param'] == param: | |
| return item['param_query_string'] | |
| return "" | |
| def update_params(params, param_to_update, min_val, max_val): | |
| param_query_string = get_param_query_string(param_to_update, ParamQueryString) | |
| if not bool(param_query_string): | |
| print("Error: could not update params") | |
| return | |
| if min_val!=None and max_val==None: | |
| params.update({param_query_string: f"{str(min_val)}+"}) | |
| if min_val==None and max_val!=None: | |
| params.update({param_query_string: f"{str(max_val)}"}) | |
| if min_val!=None and max_val!=None: | |
| params.update({param_query_string: f"{str(min_val)}-{str(max_val)}"}) | |
| def get_recipes( | |
| edamam_app_id: str, | |
| edamam_app_key: str, | |
| calories_min: float | None = None, | |
| calories_max: float | None = None, | |
| protein_min_g: float | None = None, | |
| protein_max_g: float | None = None, | |
| carbs_min_g: float | None = None, | |
| carbs_max_g: float | None = None, | |
| fat_min_g: float | None = None, | |
| fat_max_g: float | None = None, | |
| included: str | None = None, | |
| excluded: List[str] | None = None, | |
| added_sugar_min_g: float | None = None, | |
| added_sugar_max_g: float | None = None, | |
| sodium_min_mg: float | None = None, | |
| sodium_max_mg: float | None = None, | |
| saturated_fat_min_g: float | None = None, | |
| saturated_fat_max_g: float | None = None, | |
| fiber_min_g: float | None = None, | |
| fiber_max_g: float | None = None, | |
| cuisine_type: List[str] | None = None, | |
| meal_type: List[str] | None = None, | |
| diet: List[str] | None = None, | |
| health: List[str] | None = None, | |
| nb_recipes: int = 1, | |
| ) -> list: | |
| if not edamam_app_id or not edamam_app_key: | |
| return [] | |
| params = { | |
| 'type': 'any', | |
| 'app_id': edamam_app_id, | |
| 'app_key': edamam_app_key, | |
| 'calories': f"{str(calories_min)}-{str(calories_max)}", | |
| 'q': included, | |
| 'excluded': excluded, | |
| 'diet': diet, | |
| 'health': health, | |
| 'cuisineType': cuisine_type, | |
| 'mealType': meal_type, | |
| } | |
| update_params(params, 'calories', calories_min, calories_max) | |
| update_params(params, 'protein', protein_min_g, protein_max_g) | |
| update_params(params, 'carbs', carbs_min_g, carbs_max_g) | |
| update_params(params, 'fat', fat_min_g, fat_max_g) | |
| update_params(params, 'added_sugar', added_sugar_min_g, added_sugar_max_g) | |
| update_params(params, 'sodium', sodium_min_mg, sodium_max_mg) | |
| update_params(params, 'saturated_fat', saturated_fat_min_g, saturated_fat_max_g) | |
| update_params(params, 'fiber', fiber_min_g, fiber_max_g) | |
| """Get raw recipes from edamam""" | |
| response = requests.get(url='https://api.edamam.com/api/recipes/v2', params=params) | |
| """Convert to list of Recipe objects""" | |
| recipes = [] | |
| if response.status_code == 200: | |
| results = response.json()['hits'] | |
| if results: | |
| for item in results: | |
| if (len(recipes) < nb_recipes): | |
| recipe = item['recipe'] | |
| servings = int(recipe['yield']) | |
| recipes.append( | |
| Recipe( | |
| name=recipe['label'], | |
| cuisine_type=recipe['cuisineType'], | |
| calories=round(recipe['totalNutrients']['ENERC_KCAL']['quantity']/servings), | |
| protein_g=round(recipe['totalNutrients']['PROCNT']['quantity']/servings), | |
| carbs_g=round(recipe['totalNutrients']['CHOCDF']['quantity']/servings), | |
| fat_g=round(recipe['totalNutrients']['FAT']['quantity']/servings), | |
| servings=servings, | |
| ingredients=recipe['ingredientLines'], | |
| edamam_url=recipe['shareAs'], | |
| source_url=recipe['url'], | |
| ) | |
| ) | |
| else: | |
| break | |
| return recipes | |
| else: | |
| return [] | |
| else: | |
| print(f"Error {response.status_code}: {response.text}") | |
| return [] | |
| """Print Recipe object information to string""" | |
| def print2string_recipe(recipe: Recipe) -> str: | |
| string = f"" | |
| if recipe: | |
| string += f"********\n" | |
| string += f"Recipe: {recipe.name}\n" | |
| string += f"Calories: {recipe.calories}kcal\n" | |
| string += f"Protein: {recipe.protein_g}g\n" | |
| string += f"Carbs: {recipe.carbs_g}g\n" | |
| string += f"Fat: {recipe.fat_g}g\n" | |
| string += f"Ingredients for {recipe.servings} servings:\n" | |
| for ingredient in recipe.ingredients: | |
| string += f"- {ingredient}\n" | |
| string += f"URL: {recipe.edamam_url}\n" | |
| else: | |
| string += "No recipe found\n" | |
| return string | |
| if __name__ == "__main__": | |
| if READ_KEY_FROM_FILE: | |
| CURRENT_DIR = os.path.dirname(os.path.realpath(__file__)) | |
| edamam_app_id = read_json_to_dict(file_path=f"{CURRENT_DIR}/api_key.json")['edamam_app_id'] | |
| edamam_app_key = read_json_to_dict(file_path=f"{CURRENT_DIR}/api_key.json")['edamam_app_key'] | |
| else: | |
| edamam_app_id = input('Enter your edamam app id: ') | |
| edamam_app_key = input('Enter your edamam app key: ') | |
| """Compute macronutrients in grams from percent""" | |
| calories = 700 | |
| protein_min_percent = 10 | |
| protein_max_percent = 35 | |
| carbs_min_percent = 45 | |
| carbs_max_percent = 65 | |
| fat_min_percent = 10 | |
| fat_max_percent = 25 | |
| calories_div_100_div_4 = calories / 100.0 / 4.0 | |
| calories_div_100_div_9 = calories / 100.0 / 9.0 | |
| protein_min_g = round(protein_min_percent * calories_div_100_div_4) | |
| protein_max_g = round(protein_max_percent * calories_div_100_div_4) | |
| carbs_min_g = round(carbs_min_percent * calories_div_100_div_4) | |
| carbs_max_g = round(carbs_max_percent * calories_div_100_div_4) | |
| fat_min_g = round(fat_min_percent * calories_div_100_div_9) | |
| fat_max_g = round(fat_max_percent * calories_div_100_div_9) | |
| recipes = get_recipes( | |
| edamam_app_id=edamam_app_id, | |
| edamam_app_key=edamam_app_key, | |
| calories_min=None, | |
| calories_max=calories, | |
| protein_min_g=protein_min_g, | |
| protein_max_g=protein_max_g, | |
| carbs_min_g=carbs_min_g, | |
| carbs_max_g=carbs_max_g, | |
| fat_min_g=fat_min_g, | |
| fat_max_g=fat_max_g, | |
| included="chicken", | |
| excluded=["sesame"], | |
| nb_recipes=5) | |
| for recipe in recipes: | |
| print() | |
| print(print2string_recipe(recipe)) | |