Recebendo Dados de Requisição como Objeto de Classe - FastAPI

O FastAPI permite mapear os dados de uma requisição diretamente para objetos de classes definidas pelo desenvolvedor. Essas classes devem herdar de pydantic.BaseModel e são projetadas para modelar os dados esperados na requisição.

Estrutura do Projeto

Para exemplificar, criaremos uma API que recebe um objeto contendo o nome e a idade de uma pessoa e retorna uma mensagem de boas-vindas com esses dados. A estrutura do projeto será organizada da seguinte forma:

.
├── public
│   └── index.html
├── main.py

Interface Web

Para testar a API, criaremos uma interface web que simula um cliente enviando dados ao servidor. O arquivo index.html conterá:

<!DOCTYPE html>
<html>
<head>
    <title>FastAPI Demo</title>
    <meta charset="utf-8" />
</head>
<body>
    <div id="message"></div>
    <p>
        Digite seu nome: <br />
        <input name="username" id="username" />
    </p>
    <p>
        Digite sua idade: <br />
        <input name="userage" id="userage" type="number" />
    </p>
    <button onclick="send()">Enviar</button>
    <script>
        async function send() {
            const username = document.getElementById("username").value;
            const userage = document.getElementById("userage").value;

            const response = await fetch("/hello", {
                method: "POST",
                headers: { "Accept": "application/json", "Content-Type": "application/json" },
                body: JSON.stringify({ 
                    name: username,
                    age: userage
                })
            });

            if (response.ok) {
                const data = await response.json();
                document.getElementById("message").textContent = data.message;
            } else {
                console.log(response);
            }
        }
    </script>
</body>
</html>

Esse formulário captura os dados inseridos pelo usuário e os envia para o endpoint /hello via uma requisição POST.

Configurando p Backend

O arquivo main.py conterá a definição da API:

from fastapi import FastAPI
from fastapi.responses import FileResponse
from pydantic import BaseModel

class Person(BaseModel):
    name: str
    age: int

app = FastAPI()

@app.get("/")
def root():
    return FileResponse("public/index.html")

@app.post("/hello")
def hello(person: Person):
    return {"message": f"Olá, {person.name}, sua idade é {person.age}"}

A classe Person é uma subclasse de BaseModel e define os campos name e age que serão mapeados a partir dos dados enviados pelo cliente.

O endpoint /hello recebe um objeto do tipo Person e retorna uma mensagem de boas-vindas contendo o nome e a idade da pessoa.

Exemplo de uso do FastAPI para receber dados de requisição como objeto de classe

Atributos Opcionais

No FastAPI, é possível tornar alguns atributos opcionais, atribuindo-lhes None como valor padrão:

from fastapi import FastAPI
from fastapi.responses import FileResponse
from pydantic import BaseModel

class Person(BaseModel):
    name: str
    age: int | None = None

app = FastAPI()

@app.get("/")
def root():
    return FileResponse("public/index.html")

@app.post("/hello")
def hello(person: Person):
    if person.age is None:
        return {"message": f"Olá, {person.name}"}
    else:
        return {"message": f"Olá, {person.name}, sua idade é {person.age}"}

Configuração Detalhada com Field

O módulo pydantic permite configurar validações e valores padrão com Field:

from fastapi import FastAPI
from fastapi.responses import FileResponse
from pydantic import BaseModel, Field

class Person(BaseModel):
    name: str = Field(default="Indefinido", min_length=3, max_length=20)
    age: int = Field(default=18, ge=18, lt=111)

app = FastAPI()

@app.get("/")
def root():
    return FileResponse("public/index.html")

@app.post("/hello")
def hello(person: Person):
    return {"message": f"Olá, {person.name}, sua idade é {person.age}"}

Nesse exemplo, o campo name deve ter entre 3 e 20 caracteres e o campo age deve ser maior ou igual a 18 e menor que 111.

Trabalhando com Listas

É possível receber listas de objetos:

from fastapi import FastAPI
from pydantic import BaseModel

class Person(BaseModel):
    name: str
    age: int

app = FastAPI()

@app.post("/hello")
def hello(people: list[Person]):
    return {"message": people}

Envio de exemplo com JavaScript:

const response = await fetch("/hello", {
    method: "POST",
    headers: { "Accept": "application/json", "Content-Type": "application/json" },
    body: JSON.stringify([
        { name: "Tom", age: 38 },
        { name: "Bob", age: 41 },
        { name: "Sam", age: 25 }
    ])
});
const data = await response.json();
console.log(data);

Modelos Aninhados

Modelos podem conter outros modelos:

from fastapi import FastAPI
from pydantic import BaseModel

class Company(BaseModel):
    name: str

class Person(BaseModel):
    name: str
    company: Company

app = FastAPI()

@app.post("/hello")
def hello(person: Person):
    return {"message": f"{person.name} trabalha na empresa {person.company.name}"}

Envio de exemplo com JavaScript:

const response = await fetch("/hello", {
    method: "POST",
    headers: { "Accept": "application/json", "Content-Type": "application/json" },
    body: JSON.stringify({ 
        name: "Tom",
        company: { name: "Google" }
    })
});
const data = await response.json();
console.log(data);
Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com