from flask import Flask, request, render_template, send_file, Response import ast import io import zipfile from datetime import datetime import base64 app = Flask(__name__) # Expanded mapping of Gradio components to Flask-compatible HTML inputs COMPONENT_MAP = { 'gr.Textbox': {'html_type': 'input', 'attributes': {'type': 'text', 'class': 'form-control'}}, 'gr.MultimodalTextbox': {'html_type': 'input', 'attributes': {'type': 'file', 'multiple': 'true', 'class': 'form-control'}}, 'gr.Slider': {'html_type': 'input', 'attributes': {'type': 'range', 'class': 'form-range', 'min': '0', 'max': '100'}}, 'gr.Image': {'html_type': 'input', 'attributes': {'type': 'file', 'accept': 'image/*', 'class': 'form-control'}}, 'gr.Dropdown': {'html_type': 'select', 'attributes': {'class': 'form-select'}}, 'gr.Checkbox': {'html_type': 'input', 'attributes': {'type': 'checkbox', 'class': 'form-check-input'}}, 'gr.Radio': {'html_type': 'input', 'attributes': {'type': 'radio', 'class': 'form-check-input'}}, 'gr.Label': {'html_type': 'div', 'attributes': {'class': 'output-label'}}, 'gr.Audio': {'html_type': 'input', 'attributes': {'type': 'file', 'accept': 'audio/*', 'class': 'form-control'}}, 'gr.Video': {'html_type': 'input', 'attributes': {'type': 'file', 'accept': 'video/*', 'class': 'form-control'}}, 'gr.File': {'html_type': 'input', 'attributes': {'type': 'file', 'class': 'form-control'}}, 'gr.Number': {'html_type': 'input', 'attributes': {'type': 'number', 'class': 'form-control'}}, 'gr.ColorPicker': {'html_type': 'input', 'attributes': {'type': 'color', 'class': 'form-control'}}, 'gr.Markdown': {'html_type': 'div', 'attributes': {'class': 'markdown-output'}}, 'gr.Dataframe': {'html_type': 'textarea', 'attributes': {'class': 'form-control', 'readonly': 'true'}}, 'gr.HTML': {'html_type': 'div', 'attributes': {'class': 'html-output'}}, 'gr.Chatbot': {'html_type': 'div', 'attributes': {'class': 'chatbot-output'}}, 'gr.Button': {'html_type': 'button', 'attributes': {'type': 'submit', 'class': 'btn btn-primary'}}, 'gr.ClearButton': {'html_type': 'button', 'attributes': {'type': 'button', 'class': 'btn btn-secondary', 'onclick': 'clearChatbot()'}} } def parse_gradio_script(script): """Parse the Gradio script to extract components, layout, and events.""" tree = ast.parse(script) components = { 'inputs': [], 'outputs': [], 'functions': {}, 'layout': [], 'is_blocks': False, 'html_content': [], 'events': {} } for node in ast.walk(tree): if isinstance(node, ast.With): for item in node.items: if isinstance(item.context_expr, ast.Call) and hasattr(item.context_expr.func, 'attr') and item.context_expr.func.attr == 'Blocks': components['is_blocks'] = True for body_node in node.body: if isinstance(body_node, ast.Expr) and isinstance(body_node.value, ast.Call): call = body_node.value if hasattr(call.func, 'attr'): comp_type = f"gr.{call.func.attr}" if comp_type in COMPONENT_MAP: comp_name = None for kw in call.keywords: if kw.arg == '_js': continue if isinstance(kw.value, ast.Name): comp_name = kw.value.id if comp_name: components['layout'].append({'type': comp_type, 'name': comp_name}) else: components['html_content'].append(ast.unparse(call)) elif call.func.attr in ['Row', 'Column', 'Group']: components['layout'].append({'type': f"gr.{call.func.attr}", 'children': []}) if isinstance(node, ast.Assign): target = node.targets[0] if isinstance(node.value, ast.Call) and hasattr(node.value.func, 'attr') and node.value.func.attr == 'click': event_name = target.id if isinstance(target, ast.Name) else None if event_name: fn = ast.unparse(node.value.args[0]) if node.value.args else None inputs = [ast.unparse(arg) for arg in node.value.keywords[0].value.elts] if node.value.keywords else [] outputs = [ast.unparse(arg) for arg in node.value.keywords[1].value.elts] if len(node.value.keywords) > 1 else [] components['events'][event_name] = {'fn': fn, 'inputs': inputs, 'outputs': outputs} components['functions'][fn] = fn components['inputs'].extend(inputs) components['outputs'].extend(outputs) components['inputs'] = list(dict.fromkeys(components['inputs'])) components['outputs'] = list(dict.fromkeys(components['outputs'])) return components def generate_flask_app(script, components): """Generate Flask app code and frontend templates.""" flask_code = f"""from flask import Flask, request, render_template import io from PIL import Image import base64 import pandas as pd import json app = Flask(__name__) # Original functions from Gradio script {script.split('with gr.Blocks')[0].strip()} @app.route('/', methods=['GET', 'POST']) def index(): result = {{}} chatbot_messages = request.form.get('chatbot_messages', '[]') chatbot_messages = json.loads(chatbot_messages) if chatbot_messages else [] if request.method == 'POST': """ for i, input_comp in enumerate(components['inputs']): comp_type = input_comp.split('(')[0] if comp_type == 'gr.MultimodalTextbox': flask_code += f""" files = request.files.getlist('input_{i}') if files: inputs_{i} = [file.read() for file in files] else: inputs_{i} = request.form.get('input_{i}', '') """ elif comp_type == 'gr.Image': flask_code += f""" file = request.files.get('input_{i}') if file: inputs_{i} = Image.open(file) else: inputs_{i} = None """ elif comp_type in ['gr.Audio', 'gr.Video', 'gr.File']: flask_code += f""" file = request.files.get('input_{i}') if file: inputs_{i} = file.read() else: inputs_{i} = None """ elif comp_type == 'gr.Checkbox': flask_code += f""" inputs_{i} = request.form.get('input_{i}') == 'on' """ elif comp_type == 'gr.Number': flask_code += f""" inputs_{i} = float(request.form.get('input_{i}', 0)) """ else: flask_code += f""" inputs_{i} = request.form.get('input_{i}', '') """ for event_name, event in components['events'].items(): flask_code += f""" if '{event_name}' in request.form: inputs = [{', '.join(f'inputs_{components["inputs"].index(inp)}' for inp in event['inputs'])}] result['{event_name}'] = {event['fn']}(*inputs) if isinstance(result['{event_name}'], list): chatbot_messages.extend(result['{event_name}']) else: chatbot_messages.append({{ 'role': 'assistant', 'content': str(result['{event_name}']) }}) """ flask_code += """ if 'clear_chatbot' in request.form: chatbot_messages = [] """ flask_code += """ return render_template('index.html', result=result, chatbot_messages=json.dumps(chatbot_messages)) """ html_template = """