Este é um sistema distribuído de análise de sentimentos construído com uma arquitetura de microsserviços. O projeto utiliza Python e FastAPI para a camada de aplicação, Redis como intermediário de mensagens assíncronas e PostgreSQL para armazenamento persistente. O foco principal é demonstrar o uso de containers Docker para criar um ambiente de desenvolvimento isolado, escalável e resiliente.
sentiment-analyzer/
├── api/
│ ├── main.py
│ ├── requirements.txt
│ └── Dockerfile # Build da imagem da api
├── worker/
│ ├── worker.py
│ ├── requirements.txt
│ └── Dockerfile # Build da imagem do worker
├── db/
│ └── init.sh # Script de inicialização do Banco de Dados
├── docker-compose.yml # Orquestração dos serviços: redis, db, worker, api
├── config.py # Configuração para leitura das variáveis de ambiente
└── .env.example # Template de variáveis de ambiente
redis: Imagem oficial do Redis para atuar como broker de mensagens.
db: Imagem oficial PostgreSQL para persistência dos resultados.
api: App FastAPI com Dockerfile próprio que recebe um texto e o envia para uma fila (Redis).
worker: Script com Dockerfile próprio que consome as mensagens do Redis, processa o texto usando a biblioteca TextBlob e salva o resultado no banco de dados.
O fluxo de uma informação dentro do sistema segue o seguinte caminho:
-
Ingestão: A API recebe uma frase via requisição HTTP POST.
-
Mensageria: A frase é encapsulada em um JSON e enviada para uma fila no Redis. A API responde imediatamente ao usuário, garantindo baixa latência.
-
Processamento: O Worker (que pode ter múltiplas instâncias) monitora a fila constantemente. Ao detectar uma nova mensagem, ele a retira da fila e utiliza a biblioteca TextBlob para calcular a polaridade do texto.
-
Persistência: O resultado da análise (texto, score e classificação) é gravado de forma estruturada no PostgreSQL.
-
Ciclo de Vida: Graças aos volumes do Docker, os dados permanecem salvos mesmo que todos os containers sejam removidos.
- Docker
- Docker Compose
cp .env.example .env
Lembre de atualizar o arquivo .env com valores coesos.
docker compose up --build
O Docker vai baixar as imagens (Python, Redis, Postgres), rodar os Dockerfiles, criar o volume postgres_data e executar o init.sql.
-
Abra o navegador em
http://localhost:8000/docs. -
Clique no método POST /analyze, depois em Try it out.
-
No corpo do JSON, digite algo como:
{"content": "I love learning Docker and Python!"} -
Clique em Execute.
-
Vá para o terminal e confira os logs do worker:
docker compose logs -f worker
-
Abra o seu terminal (fora do container)
-
Envie uma requisição do tipo POST para o endpoint /analyze, passando o conteúdo no formato JSON:
curl -X POST http://localhost:8000/analyze \ -H "Content-Type: application/json" \ -d '{"content": "I love learning Docker and Python!"}' -
Confira os logs do worker:
docker compose logs -f worker
-
Valide se os dados foram realmente salvos no volume do Postgres:
docker exec -it sentiment_db psql -U [seu_usuario] -d [seu_banco_de_dados] -c "SELECT * FROM sentiments; -
Derrube a aplicação:
docker compose down -
Suba a aplicação novamente:
docker compose up -d -
Valide se os dados persistem no banco de dados:
docker exec -it sentiment_db psql -U [seu_usuario] -d [seu_banco_de_dados] -c "SELECT * FROM sentiments;
-
Suba múltiplas instâncias do Worker:
docker compose up -d --scale worker=3 -
Use um loop para enviar [10] requisições e ver os workers trabalhando juntos:
for i in {1..10}; do curl -X POST http://localhost:8000/analyze \ -H "Content-Type: application/json" \ -d "{\"content\": \"Teste de carga número $i\"}"; done -
Abra os logs do worker para ver a divisão de tarefas:
docker compose logs -f worker
-
Acesse
http://localhost:8000/no navegador. -
Com o container rodando, abra o arquivo
api/main.pye altere a mensagem do endpoint raiz (/). -
Salve o arquivo e confira novamente
http://localhost:8000/.
| Comando | Descrição |
|---|---|
docker ps -a |
Lista todos os containers (ativos e inativos) |
docker docker logs -f <id/nome> |
Exibe e acompanha os logs de um container |
docker stop <id/nome> |
Para a execução de um container |
docker start <id/nome> |
Inicia um container parado |
docker rm <id/nome> |
Remove um container parado |
docker images |
Lista todas as imagens locais |
docker pull |
Baixa uma imagem do Docker Hub |
docker build -t <nome>:<tag> . |
Cria uma imagem a partir de um Dockerfile |
docker run <imagem> |
Cria e inicia um container a partir de uma imagem |
docker rmi <id/nome> |
Remove uma imagem |
docker compose up -d |
Sobe os serviços em segundo plano (detached mode) |
docker compose up --build |
Força a reconstrução das imagens antes de subir |
docker compose up -d |
Sobe os serviços em segundo plano (detached mode) |
docker compose down |
Remove containers e redes criados pelo compose |
docker compose down -v |
Remove containers e também os volumes nomeados |
docker system prune -a --volumes |
Remove tudo o que não está sendo usado |