API CRUD de usuarios criada com FastAPI, Python 3.14 e arquitetura Ports and Adapters.
O projeto foi pensado para estudo de deploy no Kubernetes, por isso inclui:
- persistencia apenas em memoria
- Swagger para exploracao da API
- testes unitarios e de endpoint
- endpoints de health check para liveness e readiness
- workflow de CI para execucao automatica dos testes
- Python 3.14
- FastAPI
- Uvicorn
- Pydantic
- Pytest
- Pytest Cov
- Black
- isort
- flake8
- bandit
- mypy
Entidade principal: Usuario
id: intnome: stringdtNascimento: datestatus: booltelefones: string[]
O projeto segue o modelo Ports and Adapters:
domain: regras e contratos do dominioapplication: casos de uso e servicosadapters/inbound: entrada HTTP da aplicacaoadapters/outbound: persistencia em memoria
Estrutura simplificada:
src
|-- adapters
| |-- inbound
| | `-- http
| | `-- routes
| `-- outbound
| `-- repositories
|-- application
| `-- services
|-- domain
| `-- ports
`-- main.py
- Python 3.14 instalado
- Linux, macOS ou Windows (PowerShell/Bash)
pythonoupy -3.14disponivel no terminal
Para validar a instalacao do Python:
No Windows:
py -3.14 --versionNo Linux ou macOS:
python3 --versionInstale o uv caso ele ainda nao esteja disponivel.
No Windows com PowerShell:
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"No Linux ou macOS:
curl -LsSf https://astral.sh/uv/install.sh | she depois execute
source "$HOME/.local/bin/env"Valide a instalacao:
uv --versionOs comandos abaixo devem ser executados dentro da pasta source:
cd sourceInstalar o Python 3.14 e sincronizar as dependencias da aplicacao e de desenvolvimento:
uv python install 3.14
uv sync --project source --extra dev --activeCom recarga automatica durante o desenvolvimento:
uv run uvicorn main:app --app-dir src --reloadOu executando o arquivo principal diretamente, na porta 8080:
uv run python src/main.pyuv run pytest
uv run pytest --cov=src --cov-report=term-missinguv run isort --settings-path pyproject.toml src
uv run black --config pyproject.toml srcuv run isort --check-only --settings-path pyproject.toml src
uv run black --check --config pyproject.toml src
uv run flake8 --toml-config pyproject.toml src
uv run mypy --config-file pyproject.toml src
uv run bandit -c pyproject.toml -r src# Adicionar ou remover uma dependencia da aplicacao
uv add nome-do-pacote
uv remove nome-do-pacote
# Adicionar uma dependencia opcional ao grupo dev
uv add --optional dev nome-do-pacote
# Atualizar o lockfile e sincronizar o ambiente
uv lock
uv lock --upgrade
uv sync --upgrade
# Visualizar a arvore de dependencias
uv treeAtencao: o
pyproject.tomldeclarareadme = "README.md", mas este arquivo esta um nivel acima da pastasource. Seuv syncfalhar ao instalar o projeto, ajuste esse caminho ou disponibilize um README dentro desource.
O Dockerfile usa uv sync --frozen e o uv.lock para instalar somente as
dependencias de producao. Execute os comandos na raiz do repositorio:
docker buildx build -f docker/Dockerfile -t usuarios-api .
docker run --rm -p 8080:8080 usuarios-apiO uv e usado apenas durante o build e nao e incluido na imagem final.
Execute os comandos na raiz do repositorio:
docker buildx build -f docker/Dockerfile-pip -t usuarios-api-pip .
docker run --rm -p 8080:8080 usuarios-api-pipCaso prefira utilizar o fluxo tradicional com pip e venv, execute dentro da pasta source:
python3 -m venv source/.venv
source ./source/.venv/bin/activate
python3 -m pip install --upgrade pip
pip install -e "./source[dev]"
python3 source/src/main.pyNo Linux / macOS (Bash):
python3 -m venv source/.venvNo Windows (PowerShell):
py -3.14 -m venv source/.venvNo Linux / macOS (Bash):
source source/.venv/bin/activateNo Windows (PowerShell):
.\source\.venv\Scripts\Activate.ps1Se o PowerShell bloquear a execucao de scripts, rode uma vez:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUserpython -m pip install --upgrade pip
pip install -e .[dev]Para instalar apenas as dependencias de producao:
pip install .Opcao 1, executando diretamente o arquivo principal:
python src/main.pyOpcao 2, usando Uvicorn com recarga automatica:
uvicorn main:app --app-dir src --reloadCom a API em execucao, abra:
- API:
http://127.0.0.1:8000 - Swagger UI:
http://127.0.0.1:8000/docs - OpenAPI JSON:
http://127.0.0.1:8000/openapi.json
Com o ambiente virtual ativo:
pytest --cov=src --cov-report=term-missingNa raiz do repositorio, execute a verificacao de vulnerabilidades com Trivy:
trivy fs --scanners vuln --format table --dependency-tree .Dentro da pasta source, os mesmos checks de qualidade executados pelo CI sao:
py -3.14 -m isort --check-only --settings-path ./pyproject.toml ./src
py -3.14 -m black --check --config ./pyproject.toml ./src
py -3.14 -m flake8 --toml-config ./pyproject.toml ./src
$env:MYPYPATH = './src'
py -3.14 -m mypy --config-file ./pyproject.toml ./src
py -3.14 -m bandit -c ./pyproject.toml -r ./srcResultado esperado no estado atual do projeto:
- testes unitarios do servico
- testes dos endpoints HTTP
- cobertura de 100%
O projeto tambem possui ferramentas de padronizacao e analise estatica configuradas em pyproject.toml.
Responsavel por formatar o codigo automaticamente, mantendo um padrao consistente no projeto.
Configuracao atual:
line-length = 88target-version = py314
Executar:
black --config pyproject.toml srcResponsavel por organizar os imports e manter o estilo compativel com o Black.
Configuracao atual:
- perfil
black line_length = 88
Executar:
isort --settings-path pyproject.toml srcResponsavel por fazer checagem estatica de tipos para identificar inconsistencias antes da execucao.
Configuracao atual:
python_version = 3.14check_untyped_defs = truedisallow_incomplete_defs = trueno_implicit_optional = true
Executar:
mypy --config-file pyproject.toml srcEsses pacotes fazem parte do grupo dev, junto com as dependencias de teste.
pip install -e .[dev]GET /health/liveGET /health/ready
Uso no Kubernetes:
live: verifica se a aplicacao esta vivaready: verifica se a aplicacao esta pronta para receber trafego
POST /usuariosGET /usuariosGET /usuarios/{usuario_id}PUT /usuarios/{usuario_id}DELETE /usuarios/{usuario_id}
Requisicao:
{
"id": 1,
"nome": "Carlos",
"dtNascimento": "1992-03-14",
"status": true,
"telefones": [
"11911112222",
"1122223333"
]
}{
"id": 1,
"nome": "Carlos",
"dtNascimento": "1992-03-14",
"status": true,
"telefones": [
"11911112222",
"1122223333"
]
}Criar usuario:
curl -X POST "http://127.0.0.1:8000/usuarios" \
-H "Content-Type: application/json" \
-d "{\"id\":1,\"nome\":\"Carlos\",\"dtNascimento\":\"1992-03-14\",\"status\":true,\"telefones\":[\"11911112222\",\"1122223333\"]}"Listar usuarios:
curl "http://127.0.0.1:8000/usuarios"Verificar readiness:
curl "http://127.0.0.1:8000/health/ready"Os dados sao armazenados somente em memoria.
Implicacoes:
- ao reiniciar a aplicacao, os dados sao perdidos
- nao existe dependencia de banco de dados
- o comportamento e ideal para estudo de API, testes e deploy em Kubernetes
O workflow de CI fica em .github/workflows/ci.yml e executa:
- instalacao das dependencias
- execucao dos testes
- geracao de relatorio JUnit para os testes
As versoes declaradas do projeto ficam em pyproject.toml.
Dependencias diretas atuais do projeto:
fastapi >= 0.135.1uvicorn >= 0.41.0httpx >= 0.28.1black >= 26.3.0isort >= 8.0.1mypy >= 1.19.1pytest >= 9.0.2pytest-cov >= 7.0.0
Observacao importante:
- dependencias transitivas, como
pydantic_core, normalmente nao devem ser atualizadas isoladamente - para dependencias diretas, o ideal e atualizar, rodar testes e revisar changelog antes de subir para producao
Formas praticas de acompanhar isso:
- rodar
pip list --outdatedno ambiente virtual - usar o CI para validar se a atualizacao nao quebrou nada
- acompanhar changelogs dos pacotes principais
- usar automacao para abrir PRs de atualizacao
Comando manual:
.\.venv\Scripts\python -m pip list --outdated --format=columnsAutomacao adicionada neste projeto:
- arquivo
.github/dependabot.yml - verificacao semanal de dependencias Python
- verificacao semanal de GitHub Actions
- abertura automatica de PRs para atualizacao
Recomendacao pratica:
- manter dependencias de runtime sempre dentro de faixas compativeis e testadas
- atualizar dependencias de teste com mais frequencia
- nao perseguir
latestcegamente; perseguirlatestvalidado pelos testes
Executar a API:
py -3.14 .\src\main.pyExecutar a API com reload:
uvicorn main:app --app-dir src --reloadExecutar testes:
pytest --cov=src --cov-report=term-missingFormatar codigo:
black src tests
isort src testsChecar tipos:
mypy srcInstalar dependencias novamente:
pip install -e .[dev]trivy fs --scanners vuln --format table --dependency-tree .