-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathapp.py
More file actions
140 lines (114 loc) · 5.36 KB
/
app.py
File metadata and controls
140 lines (114 loc) · 5.36 KB
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
130
131
132
133
134
135
136
137
138
139
140
import requests
import os
from dotenv import load_dotenv
from typing import List, Dict, Optional
from flask import Flask, render_template, request, jsonify
from logging_config import setup_logger
from waitress import serve
# Setup logging
logger = setup_logger()
# for debugging start up
logger.info("Application startup - checking configuration...")
logger.info(f"Current working directory: {os.getcwd()}")
logger.info(f"API Key present: {bool(API_KEY)}")
logger.info(f"Templates directory exists: {os.path.exists('templates')}")
logger.info(f"index.html exists: {os.path.exists('templates/index.html')}")
load_dotenv
API_KEY = os.getenv('SPOONACULAR_API_KEY')
if not API_KEY:
raise ValueError("No API key found. Please set SPOONACULAR_API_KEY environment variable")
app = Flask(__name__)
def get_random_recipes(number=3, tags="", exclude_ingredients=None):
url = "https://api.spoonacular.com/recipes/complexSearch"
params = {
"apiKey": API_KEY,
"number": number * 2,
"sort": "random",
"addRecipeInformation": True,
"fillIngredients": True,
"instructionsRequired": True,
"tags": tags,
"type": "main course",
"excludeCuisine": "beverage",
}
if exclude_ingredients:
params["excludeIngredients"] = ",".join(exclude_ingredients)
logger.info("Fetching recipes with params: %s", {k: v for k, v in params.items() if k != 'apiKey'})
try:
response = requests.get(url, params=params)
response.raise_for_status() # Raises an HTTPError for bad responses
data = response.json()
recipes = [r for r in data.get("results", [])
if not any(dtype.lower() in ['drink', 'beverage', 'cocktail', 'alcohol']
for dtype in r.get('dishTypes', []))
and not (
('soup' in r.get('dishTypes', []) or 'salad' in r.get('dishTypes', []))
and 'main course' not in r.get('dishTypes', [])
)]
logger.info("Successfully fetched %d recipes", len(recipes))
return recipes[:number]
except requests.exceptions.RequestException as e:
logger.error("API request failed: %s", str(e))
return None
except ValueError as e:
logger.error("Failed to parse API response: %s", str(e))
return None
except Exception as e:
logger.error("Unexpected error: %s", str(e))
return None
def print_recipe(recipe: Dict):
print("\n" + "="*50)
print(f"Title: {recipe['title']}")
print(f"Type: {', '.join(recipe.get('dishTypes', ['Not specified']))}")
print(f"Ready in: {recipe['readyInMinutes']} minutes")
print(f"Servings: {recipe['servings']}")
print(f"Health Score: {recipe['healthScore']}/100")
print(f"Spoonacular Score: {recipe.get('spoonacularScore', 'N/A')}/100")
print("\nDietary Info:")
print(f"- Vegetarian: {recipe['vegetarian']}")
print(f"- Vegan: {recipe['vegan']}")
print(f"- Gluten Free: {recipe['glutenFree']}")
print(f"- Dairy Free: {recipe['dairyFree']}")
if recipe.get('extendedIngredients'):
print("\nIngredients:")
for ingredient in recipe['extendedIngredients']:
print(f"- {ingredient['original']}")
print(f"\nCooking Instructions: {recipe['sourceUrl']}")
print(f"Cuisine: {', '.join(recipe.get('cuisines', ['Not specified']))}")
print("="*50 + "\n")
@app.route('/', methods=['GET', 'POST'])
def home():
try:
if request.method == 'POST':
logger.info("Processing POST request for recipe search")
exclude_ingredients = ["pork", "red meat", "dairy", "wheat", "whey", "rye", "barley", "cheese", "milk", "cream"]
search_tags = ["spicy"]
recipes = get_random_recipes(
number=5,
tags=",".join(search_tags),
exclude_ingredients=exclude_ingredients
)
if recipes:
filtered_recipes = [r for r in recipes
if r.get('dishTypes') and
not any(t.lower() in ['drink', 'beverage', 'cocktail', 'alcohol']
for t in r['dishTypes'])]
logger.info("Found %d recipes after filtering", len(filtered_recipes))
return render_template('index.html', recipes=filtered_recipes)
logger.warning("No recipes found matching criteria")
return render_template('index.html', error="No recipes found matching your criteria.")
logger.info("Serving GET request for home page")
return render_template('index.html')
except Exception as e:
logger.error("Error in home route: %s", str(e))
return render_template('index.html', error="An unexpected error occurred. Please try again later.")
@app.errorhandler(404)
def not_found_error(error):
logger.error('Page not found: %s', request.url)
return render_template('index.html', error="Page not found"), 404
@app.errorhandler(500)
def internal_error(error):
logger.error('Server Error: %s', str(error))
return render_template('index.html', error="An internal error occurred. Please try again later."), 500
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80, debug=True)