import gradio as gr #from pyzbar.pyzbar import decode from lambdas import upload_models, predict import base64 from io import BytesIO, StringIO from PIL import Image import pandas as pd import os.path import numpy as np from datetime import datetime, timedelta from descriptions import prefer_frontal_cam_html, docu_eng, docu_cat, css_image_aspect_ratio DEBUG = True config = {'possible_shifts': {'No shifts': 0}, 'possible_modes': ["waste"]} def login(username, password) -> bool: if os.path.isfile('credentials.csv'): df = pd.read_csv('credentials.csv') else: s = os.environ.get('CREDENTIALS') df = pd.read_csv(StringIO(s)) if not len(df): return False df = df.replace({np.nan: None}) for idx, row in df.iterrows(): if row['username'] == username and row['password'] == password: restaurant_id = int(row['restaurant_id']) restaurant_name = str(row['restaurant_name']) mode = 'waste' possible_modes = str(row.get('modes')).split(':') possible_shifts = {i.split(':')[0]: i.split(':')[1] for i in str(row.get('shifts')).split('-')} \ if row.get('shifts') else {'no shift': None} config_aux = {'restaurant_id': restaurant_id, 'restaurant_name': restaurant_name, 'mode': mode, 'possible_modes': possible_modes, 'possible_shifts': possible_shifts, } config.clear() config.update(config_aux) return True return False def start_app(shift_id, mode, date): try: config_aux = {'date': date, 'shift_id': shift_id, 'mode': mode, 'possible_shifts': {'No shifts': 0}, 'possible_modes': ["waste"]} config.update(config_aux) gr.Info('Loading models. This may take a while') status_code, r = upload_models(**config) if status_code in (201, 200, 204): config.update(r) gr.Info('Models Correctly Loaded. Ready to predict') tab_id = 1 else: raise gr.Error(f'Error loading the models: {r}') except Exception as e: raise gr.Error(f'Error Uploading the models. \n {e}') return gr.Tabs(selected=tab_id, visible=True) def predict_app(image, patient_id=None): gr.Info('Predicting ...') buffered = BytesIO() image.save(buffered, format='JPEG') b64image = base64.b64encode(buffered.getvalue()).decode('utf-8') status_code, r = predict(b64image=b64image, patient_identifier=patient_id, **config) if status_code in (200, 201, 204): gr.Info('Prediction Successful') else: raise gr.Error(f'Error predicting {r}') # APP with (gr.Blocks(head=prefer_frontal_cam_html, css=css_image_aspect_ratio) as block): with gr.Tabs() as tabs: with gr.Tab(label='Welcome', id=0) as welcome_tab: gr.Info('Loading ...') @gr.render() def header(): gr.Markdown(f'# User: {config.get("restaurant_name", "Proppos")}', render=True) @gr.render() def render_dropdowns(): shift_dropdown = gr.Dropdown(label='Meal/Apat/Comida', value=list(config["possible_shifts"].items())[0], choices=tuple(config["possible_shifts"].items())) mode_dropdown = gr.Dropdown(label='Mode', value=config['possible_modes'][0], choices=config["possible_modes"]) days = [datetime.today().strftime('%Y-%m-%d'), (datetime.now() - timedelta(days=1)).strftime('%Y-%m-%d')] date_chooser = gr.Dropdown(choices=days, label='Date/Data/Fecha', value=days[0]) start_button = gr.Button(value='START ▶️') start_button.click(fn=start_app, inputs=[shift_dropdown, mode_dropdown, date_chooser], outputs=tabs) gr.Markdown(""" * Do you have any doubt? Please, see the documentation tab. \n * Tens un dubte? Consulta la pestanya de documentació. """) # logout_button.click(fn=lambda: config.clear()) with gr.Tab(label='📷 Capture', id=1): # MAIN TAB TO PREDICT gr.Markdown(f""" 1. Click to Access Webcam 2. Press the red button to start recording 3. Place the tray so it is centered in the displayed image and 4. Press the grey button 'PRESS TO PREDICT' """) im = gr.Image(sources=['webcam'], mirror_webcam=False, type='pil', show_share_button=False, show_download_button=False, height=720, width=1280, elem_id="image-container") ## Patient ID searcher. Uncomment if needed # with gr.Accordion(open=False): # eater_id = gr.Textbox(label='Patient Identification', placeholder='Searching Patient ID') # # current_eater_id = {'value': None} # @gr.on(inputs=im, outputs=eater_id) # def search_eater_id(image): # d = []#decode(image) # default_value = None # current_value = current_eater_id['value'] or default_value # new_value = d[0].data if d else default_value # # If it is really a new value different from the default one, change it. # final_value = new_value if new_value != default_value else current_value # current_eater_id['value'] = final_value # return final_value eater_id = None b = gr.Button('PRESS TO PREDICT') b.click(fn=predict_app, inputs=[im], outputs=gr.Info()) # add eater id to input if needed logout_button = gr.Button(link='/logout', value='Logout / Exit ↩', size='sm') with gr.Tab(label='ℹ️ Status', id=2): gr.Markdown(' Press the button to see the status of the Application and technical information') load_status_button = gr.Button('Load Status') status_json = gr.Json(label='Status') load_status_button.click(fn=lambda: config, outputs=status_json) with gr.Tab(label='📄 Documentation', id=3): choices = [('ENG 🇬🇧', docu_eng), ('CAT', docu_cat)] c = gr.Radio(label='Select the language', choices=choices) @gr.render() def display_docu(): d = gr.Markdown(docu_eng) c.change(fn=lambda x: x, inputs=c, outputs=d) block.launch(show_api=False, auth=login)