File size: 6,216 Bytes
7ee5c1b |
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 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
import gradio as gr
import base64
import requests
import io
from PIL import Image
import json
import os
from together import Together
import tempfile
def encode_image_to_base64(image_path):
"""Convert image to base64 encoding"""
with open(image_path, "rb") as image_file:
return base64.b64encode(image_file.read()).decode('utf-8')
def save_uploaded_image(image):
"""Save uploaded image to a temporary file and return the path"""
if image is None:
return None
with tempfile.NamedTemporaryFile(delete=False, suffix='.jpg') as temp_file:
if isinstance(image, dict) and "path" in image: # Gradio returns image as dict
# Copy the uploaded image to our temporary file
with open(image["path"], "rb") as img_file:
temp_file.write(img_file.read())
elif isinstance(image, Image.Image):
# If it's a PIL Image, save it
image.save(temp_file.name, format="JPEG")
else:
# Try to handle other formats
try:
Image.open(image).save(temp_file.name, format="JPEG")
except Exception:
return None
return temp_file.name
def get_recipe_suggestions(api_key, image, num_recipes=3, dietary_restrictions="None"):
"""
Get recipe suggestions based on the uploaded image of ingredients
"""
if not api_key or not image:
return "Please provide both an API key and an image of ingredients."
# Save the uploaded image
image_path = save_uploaded_image(image)
if not image_path:
return "Failed to process the uploaded image."
try:
# Initialize Together client with the provided API key
client = Together(api_key=api_key)
# Create the prompt for the model
system_prompt = """You are a culinary expert AI assistant that specializes in creating recipes based on available ingredients.
Analyze the provided image of ingredients and suggest creative, detailed recipes.
For each recipe suggestion, include:
1. Recipe name
2. Brief description of the dish
3. Complete ingredients list (including estimated quantities and any additional staple ingredients that might be needed)
4. Step-by-step cooking instructions
5. Approximate cooking time
6. Difficulty level (Easy, Medium, Advanced)
7. Nutritional highlights
Consider any dietary restrictions mentioned by the user."""
user_prompt = f"""Based on the ingredients shown in this image, suggest {num_recipes} creative and delicious recipes.
Dietary restrictions to consider: {dietary_restrictions}
Please be specific about what ingredients you can identify in the image and creative with your recipe suggestions."""
# Create message with image
response = client.chat.completions.create(
model="meta-llama/Llama-Vision-Free",
messages=[
{
"role": "system",
"content": system_prompt
},
{
"role": "user",
"content": [
{
"type": "text",
"text": user_prompt
},
{
"type": "image_url",
"image_url": {
"url": f"file://{image_path}"
}
}
]
}
],
max_tokens=2048,
temperature=0.7
)
# Clean up the temporary file
try:
os.unlink(image_path)
except:
pass
return response.choices[0].message.content
except Exception as e:
# Clean up the temporary file in case of error
try:
os.unlink(image_path)
except:
pass
return f"Error: {str(e)}"
# Create the Gradio interface
with gr.Blocks(title="Visual Recipe Assistant") as app:
gr.Markdown("# 🍲 Visual Recipe Assistant")
gr.Markdown("Upload an image of ingredients you have, and get creative recipe suggestions!")
with gr.Row():
with gr.Column(scale=1):
api_key_input = gr.Textbox(
label="Together API Key",
placeholder="Enter your Together API key here...",
type="password"
)
image_input = gr.Image(
label="Upload Image of Ingredients",
type="filepath"
)
with gr.Row():
num_recipes = gr.Slider(
minimum=1,
maximum=5,
value=3,
step=1,
label="Number of Recipe Suggestions"
)
dietary_restrictions = gr.Dropdown(
choices=["None", "Vegetarian", "Vegan", "Gluten-Free", "Dairy-Free", "Low-Carb", "Keto"],
value="None",
label="Dietary Restrictions"
)
submit_button = gr.Button("Get Recipe Suggestions", variant="primary")
with gr.Column(scale=2):
output = gr.Markdown(label="Recipe Suggestions")
# Set up the submission action
submit_button.click(
fn=get_recipe_suggestions,
inputs=[api_key_input, image_input, num_recipes, dietary_restrictions],
outputs=output
)
gr.Markdown("""
## How to Use
1. Enter your Together API key
2. Upload an image of ingredients you have available
3. Adjust the number of recipes you'd like to receive
4. Select any dietary restrictions
5. Click "Get Recipe Suggestions"
## About
This app uses the Llama-Vision-Free multimodal model from Meta to analyze images of ingredients
and suggest creative recipes based on what it identifies.
""")
# Launch the app
if __name__ == "__main__":
app.launch() |