import gradio as gr import requests from PIL import Image import io # URL de tu API # Si estás ejecutando esto en local, suele ser http://127.0.0.1:8000 # Si la API está en Render, usa la URL de Render (ej: https://tuproyecto.onrender.com) API_URL = "https://predictor-api-lab3.onrender.com" def solicitar_prediccion(image_path): """ Envía la imagen al endpoint /predict """ if image_path is None: return "You must upload an image first." try: # Abrimos la imagen en modo binario para enviarla with open(image_path, "rb") as f: files = {"file": f} response = requests.post(f"{API_URL}/predict", files=files, timeout=10) response.raise_for_status() data = response.json() # Devolvemos la predicción return f"Prediction: {data.get('prediction')}" except requests.exceptions.RequestException as e: return f"Error connecting to the API: {str(e)}" except Exception as e: return f"Unknown error: {str(e)}" def solicitar_resize(image_path, width, height): """ Envía la imagen y dimensiones al endpoint /resize """ if image_path is None: return None try: # Validar inputs if width <= 0 or height <= 0: print("Width and height must be positive.") return None payload = {"width": int(width), "height": int(height)} with open(image_path, "rb") as f: files = {"file": f} # Nota: 'data' se usa para los campos del Form (width, height) # y 'files' para el archivo response = requests.post(f"{API_URL}/resize", data=payload, files=files, timeout=10) response.raise_for_status() # La API devuelve una imagen en bytes (StreamingResponse) # La convertimos a objeto PIL Image para que Gradio la pueda mostrar image_stream = io.BytesIO(response.content) return Image.open(image_stream) except requests.exceptions.RequestException as e: print(f"Error API: {e}") return None # --- Construcción de la Interfaz con Blocks --- with gr.Blocks(title="Predictor & Resizer API Client") as demo: gr.Markdown("# Image API Client") gr.Markdown("Upload an image and choose whether you want to get a prediction or resize it.") with gr.Row(): # Left Column: Input with gr.Column(): gr.Markdown("### 1. Input Image") # Selector de imágenes. 'type="filepath"' guarda la imagen temporalmente y nos da la ruta input_image = gr.Image(label="Upload your image", type="filepath") # Right Column: Actions with gr.Column(): # --- Prediction Section --- gr.Markdown("### 2. Prediction") predict_btn = gr.Button("🔍 Get Prediction", variant="primary") predict_output = gr.Textbox(label="API Result") # CORRECCIÓN AQUÍ: gr.HTML en mayúsculas gr.HTML("
") # --- Resize Section --- gr.Markdown("### 3. Resize Image") with gr.Row(): w_input = gr.Number(label="Width", value=200, precision=0) h_input = gr.Number(label="Height", value=200, precision=0) resize_btn = gr.Button("🖼️ Resize Image") resize_output = gr.Image(label="Resized Image") # --- Connect Logic --- # Prediction Button predict_btn.click( fn=solicitar_prediccion, inputs=[input_image], outputs=predict_output ) # Botón Resize resize_btn.click( fn=solicitar_resize, inputs=[input_image, w_input, h_input], outputs=resize_output ) # Launch the app if __name__ == "__main__": demo.launch()