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