0% acharam este documento útil (0 voto)
6 visualizações

FastAPI

O documento fornece um guia passo a passo para aprender FastAPI, começando com pré-requisitos em Python, instalação e criação de um projeto básico. Ele aborda tópicos essenciais como roteamento, Pydantic para validação de dados, integração com bancos de dados e práticas recomendadas para desenvolvimento de APIs. Além disso, inclui exemplos de código e explicações sobre parâmetros de caminho e consulta, middleware e injeção de dependência.
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
6 visualizações

FastAPI

O documento fornece um guia passo a passo para aprender FastAPI, começando com pré-requisitos em Python, instalação e criação de um projeto básico. Ele aborda tópicos essenciais como roteamento, Pydantic para validação de dados, integração com bancos de dados e práticas recomendadas para desenvolvimento de APIs. Além disso, inclui exemplos de código e explicações sobre parâmetros de caminho e consulta, middleware e injeção de dependência.
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
Você está na página 1/ 31

📍 Etapa 1: Pré-requisitos

Antes de mergulhar no FastAPI, é importante ter:

🔹 Conhecimentos em Python
●​ Sintaxe básica​

●​ Funções​

●​ Estruturas de dados (listas, dicionários)​

●​ Manipulação de arquivos​

●​ Módulos e pacotes

🚀 Etapa 2: Aprender FastAPI do zero


🔹 Instalação do FastAPI e Uvicorn (servidor)
pip install fastapi uvicorn

🔹 Primeiro projeto
Crie um arquivo main.py:

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
return {"mensagem": "Olá, mundo!"}

Rode com:

uvicorn main:app --reload


Acesse em: http://127.0.0.1:8000​
Swagger (auto documentação): http://127.0.0.1:8000/docs

📚 Etapa 3: Estudar os principais tópicos do FastAPI


✅ Roteamento (GET, POST, PUT, DELETE)
✅ Pydantic (validação de dados com BaseModel)
✅ Query Parameters e Path Parameters
✅ Middleware e Dependency Injection
✅ CRUD com banco de dados (geralmente com SQLAlchemy + SQLite
ou PostgreSQL)

✅ Autenticação (OAuth2, JWT)


✅ Upload de arquivos
✅ CORS, versionamento de API e estrutura de projetos maiores
🛠 Etapa 4: Praticar com banco de dados
Aprenda a integrar com SQLAlchemy:

●​ Crie modelos com ORM​

●​ Faça um CRUD básico

💡 Etapa 5: Projeto prático


Escolha um projeto simples como:

●​ API de tarefas (To-Do List)​

●​ API de cadastro de usuários​

●​ API de biblioteca (livros, autores, empréstimos)​

Depois, pode usar:


●​ Docker para containerizar​

●​ Postman ou Swagger para testar​

●​ Hospedar no Render ou Railway

✅ pip install "fastapi[standard]" — O que


significa?
Esse comando instala o FastAPI junto com dependências extras úteis, como:

Pacote Função

uvicorn Servidor ASGI recomendado para rodar a aplicação

httpx Cliente HTTP assíncrono, útil para testes

python-doten Carregar variáveis de ambiente do .env


v

email-valida Validação de emails


tor

pydantic (Já vem com FastAPI) Validação e tipagem de


dados

📌 Quando usar fastapi[standard]


Use esse comando se você está:

●​ Começando do zero com FastAPI​

●​ Querendo o ambiente de desenvolvimento mais completo​

●​ Vai trabalhar com autenticação, testes ou uso de .env



Teoria: Roteamento e Métodos HTTP


(GET, POST, PUT, DELETE)
1. O que é roteamento?
●​ Roteamento é o processo pelo qual uma aplicação web decide qual código executar
quando recebe uma requisição em uma URL específica.​

●​ Cada rota está associada a um caminho (endpoint) e a um método HTTP (GET,


POST, etc).​

●​ No backend, ao definir rotas, indicamos quais URLs e métodos serão tratados por
quais funções.​

2. Métodos HTTP principais para APIs REST


APIs RESTful usam os métodos HTTP para definir a intenção da requisição. Os mais
comuns são:

a) GET

●​ Usado para recuperar dados do servidor.​

●​ É uma operação segura e idempotente (não altera o estado do servidor, pode ser
repetida sem efeitos colaterais).​

●​ Exemplo: buscar uma lista de usuários, detalhes de um item.​

b) POST

●​ Usado para criar um novo recurso no servidor.​

●​ Pode alterar o estado do servidor (ex: criar um novo registro no banco).​

●​ Não é idempotente — múltiplos POST criam múltiplos recursos.​

c) PUT

●​ Usado para atualizar um recurso existente.​

●​ Normalmente substitui o recurso inteiro com os dados enviados.​

●​ É idempotente — repetir a mesma requisição PUT tem o mesmo efeito que uma
única.​
d) DELETE

●​ Usado para remover um recurso do servidor.​

●​ Também é idempotente — deletar o mesmo recurso várias vezes não gera erros
adicionais (o recurso já estará removido).​

3. Como o roteamento usa esses métodos?


Cada rota na API define o caminho e o método HTTP aceito. Por exemplo:

●​ GET /usuarios → lista usuários​

●​ GET /usuarios/{id} → detalha usuário​

●​ POST /usuarios → cria novo usuário​

●​ PUT /usuarios/{id} → atualiza usuário​

●​ DELETE /usuarios/{id} → deleta usuário​

4. Por que essa organização?


●​ Seguir os métodos HTTP facilita a compreensão e padroniza a API.​

●​ Permite usar ferramentas que sabem interpretar a intenção do método (caches,


proxies, browsers).​

●​ Facilita o desenvolvimento front-end que consome a API.​

5. Idempotência e segurança
●​ Idempotente: mesmo efeito ao repetir a mesma requisição várias vezes.​

●​ Seguro: não altera o estado do servidor (apenas leitura).​


●​ GET é seguro e idempotente; PUT, DELETE são idempotentes; POST não é
idempotente.​

6. Exemplos rápidos (pseudocódigo):

GET /produtos -> listar produtos


POST /produtos -> criar novo produto
GET /produtos/123 -> obter detalhes do produto 123
PUT /produtos/123 -> atualizar produto 123
DELETE /produtos/123 -> deletar produto 123

✅ Roteamento (GET, POST, PUT, DELETE)

✅ 1. Setup básico
Crie um arquivo chamado main.py:

from fastapi import FastAPI


from pydantic import BaseModel
from typing import List

app = FastAPI()

# Modelo de dados
class Item(BaseModel):
id: int
nome: str
descricao: str = ""

# Banco de dados fictício (em memória)


itens = []

🔹 2. GET – Buscar todos os itens


@app.get("/itens", response_model=List[Item])
def get_itens():
return itens

🔹 3. POST – Criar um novo item


@app.post("/itens", response_model=Item)
def criar_item(item: Item):
itens.append(item)
return item

🔹 4. PUT – Atualizar um item pelo ID


@app.put("/itens/{item_id}", response_model=Item)
def atualizar_item(item_id: int, item_atualizado: Item):
for i, item in enumerate(itens):
if item.id == item_id:
itens[i] = item_atualizado
return item_atualizado
return {"erro": "Item não encontrado"}

🔹 5. DELETE – Remover um item pelo ID


@app.delete("/itens/{item_id}")
def deletar_item(item_id: int):
for i, item in enumerate(itens):
if item.id == item_id:
itens.pop(i)
return {"mensagem": "Item removido"}
return {"erro": "Item não encontrado"}

▶️ Executar a API
Terminal:

bash
CopiarEditar
uvicorn main:app --reload

📍
Abra o navegador em:​
http://127.0.0.1:8000/docs → Interface interativa para testar todas essas rotas!

✅ O que é BaseModel do Pydantic?


É uma classe base para modelos de dados, que:

●​ Valida os dados automaticamente​

●​ Garante os tipos corretos​

●​ Funciona tanto na entrada (input) quanto na saída (output) da API​



1. O que é Pydantic?
●​ Pydantic é uma biblioteca Python para validação de dados e parsing (análise e
conversão).​

●​ Ela transforma dados brutos (por exemplo, JSON recebidos em requisições) em


objetos Python fortemente tipados.​

●​ Permite garantir que os dados recebidos são do formato esperado antes de


processá-los.​

2. O que é BaseModel?
●​ BaseModel é a classe base do Pydantic para definir modelos de dados.​

●​ Você cria classes que herdam de BaseModel e define os campos (atributos) com
seus tipos.​

●​ O Pydantic automaticamente valida o tipo e os valores ao instanciar esses modelos.​


3. Por que usar Pydantic no FastAPI?
●​ FastAPI utiliza Pydantic para:​

○​ Validar e garantir a integridade dos dados enviados em requisições (ex:


JSON).​

○​ Converter automaticamente os dados para tipos Python.​

○​ Gerar documentação automática (ex: Swagger) com base nos modelos.​

●​ Isso facilita o desenvolvimento e evita erros comuns com dados inválidos.​

4. Como funciona a validação?


●​ Ao receber dados na API, FastAPI tenta criar uma instância do modelo Pydantic
correspondente.​

●​ Se os dados não estiverem corretos (tipo errado, campo obrigatório faltando, etc),
uma exceção é lançada automaticamente, gerando resposta 422 (Unprocessable
Entity).​

●​ Exemplos de validação: tipos (int, str), formatos (email, URL), valores


mínimos/máximos, campos opcionais, padrões regex, etc.​

📌 Exemplo básico
from pydantic import BaseModel

class Usuario(BaseModel):
id: int
nome: str
email: str
ativo: bool = True # valor padrão
✅ Como o FastAPI usa isso?
POST com validação automática:
python
CopiarEditar
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Usuario(BaseModel):
id: int
nome: str
email: str
ativo: bool = True

@app.post("/usuarios")
def criar_usuario(usuario: Usuario):
return {"mensagem": "Usuário criado", "dados": usuario}

Enviando esse JSON para a rota /usuarios:


json
CopiarEditar
{
"id": 1,
"nome": "Camylla",
"email": "[email protected]"
}

FastAPI responde:
json
CopiarEditar
{
"mensagem": "Usuário criado",
"dados": {
"id": 1,
"nome": "Camylla",
"email": "[email protected]",
"ativo": true
}
}

⚠️ Exemplo de validação funcionando


Se você enviar isso:

json
CopiarEditar
{
"id": "abc",
"nome": 123,
"email": true
}

A resposta será:

json
CopiarEditar
{
"detail": [
{
"loc": ["body", "id"],
"msg": "value is not a valid integer",
"type": "type_error.integer"
},
...
]
}

Ou seja, ele detecta e informa o erro automaticamente.

🛠 Dicas avançadas
✔️ Campos opcionais:
python
CopiarEditar
from typing import Optional
class Usuario(BaseModel):
nome: str
idade: Optional[int] = None

✔️ Validação de e-mail:
python
CopiarEditar
from pydantic import EmailStr

class Usuario(BaseModel):
nome: str
email: EmailStr # valida se é e-mail válido

Query Parameters e Path Parameters

1. O que são parâmetros em APIs?


Parâmetros são informações extras que você envia na requisição para filtrar, identificar ou
modificar a resposta da API.

2. Path Parameters (Parâmetros de caminho)


●​ Fazem parte do caminho (URL) da requisição.​

●​ São usados para identificar um recurso específico.​

●​ São obrigatórios, pois definem qual recurso a API deve acessar.​

●​ Exemplo:​

○​ URL: /usuarios/123​

○​ Aqui, 123 é um path parameter que indica o usuário de ID 123.​

Características
●​ Inseridos diretamente na URL.​

●​ Normalmente usados para identificar recursos (IDs, nomes únicos).​

●​ São definidos na rota, como /usuarios/{id}.​

●​ São capturados no backend para buscar, atualizar ou deletar o recurso


correspondente.​

3. Query Parameters (Parâmetros de consulta)


●​ Fazem parte da query string, que vem após o símbolo ? na URL.​

●​ Usados para filtrar, ordenar, paginar ou modificar a resposta.​

●​ São opcionais.​

●​ Exemplo:​

○​ URL: /usuarios?idade=30&cidade=SP​

○​ Aqui, idade=30 e cidade=SP são query parameters para filtrar os usuários.​

Características

●​ Não fazem parte do caminho da URL, mas sim da query string.​

●​ Podem ser múltiplos e opcionais.​

●​ Permitem enviar dados flexíveis para a API, como filtros, buscas, paginação.​

●​ São usados para modificar o comportamento da consulta sem mudar o recurso.​

4. Diferenças principais entre Path e Query Parameters


Aspecto Path Parameter Query Parameter

Localização na Dentro do caminho (ex: Após ? na URL (ex:


URL /users/1) /users?age=30)
Obrigatoriedade Obrigatório Opcional

Uso principal Identificar recursos específicos Filtrar, ordenar, paginar dados

Exemplo /produtos/45 /produtos?categoria=eletr


onicos

5. No FastAPI
●​ Path Parameters são declarados na definição da rota com chaves {} e passados
como argumentos na função.​

●​ Query Parameters são declarados como parâmetros da função com valores padrão
ou opcionais.

✅ Path Parameters (Parâmetros de caminho)


São os dados que fazem parte da URL, geralmente identificadores.

Exemplo:
python
CopiarEditar
from fastapi import FastAPI

app = FastAPI()

@app.get("/itens/{item_id}")
def ler_item(item_id: int):
return {"item_id": item_id}

●​ Aqui, item_id é obrigatório e faz parte da rota.​

●​ Exemplo de acesso: /itens/5 → retorna {"item_id": 5}​

✅ Query Parameters (Parâmetros de consulta)


São os dados que vêm depois do ? na URL, opcionais ou com valores padrão.
Exemplo:
python
CopiarEditar
@app.get("/buscar/")
def buscar_termo(q: str = None, limite: int = 10):
return {"query": q, "limite": limite}

●​ Acessando /buscar/?q=python&limite=5 → {"query": "python",


"limite": 5}​

●​ Se não passar nada: /buscar/ → {"query": null, "limite": 10} (limite


padrão 10)​

📝 Diferenças rápidas
Tipo Na URL Obrigatório Exemplo
?

Path No caminho, como parte da Sim /itens/3


Parameter rota

Query Depois do ? Não /buscar?q=teste&lim


Parameter (normal) ite=10

💡 Exemplo completo com os dois juntos:


python
CopiarEditar
@app.get("/usuarios/{usuario_id}/posts")
def get_posts(usuario_id: int, categoria: str = None, pagina: int =
1):
return {
"usuario_id": usuario_id,
"categoria": categoria,
"pagina": pagina
}
✅ Middleware no FastAPI
Middleware é uma função que executa código antes e/ou depois de cada requisição,
podendo modificar a requisição ou a resposta.

Middleware e Dependency Injection

1. Middleware
O que é Middleware?

●​ Middleware é uma camada intermediária que processa requisições e respostas


entre o cliente e a aplicação.​

●​ Funciona como um filtro ou interceptador das requisições antes que cheguem nas
rotas, e das respostas antes que sejam enviadas ao cliente.​

Para que serve?

●​ Autenticação e autorização​

●​ Logging (registro de logs)​

●​ Tratamento de erros genéricos​

●​ Modificação de cabeçalhos HTTP​

●​ CORS (controle de acesso de origem cruzada)​

●​ Medição de tempo de resposta​

●​ Aplicação de compressão ou cache​

Como funciona?

●​ Toda requisição passa pelo middleware antes de chegar na função que trata a rota.​
●​ O middleware pode permitir que a requisição prossiga, modificar os dados, ou
bloquear a requisição.​

2. Dependency Injection (Injeção de Dependências)


O que é Dependency Injection?

●​ É um padrão de design onde componentes (dependências) são fornecidos a


uma função ou objeto em vez de serem criados dentro dele.​

●​ Ajuda a separar responsabilidades, facilitando testes, manutenção e organização do


código.​

Por que usar?

●​ Facilita reutilização e teste de componentes (ex: conexão com banco,


autenticação).​

●​ Evita acoplamento forte entre componentes do sistema.​

●​ Permite gerenciar o ciclo de vida das dependências (ex: abrir e fechar conexão de
banco).​

Como funciona no FastAPI?

●​ FastAPI permite declarar dependências como parâmetros de funções com o


decorator especial Depends().​

●​ Quando a rota é chamada, FastAPI resolve e injeta automaticamente essas


dependências.​

●​ Exemplo de dependência: sessão de banco de dados, usuário autenticado, serviço


externo.​

Benefícios

●​ Código mais limpo, modular e testável.​

●​ Reuso de componentes comuns em diferentes rotas sem repetição.​


●​ Controle automático da criação e destruição das dependências.​

3. Resumo prático

Conceito Definição Exemplo de uso

Middleware Função que intercepta requisições e Log de requisições,


respostas autenticação

Dependency Fornecimento externo de recursos Injetar sessão do banco,


Injection para funções usuário atual

Exemplo simples de Middleware


python
CopiarEditar
from fastapi import FastAPI, Request
import time

app = FastAPI()

@app.middleware("http")
async def medir_tempo_request(request: Request, call_next):
inicio = time.time()
response = await call_next(request) # chama a próxima etapa
(rota, outro middleware)
duracao = time.time() - inicio
response.headers["X-Duration-Seconds"] = str(duracao)
return response

@app.get("/")
async def raiz():
return {"mensagem": "Olá, mundo!"}
Aqui o middleware mede o tempo que a requisição levou para ser processada e adiciona
esse dado no header da resposta.

✅ Dependency Injection (Injeção de Dependência)


No FastAPI, DI permite "injetar" dependências em funções automaticamente, como banco
de dados, autenticação, etc.

Exemplo básico de dependência


python
CopiarEditar
from fastapi import Depends, FastAPI

app = FastAPI()

def obter_usuario_atual():
return {"nome": "Camylla", "id": 1}

@app.get("/perfil")
def perfil(usuario: dict = Depends(obter_usuario_atual)):
return {"perfil_usuario": usuario}

Aqui a função obter_usuario_atual é injetada na rota automaticamente.

Exemplo prático com banco de dados fictício


python
CopiarEditar
def get_db():
db = "Conexão com banco fictícia"
try:
yield db
finally:
print("Fechando conexão com banco")

@app.get("/itens")
def listar_itens(db=Depends(get_db)):
return {"db": db, "itens": ["item1", "item2"]}
●​ get_db é um gerador que cria e limpa recursos.​

●​ O FastAPI cuida da execução, abertura e fechamento.​

Por que usar essas ferramentas?


●​ Middleware: para registrar logs, tratar erros globais, adicionar cabeçalhos,
autenticação, CORS etc.​

●​ Dependency Injection: para organizar código, reutilizar componentes, separar


responsabilidades.​

Explicação Teórica: CRUD com Banco de


Dados + SQLAlchemy

1. O que é CRUD?
CRUD é o acrônimo para as operações básicas que uma aplicação faz num banco de
dados:

●​ Create (Criar) → Inserir novos registros​

●​ Read (Ler) → Buscar registros existentes​

●​ Update (Atualizar) → Modificar registros existentes​

●​ Delete (Deletar) → Remover registros​

2. Por que usar um ORM (como SQLAlchemy)?


●​ ORM = Object-Relational Mapping (Mapeamento Objeto-Relacional)​

●​ Permite trabalhar com banco de dados usando objetos Python em vez de escrever
SQL manualmente.​
●​ Faz o mapeamento entre tabelas do banco e classes/objetos do seu código.​

●​ Facilita a manutenção e aumenta a produtividade, além de ajudar a prevenir erros de


SQL.​

3. Banco de dados: SQLite vs PostgreSQL


●​ SQLite​

○​ Banco de dados leve, embutido, usa arquivo local (.db)​

○​ Ideal para testes, protótipos e projetos pequenos​

●​ PostgreSQL​

○​ Banco de dados cliente-servidor robusto, usado em produção​

○​ Suporta mais recursos avançados, alta escalabilidade e segurança​

4. Como funciona a integração FastAPI + SQLAlchemy?


a) Configuração da conexão e sessão

●​ Você cria uma engine para conectar no banco (ex: SQLite, PostgreSQL).​

●​ Cria uma sessão (session) para gerenciar as transações (consultas, inserções etc).​

●​ O FastAPI usa dependência para abrir e fechar a sessão automaticamente a cada


requisição.​

b) Definição dos modelos (tabelas)

●​ Você define classes que herdam de uma base declarativa do SQLAlchemy.​

●​ Cada classe representa uma tabela, e seus atributos representam colunas.​

●​ Exemplo: class Item(Base): id = Column(Integer,


primary_key=True).​
c) Definição dos schemas Pydantic

●​ Para validar e serializar os dados enviados e recebidos pela API, você usa modelos
Pydantic.​

●​ Eles são diferentes dos modelos SQLAlchemy (que são para banco), mas espelham
os campos principais.​

5. Operações CRUD na prática


●​ Create:​

○​ Cria um objeto da classe modelo.​

○​ Adiciona na sessão, faz commit para salvar no banco.​

○​ Retorna o objeto salvo (com ID gerado).​

●​ Read:​

○​ Consulta registros usando filtros (ex: por ID, com limite).​

○​ Retorna os objetos correspondentes.​

●​ Update:​

○​ Consulta o objeto.​

○​ Modifica os campos desejados.​

○​ Comita as mudanças no banco.​

●​ Delete:​

○​ Consulta o objeto.​

○​ Deleta da sessão.​

○​ Comita a operação.​
6. Benefícios de usar FastAPI com SQLAlchemy para
CRUD
●​ Integração natural com validação via Pydantic.​

●​ Código Python limpo e organizado.​

●​ Reuso com dependências (sessions, autenticação, etc).​

●​ Interface automática de documentação (Swagger) para testar suas rotas CRUD.​

1. Instale as dependências

pip install fastapi[standard] sqlalchemy sqlite3 databases alembic

2. Estrutura básica do projeto

/app
├── main.py
├── database.py
├── models.py
└── schemas.py

3. database.py — Configuração do banco e sessão


python
CopiarEditar
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, declarative_base

SQLALCHEMY_DATABASE_URL = "sqlite:///./test.db"

engine = create_engine(
SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread":
False}
)

SessionLocal = sessionmaker(autocommit=False, autoflush=False,


bind=engine)

Base = declarative_base()

4. models.py — Definindo os modelos (tabelas)

from sqlalchemy import Column, Integer, String


from database import Base

class Item(Base):
__tablename__ = "itens"

id = Column(Integer, primary_key=True, index=True)


nome = Column(String, index=True)
descricao = Column(String, index=True)

5. schemas.py — Definindo os Pydantic models


(validação)

from pydantic import BaseModel

class ItemBase(BaseModel):
nome: str
descricao: str | None = None

class ItemCreate(ItemBase):
pass

class Item(ItemBase):
id: int

class Config:
orm_mode = True
6. main.py — CRUD e rotas

from fastapi import FastAPI, Depends, HTTPException


from sqlalchemy.orm import Session

import models, schemas


from database import SessionLocal, engine, Base

Base.metadata.create_all(bind=engine)

app = FastAPI()

# Dependency para obter a sessão do DB


def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()

@app.post("/itens/", response_model=schemas.Item)
def criar_item(item: schemas.ItemCreate, db: Session =
Depends(get_db)):
db_item = models.Item(nome=item.nome, descricao=item.descricao)
db.add(db_item)
db.commit()
db.refresh(db_item)
return db_item

@app.get("/itens/", response_model=list[schemas.Item])
def ler_itens(skip: int = 0, limit: int = 10, db: Session =
Depends(get_db)):
itens = db.query(models.Item).offset(skip).limit(limit).all()
return itens

@app.get("/itens/{item_id}", response_model=schemas.Item)
def ler_item(item_id: int, db: Session = Depends(get_db)):
item = db.query(models.Item).filter(models.Item.id ==
item_id).first()
if not item:
raise HTTPException(status_code=404, detail="Item não
encontrado")
return item

@app.put("/itens/{item_id}", response_model=schemas.Item)
def atualizar_item(item_id: int, item: schemas.ItemCreate, db:
Session = Depends(get_db)):
db_item = db.query(models.Item).filter(models.Item.id ==
item_id).first()
if not db_item:
raise HTTPException(status_code=404, detail="Item não
encontrado")
db_item.nome = item.nome
db_item.descricao = item.descricao
db.commit()
db.refresh(db_item)
return db_item

@app.delete("/itens/{item_id}")
def deletar_item(item_id: int, db: Session = Depends(get_db)):
db_item = db.query(models.Item).filter(models.Item.id ==
item_id).first()
if not db_item:
raise HTTPException(status_code=404, detail="Item não
encontrado")
db.delete(db_item)
db.commit()
return {"mensagem": "Item deletado com sucesso"}

7. Rodando a aplicação

uvicorn main:app --reload

8. Testando
●​ Abra no navegador:​
http://127.0.0.1:8000/docs​
para acessar a interface interativa Swagger UI.

✅ Autenticação (OAuth2, JWT)

1. Autenticação (OAuth2, JWT)

Teoria
OAuth2

●​ Protocolo padrão para autorização, permite que apps acessem recursos protegidos
em nome do usuário.​

●​ Usa "tokens de acesso" para autorizar, sem compartilhar senhas.​

●​ É complexo, mas seguro para apps que precisam acessar APIs externas (ex: login
via Google).​

JWT (JSON Web Token)

●​ Formato compacto e seguro para representar informações entre duas partes.​

●​ Usado para autenticação: servidor gera um token com dados do usuário, que é
enviado no cabeçalho das requisições.​

●​ Token é auto-contido, assinado digitalmente, para verificar autenticidade e evitar


manipulação.​

●​ Permite APIs stateless (sem guardar sessão no servidor).​

Exemplo simples de JWT no FastAPI


python
CopiarEditar
from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer,
OAuth2PasswordRequestForm
import jwt
from datetime import datetime, timedelta

app = FastAPI()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

SECRET_KEY = "segredo_supersecreto"

def criar_token(data: dict, expires_delta: timedelta):


to_encode = data.copy()
to_encode.update({"exp": datetime.utcnow() + expires_delta})
return jwt.encode(to_encode, SECRET_KEY, algorithm="HS256")

@app.post("/token")
def login(form_data: OAuth2PasswordRequestForm = Depends()):
# Aqui você validaria usuário e senha no banco
if form_data.username != "usuario" or form_data.password !=
"senha":
raise HTTPException(status_code=400, detail="Credenciais
inválidas")
token = criar_token({"sub": form_data.username},
timedelta(minutes=30))
return {"access_token": token, "token_type": "bearer"}

@app.get("/usuario")
def ler_usuario(token: str = Depends(oauth2_scheme)):
try:
payload = jwt.decode(token, SECRET_KEY,
algorithms=["HS256"])
usuario = payload.get("sub")
if usuario is None:
raise HTTPException(status_code=401, detail="Token
inválido")
return {"usuario": usuario}
except jwt.PyJWTError:
raise HTTPException(status_code=401, detail="Token inválido
ou expirado")
2. Upload de arquivos

Teoria
●​ APIs permitem que clientes enviem arquivos (imagens, documentos).​

●​ O backend precisa receber e armazenar esses arquivos.​

●​ O FastAPI facilita recebendo arquivos via File e UploadFile.​

●​ Arquivos podem ser salvos no disco, banco ou processados em memória.​

Exemplo simples de upload


python
CopiarEditar
from fastapi import FastAPI, UploadFile, File

app = FastAPI()

@app.post("/upload")
async def upload_arquivo(file: UploadFile = File(...)):
conteudo = await file.read()
with open(f"arquivos/{file.filename}", "wb") as f:
f.write(conteudo)
return {"filename": file.filename, "content_type":
file.content_type}

3. CORS, versionamento de API e


estrutura de projetos maiores

Teoria
CORS (Cross-Origin Resource Sharing)
●​ Segurança dos navegadores que bloqueia requisições de origens diferentes
(domínios).​

●​ API pode liberar CORS para permitir que sites externos acessem seus recursos.​

●​ FastAPI tem middleware para configurar CORS facilmente.​

Versionamento de API

●​ Boas práticas indicam versionar APIs (/v1/, /v2/) para permitir evolução sem
quebrar clientes antigos.​

●​ Pode ser feito por URL, header ou parâmetro.​

Estrutura de projetos maiores

●​ Em projetos maiores, separar o código em módulos:​

○​ Rotas (endpoints) organizados por funcionalidade​

○​ Modelos e schemas (Pydantic) separados​

○​ Serviços (lógica de negócio) isolados​

○​ Configurações e middlewares em arquivos próprios​

●​ Isso facilita manutenção, testes e escalabilidade.

Exemplos simples
CORS no FastAPI

from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # ou lista de domínios permitidos
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
Versionamento básico pela URL
python
CopiarEditar
from fastapi import APIRouter, FastAPI

app = FastAPI()

v1 = APIRouter(prefix="/v1")
v2 = APIRouter(prefix="/v2")

@v1.get("/produtos")
def produtos_v1():
return {"versao": "v1", "produtos": []}

@v2.get("/produtos")
def produtos_v2():
return {"versao": "v2", "produtos": ["novo"]}

app.include_router(v1)
app.include_router(v2)

Estrutura simplificada (exemplo)

/app
/routers
usuarios.py
produtos.py
/models
usuario.py
produto.py
/schemas
usuario.py
produto.py
main.py

Você também pode gostar