Spec Backend Com Python E Fastapi • Trilha Progressiva em 4 Níveis


🎯 Nível 1: Fundamentos

Problema 03.1 — Extração de Path Parameters e Query com Tipagem

Contexto: Extração de Path Parameters e Query com Tipagem no contexto de Parâmetros de Rota, Query, Headers e Body.

Requisitos de Execução:

  1. Criar endpoint /items/{item_id} aceitando parâmetro obrigatório de rota e filtro de busca opcional.

Resultado Esperado

GET /items/42?q=search -> {'item_id': 42, 'filtro': 'search'}

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_03_1_SeuNome
  2. Envie na tarefa: Atividade Cap 03 - Parâmetros de Rota, Query, Headers e Body
🔑 Gabarito de Código & Solução Comentada
# path_query.py
from fastapi import FastAPI, Path, Query
from typing import Optional

app = FastAPI()

@app.get("/items/{item_id}")
async def read_item(
    item_id: int = Path(..., ge=1, description="ID do item positivo"),
    q: Optional[str] = Query(None, min_length=3, max_length=50)
):
    return {"item_id": item_id, "filtro": q}

🔍 Nível 2: Prática

Problema 03.2 — Validação de Corpo de Requisição com Múltiplos Modelos

Contexto: Validação de Corpo de Requisição com Múltiplos Modelos no contexto de Parâmetros de Rota, Query, Headers e Body.

Requisitos de Execução:

  1. Criar rota POST /pedidos recebendo objeto Cliente e lista de ItemPedido no mesmo payload.

Resultado Esperado

POST /pedidos -> 201 Created com total calculado.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_03_2_SeuNome
  2. Envie na tarefa: Atividade Cap 03 - Parâmetros de Rota, Query, Headers e Body
🔑 Gabarito de Código & Solução Comentada
# body_multiple.py
from fastapi import FastAPI, Body, status
from pydantic import BaseModel
from typing import List

class ItemPedido(BaseModel):
    produto_id: int
    quantidade: int
    preco_unitario: float

class ClienteRef(BaseModel):
    cliente_id: int
    nome: str

app = FastAPI()

@app.post("/pedidos", status_code=status.HTTP_201_CREATED)
async def criar_pedido(cliente: ClienteRef = Body(...), itens: List[ItemPedido] = Body(...)):
    total = sum(i.quantidade * i.preco_unitario for i in itens)
    return {"cliente": cliente.nome, "total": total, "qtd_itens": len(itens)}

⚡ Nível 3: Integração

Problema 03.3 — Extração e Validação de Headers Customizados e Cookies

Contexto: Extração e Validação de Headers Customizados e Cookies no contexto de Parâmetros de Rota, Query, Headers e Body.

Requisitos de Execução:

  1. Extrair cabeçalho X-Tenant-ID obrigatório e cookie de sessão session_id validando formato UUID.

Resultado Esperado

Header X-Tenant-ID extraído: 'corp_alpha' | Cookie de Sessão validado.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_03_3_SeuNome
  2. Envie na tarefa: Atividade Cap 03 - Parâmetros de Rota, Query, Headers e Body
🔑 Gabarito de Código & Solução Comentada
# headers_cookies.py
from fastapi import FastAPI, Header, Cookie, HTTPException
from typing import Optional

app = FastAPI()

@app.get("/tenant-info")
async def obter_tenant(
    x_tenant_id: str = Header(..., description="ID da organização no header"),
    session_id: Optional[str] = Cookie(None)
):
    if not x_tenant_id.startswith("corp_"):
        raise HTTPException(status_code=400, detail="Tenant ID inválido")
    return {"tenant": x_tenant_id, "session_active": session_id is not None}

🏆 Nível 4: Desafio Corporativo

Problema 03.4 — Endpoint com Upload de Arquivos Multipart e Validação de Mime-Type

Contexto: Endpoint com Upload de Arquivos Multipart e Validação de Mime-Type no contexto de Parâmetros de Rota, Query, Headers e Body.

Requisitos de Execução:

  1. Implementar rota /upload-documento aceitando UploadFile e validando extensão (.pdf, .png) e tamanho máximo.

Resultado Esperado

Upload validado: 'relatorio.pdf' (1.2 MB, application/pdf).

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_03_4_SeuNome
  2. Envie na tarefa: Atividade Cap 03 - Parâmetros de Rota, Query, Headers e Body
🔑 Gabarito de Código & Solução Comentada
# upload_handler.py
from fastapi import FastAPI, UploadFile, File, HTTPException

app = FastAPI()
MAX_FILE_SIZE = 5 * 1024 * 1024  # 5MB

@app.post("/upload-documento")
async def upload_documento(arquivo: UploadFile = File(...)):
    if arquivo.content_type not in ["application/pdf", "image/png"]:
        raise HTTPException(status_code=415, detail="Tipo de mídia não suportado")
    conteudo = await arquivo.read()
    if len(conteudo) > MAX_FILE_SIZE:
        raise HTTPException(status_code=413, detail="Arquivo excede limite de 5MB")
    return {"filename": arquivo.filename, "tamanho_bytes": len(conteudo)}