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 @app.get("/") def read_root(): return {"message": "Olá do Backend FastAPI!"} @app.get("/hello/{name}") def read_hello(name: str): return {"message": f"Olá, {name}! Bem-vindo(a)!"} @app.post("/items/") 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="/")