File size: 4,326 Bytes
96f6720
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import gradio as gr

from jinja2 import Environment, FileSystemLoader

from log_util import logger
from meal_image_search import search_meal_image
from recipe_generator import get_altered_recipe, get_image_from_recipe, get_recipe_from_image
from util import yield_lines_from_file

BRAND = 'HealthAI'
TITLE = f'{BRAND} Chef'

env = Environment(loader=FileSystemLoader('templates'))
template = env.get_template('recipe.html')

DISCLAIMER = 'This recipe is a healthier option <em>generated by AI</em>. A registered dietitian can provide expert dietary advice 😀'

async def process_image(file):
    if not file:
        yield None, None
        return

    image_path = file.name
    yield image_path, None

    try:
        recipe = await get_recipe_from_image(image_path)
        html = template.render(recipe=recipe)
        yield image_path, html

    except Exception as e:
        logger.error(e)
        yield None, None
        if 'not a meal' in str(e).lower():
            raise gr.Error("This image doesn't contain a meal.")
        raise gr.Error("Sorry, this image can't be processed.")

async def get_new_recipe(orig_recipe: str, restrictions: list[str], diagnoses: list[str]):
    if not orig_recipe or (not restrictions and not diagnoses):
        yield None, None

        if not orig_recipe:
            raise gr.Error('Please upload a meal pic first.')

        if not restrictions and not diagnoses:
            raise gr.Error(
'Please select dietary restrictions or medical diagnoses, then try again. I will give you a new recipe based on your selections!')

    try:
        recipe = await get_altered_recipe(orig_recipe, restrictions, diagnoses)
        recipe['disclaimer'] = DISCLAIMER
        html = template.render(recipe=recipe)
        yield html, None

    except Exception as e:
        logger.error(e)
        yield None, None
        raise gr.Error(f"Sorry, a new recipe can't be made.")

    try:
        image_url = get_image_from_recipe(recipe)
        yield html, image_url

    except Exception as e:
        logger.error(e)
        yield html, None

def search_image(search_text: str) -> str:
    if not search_text:
        return None

    try:
        image_url = search_meal_image(search_text)
        if image_url:
            return image_url

    except Exception as e:
        logger.error(e)

    raise gr.Error(f"Sorry, can't find a meal pic for {search_text}.")

with gr.Blocks(title=TITLE, theme=gr.themes.Monochrome(), css='''
    footer {visibility: hidden}

    /* make container full width */
    .gradio-container {
        width: 100% !important; /* flll width */
        max-width: 100% !important; /* prevent max-width restriction */
        margin: 5px 0px 5px 0px !important; /* top, right, bottom, left */
    }
    '''.strip()) as demo:

    with gr.Row():
        gr.Markdown(f'# {TITLE} 🍽️')
        new_recipe_button = gr.Button(f'Get {BRAND} Recipe 😋', scale=0)

    file_select = gr.File(label='Upload Meal Pic', container=True, file_types=['.jpg', '.jpeg', '.png', '.gif', '.webp'])

    search_text = gr.Textbox(placeholder='Or enter a meal to search for an image of it', submit_btn=True, container=False, interactive=True, max_lines=1)

    with gr.Row():
        restrictions_dropdown = gr.Dropdown(label='Dietary Restrictions', choices=yield_lines_from_file('dietary_restrictions.txt'), interactive=True, multiselect=True, value=None)
        diagnoses_dropdown = gr.Dropdown(label='Medical Diagnoses', choices=yield_lines_from_file('medical_diagnoses.txt'), interactive=True, multiselect=True, value=None)

    with gr.Row():
        orig_meal = gr.Image(label='Original Meal', interactive=False)
        new_meal = gr.Image(label=f'{BRAND} Meal', interactive=False)

    with gr.Row():
        orig_recipe = gr.HTML(label='Original Recipe', container=True, show_label=True)
        new_recipe = gr.HTML(label=f'{BRAND} Recipe', container=True, show_label=True)

    search_text.submit(search_image, inputs=search_text, outputs=file_select)

    file_select.change(
        process_image,
        inputs=file_select,
        outputs=[orig_meal, orig_recipe]
    )

    new_recipe_button.click(fn=get_new_recipe, inputs=[orig_recipe, restrictions_dropdown, diagnoses_dropdown], outputs=[new_recipe, new_meal])

demo.launch(server_name='0.0.0.0')