-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrecipes.py
129 lines (111 loc) · 3.74 KB
/
recipes.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
from abc import abstractmethod
import requests
from typing import List
class RecipeIngredient:
def __init__(self, title: str, image: str):
self.title = title
self.image = image
def __str__(self):
json = {
"title": self.title,
"image": self.image,
}
return str(json)
class RecipeInstruction:
def __init__(self, step: str):
self.step = step
def __str__(self):
return self.step
class Recipe:
def __init__(
self,
title: str,
likes: int,
image: str,
ingredients: List[RecipeIngredient],
instructions: List[RecipeInstruction],
):
self.title = title
self.likes = likes
self.image = image
self.ingredients = ingredients
self.instructions = instructions
def __str__(self):
json = {
"title": self.title,
"likes": self.likes,
"image": self.image,
"ingredients": [str(ingredient) for ingredient in self.ingredients],
"instructions": [str(instruction) for instruction in self.instructions],
}
return str(json)
class RecipeProvider:
@abstractmethod
def fetch_recipes(
self,
query: str,
include_cuisines: List = [],
exclude_cuisines: List = [],
include_ingredients: List = [],
exclude_ingredients: List = [],
max_amount: int = 5,
) -> List[Recipe]:
pass
class SpoonacularRecipeProvider(RecipeProvider):
def __init__(self, apiKey: str):
self.API_URL = "https://api.spoonacular.com/recipes/complexSearch"
self.API_KEY = apiKey
def fetch_recipes(
self,
query: str,
include_cuisines: List = [],
exclude_cuisines: List = [],
include_ingredients: List = [],
exclude_ingredients: List = [],
max_amount: int = 5,
):
params = {
"query": query,
"cuisine": ",".join(include_cuisines),
"excludeCuisine": ",".join(exclude_cuisines),
"includeIngredients": ",".join(include_ingredients),
"excludeIngredients": ",".join(exclude_ingredients),
"number": max_amount,
"apiKey": self.API_KEY,
"instructionsRequired": "true",
"addRecipeInformation": "true",
"addRecipeNutrition": "false",
"fillIngredients": "true",
"ignorePantry": "true",
"sort": "calories",
"sortDirection": "desc",
}
# Make the GET request to the Spoonacular API
response = requests.get(self.API_URL, params=params)
json_response: dict[str, any] = response.json()
if response.status_code == 200:
recipes = json_response.get("results", [])
return [
Recipe(
recipe.get("title"),
recipe.get("likes"),
recipe.get("image"),
[
RecipeIngredient(
ingredient.get("original"), ingredient.get("image")
)
for ingredient in recipe["missedIngredients"]
+ recipe["usedIngredients"]
],
[
RecipeInstruction(instruction.get("step"))
for instructions in recipe["analyzedInstructions"]
for instruction in instructions["steps"]
],
)
for recipe in recipes
]
else:
raise Exception(
f'Error fetching recipes: {response.status_code} {json_response.get("message", "Unknown error")}'
)