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()