🧩 Exercícios: Parâmetros de Rota, Query, Headers e Body
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:
- 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)
- Salve o arquivo como:
Atividade_03_1_SeuNome - 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:
- Criar rota POST
/pedidosrecebendo objetoClientee lista deItemPedidono mesmo payload.
Resultado Esperado
POST /pedidos -> 201 Created com total calculado.
📤 Instruções de Entrega (Microsoft Teams)
- Salve o arquivo como:
Atividade_03_2_SeuNome - 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:
- Extrair cabeçalho
X-Tenant-IDobrigatório e cookie de sessãosession_idvalidando formato UUID.
Resultado Esperado
Header X-Tenant-ID extraído: 'corp_alpha' | Cookie de Sessão validado.
📤 Instruções de Entrega (Microsoft Teams)
- Salve o arquivo como:
Atividade_03_3_SeuNome - 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:
- Implementar rota
/upload-documentoaceitandoUploadFilee 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)
- Salve o arquivo como:
Atividade_03_4_SeuNome - 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)}