Esta é uma API REST desenvolvida em Python com FastAPI para o gerenciamento de usuários.
O projeto foi estruturado utilizando princípios da Arquitetura Hexagonal (Ports and Adapters) para garantir um código limpo, desacoplado e de fácil manutenção.
- Autenticação: Sistema de login seguro com tokens JWT
- CRUD de Usuários: Criação, Leitura, Atualização e Deleção
- Paginação: Listagem paginada para performance eficiente
- Proteção de Rotas: Autenticação obrigatória em operações críticas
- Documentação Automática: Swagger UI e ReDoc gerados automaticamente
- Framework: FastAPI
- Banco de Dados: SQLite
- Arquitetura: Hexagonal (Ports and Adapters)
- Autenticação: JWT (JSON Web Tokens)
- Testes: Unitários na camada de serviço
- Versionamento: Código organizado para publicação no GitHub
- Python 3.8 ou superior
- Git
git clone https://github.com/cssbreno/fastapi-user-manager.git
cd fastapi-user-manager# Criação
python3 -m venv venv
# Ativação
# Windows:
venv\Scripts\activate
# macOS/Linux:
source venv/bin/activateApós ativar, você verá
(venv)no início da linha do terminal.
IMPORTANTE: Este projeto requer configuração de variáveis de ambiente para funcionar corretamente.
# Copie o arquivo de exemplo
cp .env.example .env
# Gere uma chave secreta única
# Python (recomendado, pois já é um pré-requisito)
python -c "import secrets; print(secrets.token_hex(32))"
# Ou use o comando abaixo para gerar uma chave secreta única
# Windows:
powershell -Command "openssl rand -hex 32"
# Linux/Mac:
openssl rand -hex 32
# Copie a chave secreta gerada para o arquivo .env
echo "SECRET_KEY=sua_chave_secreta_aqui" >> .env
# Edite o arquivo .env com suas configurações (opcional)
nano .env # ou use seu editor preferidoConfigurações no .env:
SECRET_KEY: Chave secreta para JWT (obrigatória para produção)ACCESS_TOKEN_EXPIRE_MINUTES: Tempo de expiração do token (padrão: 30 min)DATABASE_URL: URL do banco de dados (padrão: SQLite local)ALGORITHM: Algoritmo de criptografia JWT (padrão: HS256)
Exemplo de .env preenchido:
SECRET_KEY=sua_chave_secreta_gerada_aqui_com_64_caracteres
ACCESS_TOKEN_EXPIRE_MINUTES=30
DATABASE_URL=sqlite:///./database.db
ALGORITHM=HS256Nota: O projeto funcionará com os valores padrão, mas é altamente recomendado configurar uma SECRET_KEY única em produção.
pip install -r requirements.txtNa raiz do projeto:
uvicorn src.main:app --reloadsrc.main:app: aponta para o objetoappemsrc/main.py--reload: reinicia o servidor automaticamente a cada alteração
O servidor estará disponível em: http://127.0.0.1:8000
- Swagger UI → http://127.0.0.1:8000/docs
- ReDoc → http://127.0.0.1:8000/redoc
Baixe o arquivo postman_requests.json pronto para importação no Postman ou siga os passos abaixo:
- Crie um usuário →
POST /users/(comusername,emailepassword) - Crie um token de acesso →
POST /token(comemailepassword) - Autentique-se → Clique em Authorize no Swagger e insira:
email: seu email (não username)password: sua senha- Deixe
client_ideclient_secretem branco
- Acesse rotas protegidas → Endpoints como
GET /users/meouPUT /users/{user_id}estarão liberados com o token gerado.
Nota: O sistema usa email (não username) para autenticação, conforme implementado na API.
1. Criar usuário:
curl -X POST "http://127.0.0.1:8000/users/" \
-H "Content-Type: application/json" \
-d '{
"username": "usuario_teste",
"email": "teste@exemplo.com",
"password": "senha123"
}'2. Obter token de acesso:
curl -X POST "http://127.0.0.1:8000/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "username=teste@exemplo.com&password=senha123"Nota: O endpoint /token espera email e password como form data, não JSON.
3. Acessar rota protegida:
curl -X GET "http://127.0.0.1:8000/users/me" \
-H "Authorization: Bearer SEU_TOKEN_AQUI"4. Listar usuários:
curl -X GET "http://127.0.0.1:8000/users/" \
-H "Authorization: Bearer SEU_TOKEN_AQUI"5. Atualizar usuário:
curl -X PUT "http://127.0.0.1:8000/users/1" \
-H "Authorization: Bearer SEU_TOKEN_AQUI" \
-H "Content-Type: application/json" \
-d '{
"username": "usuario_teste_atualizado",
"email": "teste@exemplo.com",
"password": "senha123"
}'6. Deletar usuário:
curl -X DELETE "http://127.0.0.1:8000/users/1" \
-H "Authorization: Bearer SEU_TOKEN_AQUI"Na raiz do projeto:
# Executar todos os testes
pytest
# Executar com mais detalhes
pytest -v
# Executar com cobertura de código
pytest --cov=src --cov-report=html
# Após executar, abra o relatório HTML:
# Abra o arquivo htmlcov/index.html no seu navegador
# Executar testes específicos
pytest tests/test_user_service.py -vCobertura Atual dos Testes:
- ✅ UserService: Testes unitários completos com mocks
- ✅ SQLiteUserRepository: Testes de persistência com mocks
- ✅ Autenticação: Sistema JWT e hash de senhas testado
- ✅ Configuração: Validação de variáveis de ambiente
- ✅ Validação: Schemas e validações testados
- ✅ Rotas da API: Endpoints testados com TestClient
Estrutura de Testes:
tests/test_user_service.py: Testes unitários da camada de serviçotests/test_sqlite_repository.py: Testes do repositório de dadostests/test_auth.py: Testes de autenticação e JWTtests/test_config.py: Testes de configuraçãotests/test_api_endpoints.py: Testes de integração dos endpoints da API
Tipos de Testes Implementados:
- Testes Unitários:
tests/test_user_service.py- Testa a lógica de negócio isoladamente - Testes de Repositório:
tests/test_sqlite_repository.py- Testa a camada de persistência - Testes de Autenticação:
tests/test_auth.py- Testa JWT, hash de senhas e validação de tokens - Testes de Configuração:
tests/test_config.py- Testa carregamento de variáveis de ambiente - Testes de API:
tests/test_api_endpoints.py- Testa os endpoints com TestClient - Mocks: Uso de
unittest.mockpara isolamento de dependências - Fixtures: Reutilização de dados de teste entre diferentes testes
fastapi-user-manager/
├── src/
│ ├── core/ # Lógica de negócio (domínio)
│ │ ├── models.py # Modelos de domínio (Pydantic)
│ │ ├── ports/ # Interfaces (contratos)
│ │ │ └── user_repository.py
│ │ └── services/ # Serviços de negócio
│ │ └── user_service.py
│ ├── infrastructure/ # Implementações concretas
│ │ ├── database/ # Camada de persistência
│ │ │ ├── models.py # Modelos SQLAlchemy
│ │ │ ├── database.py # Configuração do banco
│ │ │ └── sqlite_user_repository.py
│ │ └── web/ # Camada de apresentação
│ │ ├── api.py # Controllers/rotas
│ │ ├── auth.py # Autenticação JWT
│ │ ├── schemas.py # Validação de entrada/saída
│ │ └── dependencies.py # Injeção de dependências
│ ├── config.py # Configurações e variáveis de ambiente
│ └── main.py # Ponto de entrada da aplicação
├── tests/ # Testes automatizados
│ ├── test_user_service.py # Testes unitários
│ └── test_api_endpoints.py # Testes de integração
├── requirements.txt # Dependências Python
├── pytest.ini # Configuração do pytest
└── .env.example # Exemplo de variáveis de ambiente
Core (Domínio):
models.py: Entidades de negócio (User) usando Pydanticports/: Interfaces que definem contratos (UserRepository)services/: Lógica de negócio (UserService)
Infrastructure (Implementação):
database/: Persistência de dados com SQLAlchemyweb/: API REST com FastAPI, autenticação e validação
Schemas vs Models:
core/models.py: Modelos de domínio para lógica de negócioinfrastructure/web/schemas.py: Schemas para validação de entrada/saída da APIinfrastructure/database/models.py: Modelos SQLAlchemy para persistência
Para adicionar novos testes:
- Testes Unitários: Crie arquivos em
tests/test_*.py - Use Mocks: Para isolar dependências externas
- Fixtures: Para reutilizar dados de teste
- Cobertura: Execute
pytest --cov=src --cov-report=html
- Arquitetura Hexagonal: Separação clara entre domínio e infraestrutura
- Dependency Injection: Uso de
Depends()para injeção de dependências - Validação: Schemas Pydantic para entrada/saída da API
- Tratamento de Erros: HTTP status codes apropriados
- Separação de Modelos:
- Modelos de domínio (core) para lógica de negócio
- Schemas (web) para validação de API
- Modelos de persistência (database) para SQLAlchemy
1. Erro "Module not found":
# Certifique-se de estar no diretório raiz do projeto
cd fastapi-user-manager
# Ative o ambiente virtual
source venv/bin/activate # Linux/Mac
# ou
venv\Scripts\activate # Windows2. Erro de banco de dados:
# Verifique se o arquivo .env está configurado
cat .env
# Certifique-se de que o DATABASE_URL está correto3. Erro de autenticação:
- Verifique se
SECRET_KEYestá configurada no .env - Certifique-se de que o token não expirou
- Use o endpoint
/tokenpara obter um novo token - IMPORTANTE: Use email (não username) para autenticação
4. Porta já em uso:
# Use uma porta diferente
uvicorn src.main:app --reload --port 8001