Spaces:
Runtime error
Runtime error
| import gradio as gr | |
| from fastapi import FastAPI | |
| from pydantic import BaseModel | |
| from typing import Optional | |
| # --- Backend FastAPI --- | |
| app = FastAPI() | |
| class Item(BaseModel): | |
| name: str | |
| description: Optional[str] = None | |
| price: float | |
| def read_root(): | |
| return {"message": "Olá do Backend FastAPI!"} | |
| def read_hello(name: str): | |
| return {"message": f"Olá, {name}! Bem-vindo(a)!"} | |
| def create_api_item(item: Item): | |
| return item | |
| # --- Funções de Lógica (agora chamadas diretamente) --- | |
| def get_hello_message(name: str): | |
| """Chama a lógica do backend diretamente.""" | |
| if not name: | |
| return "Por favor, insira um nome." | |
| # Chamada direta à função do backend | |
| response = read_hello(name) | |
| return response.get("message", "Resposta inesperada.") | |
| def create_item(name: str, description: str, price: float): | |
| """Chama a lógica do backend diretamente.""" | |
| # Validação explícita para evitar problemas com valores 'falsy' como 0.0 | |
| if not name or price is None: | |
| # Retorna um JSON vazio ou uma mensagem de erro, mantendo o tipo de saída consistente. | |
| return gr.JSON(value={"error": "Nome e Preço são campos obrigatórios."}) | |
| # Cria uma instância do modelo Pydantic, como o backend espera | |
| item_model = Item( | |
| name=name, | |
| description=description, | |
| price=float(price) # Garante que o tipo é float | |
| ) | |
| # Chamada direta à função do backend | |
| # O Gradio espera um dicionário para o componente gr.JSON, então convertemos o modelo. | |
| return create_api_item(item_model).model_dump() | |
| # --- Interface Gradio --- | |
| with gr.Blocks(title="FastAPI + Gradio Integrado") as demo: | |
| gr.Markdown("# 🚀 FastAPI + Gradio Integrado") | |
| gr.Markdown("**Backend e Frontend em um único app!**") | |
| with gr.Tab("🏠 Saudação Raiz"): | |
| gr.Markdown("### Endpoint: GET /") | |
| btn_root = gr.Button("Chamar API Raiz", variant="primary") | |
| output_root = gr.Textbox( | |
| label="Resposta da API", | |
| placeholder="Clique no botão para ver a mensagem...", | |
| lines=3 | |
| ) | |
| # Para a rota raiz, podemos simplesmente chamar a função do backend diretamente no click | |
| btn_root.click( | |
| fn=lambda: read_root().get("message", "Resposta inesperada."), | |
| inputs=None, | |
| outputs=output_root) | |
| with gr.Tab("👋 Saudação com Nome"): | |
| gr.Markdown("### Endpoint: GET /hello/{name}") | |
| with gr.Row(): | |
| with gr.Column(): | |
| input_name = gr.Textbox( | |
| label="Digite seu nome", | |
| placeholder="Seu nome aqui..." | |
| ) | |
| btn_hello = gr.Button("Enviar Saudação", variant="primary") | |
| with gr.Column(): | |
| output_hello = gr.Textbox( | |
| label="Resposta da API", | |
| lines=3 | |
| ) | |
| btn_hello.click(fn=get_hello_message, inputs=input_name, outputs=output_hello) | |
| with gr.Tab("📦 Criar Item"): | |
| gr.Markdown("### Endpoint: POST /items/") | |
| with gr.Row(): | |
| with gr.Column(): | |
| input_item_name = gr.Textbox( | |
| label="Nome do Item*", | |
| placeholder="Nome do item..." | |
| ) | |
| input_item_desc = gr.Textbox( | |
| label="Descrição do Item (Opcional)", | |
| placeholder="Descrição do item...", | |
| lines=2 | |
| ) | |
| input_item_price = gr.Number( | |
| label="Preço do Item*", | |
| value=0.0 | |
| ) | |
| btn_create = gr.Button("Criar Item", variant="primary") | |
| with gr.Column(): | |
| output_item = gr.JSON( | |
| label="Item Criado (Resposta da API)" | |
| ) | |
| btn_create.click( | |
| fn=create_item, | |
| inputs=[input_item_name, input_item_desc, input_item_price], | |
| outputs=output_item | |
| ) | |
| # Rodapé | |
| gr.Markdown("---") | |
| gr.Markdown("### 🔧 Desenvolvido com Gradio (Frontend) + FastAPI (Backend)") | |
| # Monta a interface Gradio na aplicação FastAPI. | |
| # A plataforma do Hugging Face Spaces detectará o objeto 'app' e o executará com um servidor ASGI (Uvicorn). | |
| app = gr.mount_gradio_app(app, demo, path="/") |