recipes_app / app.py
adrianpierce's picture
Update app.py
7ca3025
raw
history blame
No virus
7.88 kB
# imports
import streamlit as st
import numpy as np
import pandas as pd
import re
import json
import openai
openai.api_key = st.secrets["open_ai_key"]
# state management
if 'gpt_response' not in st.session_state:
st.session_state.gpt_response = None
# app
st.title("Let's get cooking")
user_direction = st.text_area(
"What do you want to cook? Describe anything - a dish, cuisine, event, or vibe.",
placeholder="quick snack, asian style bowl with either noodles or rice, something italian",
)
serving_size = st.number_input(
"How many people are you cooking for?",
min_value=1,
max_value=100,
value=2,
step=1
)
difficulty_dictionary = {
"Quick & Easy": {
"description": "Easy recipes with straightforward instructions. Ideal for beginners or those seeking quick and simple cooking.",
},
"Intermediate": {
"description": "Recipes with some intricate steps that invite a little challenge. Perfect for regular cooks wanting to expand their repertoire with new ingredients and techniques.",
},
"Professional": {
"description": "Complex recipes that demand a high level of skill and precision. Suited for seasoned cooks aspiring to professional-level sophistication and creativity.",
}
}
selected_difficulty = st.radio(
"Choose a difficulty level for your recipe.",
[
list(difficulty_dictionary.keys())[0],
list(difficulty_dictionary.keys())[1],
list(difficulty_dictionary.keys())[2]
],
captions = [
difficulty_dictionary["Quick & Easy"]["description"],
difficulty_dictionary["Intermediate"]["description"],
difficulty_dictionary["Professional"]["description"]
]
)
exclusions = st.text_area(
"Any ingredients you want to exclude?",
placeholder="gluten, dairy, nuts, cilantro",
)
user_inputs = {
"user_direction" : user_direction,
"exclusions": exclusions,
"serving_size": serving_size,
"difficulty": selected_difficulty
}
def create_detailed_prompt(user_direction, exclusions, serving_size, difficulty):
if difficulty == "Quick and Easy":
prompt = (
f"Please provide a 'Quick and Easy' recipe for {user_direction} with a serving size of {serving_size}. "
f"It should require as few ingredients as possible and should be ready as little time as possible. "
f"The steps should be simple, and the ingredients should be commonly found in a household pantry. "
f"Ensure to exclude {exclusions} from the recipe."
)
elif difficulty == "Intermediate":
prompt = (
f"I'm looking for a recipe for a classic {user_direction} with a serving size of {serving_size} that offers a bit of a cooking challenge "
f"but doesn't require professional skills.The recipe should feature traditional ingredients and techniques that are authentic to its cuisine. "
f"Please provide a step-by-step guide that explains the process in detail. "
f"Ensure to exclude {exclusions} from the recipe."
)
elif difficulty == "Professional":
prompt = (
f"Create an advanced recipe for {user_direction} with a serving size of {serving_size} that pushes the boundaries of culinary arts."
f"This recipe should integrate unique ingredients, advanced cooking techniques, and innovative presentations."
f"I'm aiming for a dish that could be served at a high-end restaurant or would impress at a gourmet food competition."
f"Please detail the preparation and cooking process, considering that complexity and creativity are more important than prep and cooking time. "
f"Ensure to exclude {exclusions} from the recipe."
)
return prompt
def generate_recipe(user_inputs):
with st.spinner('Building the perfect recipe for you...'):
functions = [
{
"name": "provide_recipe",
"description": "Provides a detailed recipe strictly adhering to the user input/specifications, especially ingredient exclusions and the recipe difficulty",
"parameters": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "A creative name for the recipe"
},
"description": {
"type": "string",
"description": "a brief one sentence description of the provided recipe"
},
"ingredients": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Name of the ingredient"
},
"quantity": {
"type": "string",
"description": "Amount of the ingredient"
}
}
}
},
"instructions": {
"type": "array",
"items": {
"type": "object",
"properties": {
"step_number": {
"type": "number",
"description": "The sequence number of this step"
},
"instruction": {
"type": "string",
"description": "Detailed description of what to do in this step"
}
}
}
}
},
"required": [
"name",
"description",
"ingredients",
"instructions"
],
},
}
]
prompt = create_detailed_prompt(user_inputs['user_direction'], user_inputs['exclusions'], user_inputs['serving_size'], user_inputs['difficulty'])
messages = [{"role": "user", "content": prompt}]
st.session_state.gpt_response = openai.ChatCompletion.create(
model="gpt-4",
messages=messages,
temperature=0.75,
top_p=0.75,
functions=functions,
function_call={"name":"provide_recipe"}, # auto is default, but we'll be explicit
)
st.button(label='Submit', on_click=generate_recipe, kwargs=dict(user_inputs=user_inputs))
if st.session_state.gpt_response is not None:
st.divider()
loaded_recipe = json.loads(st.session_state.gpt_response['choices'][0]['message']["function_call"]["arguments"])
st.header(loaded_recipe['name'])
# st.write(f"**Serving Size: {loaded_recipe['recipe_serving_size']}**")
st.write(f"**Description:** {loaded_recipe['description']}")
st.subheader("Ingredients:")
try:
md_ingredients = ''
for ingredient in loaded_recipe['ingredients']:
md_ingredients += f"- {ingredient['quantity']} {ingredient['name']} \n"
st.markdown(md_ingredients)
except:
st.write(loaded_recipe['ingredients'])
st.subheader("Instructions:")
try:
md_instructions = ''
for instruction in recipe['instructions']:
md_instructions += f"{instruction['step_number']}. {instruction['instruction']} \n"
st.markdown(md_instructions)
except:
st.write(loaded_recipe['instructions'])