import gradio as gr def add_numbers(data): """Python function that adds two numbers""" try: num1 = float(data.get("num1", 0)) num2 = float(data.get("num2", 0)) result = num1 + num2 return {"result": result, "expression": f"{num1} + {num2} = {result}"} except (ValueError, TypeError) as e: return {"result": "Error", "expression": f"Invalid input: {e}"} # HTML for the math calculator MATH_HTML = """

Math Calculator

Custom HTML calling Python via Gradio

+
Result from Python:
${value.result !== undefined ? value.result : '—'}
${value.expression || ''}
Ready
""" # CSS for the math calculator MATH_CSS = """ """ # JavaScript that wires up the UI and calls Python via trigger MATH_JS = """ (function() { function $(sel) { return element.querySelector(sel); } function updateStatus(msg) { $('#status').textContent = msg; } // When calculate button is clicked $('#calculate-btn').addEventListener('click', function() { var num1 = parseFloat($('#num1').value) || 0; var num2 = parseFloat($('#num2').value) || 0; updateStatus('Calling Python...'); // Update props.value with the data to send to Python props.value = { num1: num1, num2: num2 }; // Trigger the 'submit' event which calls the Python function trigger('submit'); }); // Allow Enter key to trigger calculation $('#num1').addEventListener('keypress', function(e) { if (e.key === 'Enter') $('#calculate-btn').click(); }); $('#num2').addEventListener('keypress', function(e) { if (e.key === 'Enter') $('#calculate-btn').click(); }); updateStatus('Ready - Enter numbers and click Calculate'); })(); """ # JavaScript to handle the response from Python MATH_JS_CHANGE = """ (function() { function $(sel) { return element.querySelector(sel); } // This runs when the component value changes (i.e., when Python returns) if (props.value && props.value.result !== undefined) { $('#result-value').textContent = props.value.result; $('#result-expression').textContent = props.value.expression || ''; $('#status').textContent = 'Calculated by Python at ' + new Date().toLocaleTimeString(); } })(); """ # Create the Gradio app with gr.Blocks(fill_height=True, title="Math Calculator") as demo: calculator = gr.HTML( value={}, html_template=MATH_CSS + MATH_HTML, js_on_load=MATH_JS, container=False ) # When JS triggers 'submit', call add_numbers and update the component calculator.submit(add_numbers, inputs=calculator, outputs=calculator) if __name__ == "__main__": demo.launch()