Introduction
This project shows you how to build a Recipe Finder web app using Python, Streamlit, and the Spoonacular API. Enter ingredients you have at home and the app will find recipes you can make right now. This app and the weather app share the same API-request skeleton — learn one and you know both.
Prerequisites
- Python 3.8+ — python.org
- Libraries:
pip install streamlit requests
- Spoonacular API Key — Sign up for free at spoonacular.com/food-api and grab your API key from the dashboard.
Step 1: Create the Script
Create recipe_finder.py and paste the following:
import streamlit as st
import requests
st.set_page_config(page_title="Recipe Finder", page_icon="🍳")
st.title("🍳 Recipe Finder")
st.write("Enter ingredients you have and discover recipes you can make!")
API_KEY = "YOUR_SPOONACULAR_API_KEY"
ingredients = st.text_input(
"Enter ingredients (comma-separated):",
placeholder="e.g. chicken, tomato, garlic"
)
num_results = st.slider("Number of recipes", 1, 10, 5)
if st.button("Find Recipes") and ingredients:
url = (
f"https://api.spoonacular.com/recipes/findByIngredients"
f"?apiKey={API_KEY}&ingredients={ingredients}&number={num_results}"
)
response = requests.get(url)
if response.status_code == 200:
recipes = response.json()
if recipes:
for recipe in recipes:
with st.expander(f"🍽️ {recipe['title']}"):
col1, col2 = st.columns([1, 2])
with col1:
st.image(recipe['image'], use_column_width=True)
with col2:
used = [i['name'] for i in recipe['usedIngredients']]
missed = [i['name'] for i in recipe['missedIngredients']]
st.write(f"**✅ Used:** {', '.join(used)}")
st.write(f"**🛒 Missing:** {', '.join(missed)}")
else:
st.info("No recipes found. Try different ingredients!")
else:
st.error("API error — please check your API key.")
Step 2: Add Your API Key
Replace YOUR_SPOONACULAR_API_KEY with the key from your Spoonacular dashboard.
Step 3: Run the App
streamlit run recipe_finder.py
Step 4: Use the App
Enter ingredients separated by commas (e.g. chicken, tomato, garlic), adjust the slider for how many recipes to show, and click Find Recipes. Each result is collapsible and shows the recipe image alongside used and missing ingredients.
How It Works
The flow is: read comma-separated ingredients from st.text_input, split and strip them into a list, then call the Spoonacular complexSearch endpoint with includeIngredients. The API returns matching recipe IDs and titles; a second call to the information endpoint per recipe fetches details like image and used/missed ingredient counts.
Two design choices matter. First, debouncing via button — the search only fires on st.button("Find Recipes"), so typing does not spam the API. Second, defensive parsing — every field is read with .get() because recipe data is inconsistently populated.
Rendering uses st.columns(3) for a card grid, with st.image() and a markdown link per card. If you want to visualize nutrition data from the response, the charting patterns from the Pandas dashboard tutorial drop straight in.
Key Concepts
requests.get(url)— Calls the Spoonacular API and returns recipe data.st.expander()— Creates a collapsible card for each recipe result.st.image()— Renders the recipe thumbnail image.st.slider()— Lets the user control how many results to fetch.
What to Try Next
- Filter by diet (vegetarian, vegan, gluten-free) using extra API parameters.
- Show nutritional info using the Spoonacular nutrition endpoint.
- Let users save favourite recipes with
st.session_state.
Common Errors & Fixes
-
401/403 from Spoonacular — free-tier keys activate slowly and have daily quotas (about 150 calls/day). Cache results with
@st.cache_datato stretch the quota. -
No recipes found — too many ingredients at once over-constrains the search. Try 2-3 core ingredients and add more only if needed.
-
requests.exceptions.MissingSchema— the base URL lost itshttps://, usually from a stray quote when concatenating the query string. Use theparams=argument instead of string building. -
Images fail to load — Spoonacular serves images over HTTPS with short-lived URLs; pass headers or re-fetch rather than caching image URLs long-term.
-
Duplicate recipes in results — the API returns the same dish for overlapping ingredient sets; deduplicate on recipe
idbefore rendering the grid. -
Ingredients input breaks on trailing comma —
"eggs, milk,"produces an empty string in the list; filter with[i.strip() for i in raw.split(",") if i.strip()].
FAQ
Is the Spoonacular API free?
There is a free tier (~150 calls/day) which is enough for personal use. Paid tiers raise the quota.
Can I filter by diet (vegan, gluten-free)?
Yes — add diet=vegan or intolerances=gluten as query parameters; the API supports dozens of filters.
How do I show full instructions?
Call the /recipes/{id}/analyzedInstructions endpoint and render the returned steps as a numbered st.markdown list.
Can I search by dish name instead of ingredients?
Yes — the same API’s query parameter accepts names like “pasta”; swap the parameter and keep the identical rendering code.