🛰️ Async MicroService Framework com ZeroMQ
Este projeto é um framework leve e assíncrono para criar microsserviços em Python, utilizando zmq.asyncio como mecanismo de comunicação entre processos ou entre máquinas.
🚀 Recursos
- 📡 Comunicação assíncrona entre microsserviços com ZeroMQ (PUSH/PULL + PUB/SUB)
- 🧠 Suporte a ações (
@action) e tarefas (@task) com execução assíncrona - 📢 Suporte a mensagens broadcast, requisições diretas e respostas
- 🔌 Sistema de descoberta de serviços, incluindo detecção de desconexão via heartbeat
- ⚙️ Customização com hooks para eventos (
on_connect,on_new_service,on_service_disconnect, etc.) - 🔐 Criptografia e autenticação opcionais via ZMQ CURVE (Curve25519/libsodium)
📦 Requisitos
- Python 3.8+
pyzmqasyncio
poetry install
Exemplo de Uso
class MyService:
@MicroService.action
async def hello(self, origin, data):
print(f"Recebido de {origin}: {data}")
@MicroService.task
async def heartbeat(self):
while True:
await asyncio.sleep(5)
print("Estou vivo")
if __name__ == '__main__':
service = MicroService(
service=MyService(),
sender_endpoint='ipc:///tmp/sender', # tcp://0.0.0.0:3000
receiver_endpoint='ipc:///tmp/receiver' # tcp://0.0.0.0:4000
)
asyncio.run(service.run())
📡 Fluxo de Mensagens
-
Registro: ao iniciar, um serviço envia uma mensagem com suas ações disponíveis.
-
Broadcast: mensagens são enviadas para todos os serviços.
-
Ação direta: mensagens com prefixo action: disparam métodos marcados como @action.
-
Resposta direta: mensagens com prefixo service_name: retornam dados diretamente ao solicitante.
-
Heartbeat: mensagens são enviadas periodicamente por cada serviço; se um serviço para de enviar sinais por
heartbeat_timeoutsegundos, o hookon_service_disconnect(service)é disparado nos demais serviços que o conheciam.
💓 Heartbeat e detecção de desconexão
Por padrão, todo MicroService envia um heartbeat periódico e monitora os heartbeats dos demais
serviços conhecidos. Isso permite detectar quando um serviço cai sem avisar (crash, queda de
rede, etc.), não só quando ele se conecta.
service = MicroService(
service=MyService(),
sender_endpoint='tcp://0.0.0.0:3000',
receiver_endpoint='tcp://0.0.0.0:4000',
enable_heartbeat=True, # padrão: True
heartbeat_interval=5, # segundos entre heartbeats (padrão: 5)
heartbeat_timeout=15, # segundos sem sinal até considerar desconectado (padrão: 3x o intervalo)
)
class MyService:
async def on_service_disconnect(self, service: str):
print(f'{service} parou de responder')
🧩 Arquitetura
┌──────────────┐ PUSH ┌──────────────┐
│ MicroService │ ─────────────────▶ │ Receiver │
└──────────────┘ └──────────────┘
▲
│
SUB │
▼
┌──────────────┐
│ Sender │
└──────────────┘
🔐 Criptografia
O aiofase suporta criptografia e autenticação de ponta a ponta via ZMQ CURVE
(Curve25519/libsodium, nativo do pyzmq). É opcional e desligada por padrão.
1. Gerar as chaves
Cada serviço (e o broker) precisa de um par de chaves CURVE. Gere com o CLI do módulo
aiofase.security:
python -m aiofase.security --name broker --out ./keys
python -m aiofase.security --name meu_servico --out ./keys
Isso cria broker.key (pública, pode compartilhar) e broker.key_secret.
2. Habilitar no broker
server = Server(
sender_endpoint='tcp://0.0.0.0:3000',
receiver_endpoint='tcp://0.0.0.0:4000',
curve_secretkey_file='./keys/broker.key_secret',
authorized_clients_dir='./keys/authorized_clients', # opcional, veja abaixo
)
Ou via CLI: python -m aiofase.server --curve-secretkey-file ./keys/broker.key_secret.
- Com
authorized_clients_dir: só clientes cuja chave pública (.key) esteja nesse diretório conseguem conectar — criptografia e autenticação. - Sem
authorized_clients_dir: qualquer par de chaves CURVE válido é aceito — só criptografia, sem controle de quem conecta (CURVE_ALLOW_ANY).
3. Habilitar no MicroService
service = MicroService(
service=MyService(),
sender_endpoint='tcp://0.0.0.0:3000',
receiver_endpoint='tcp://0.0.0.0:4000',
curve_secretkey_file='./keys/meu_servico.key_secret',
server_publickey_file='./keys/broker.key',
)
Os dois parâmetros (curve_secretkey_file e server_publickey_file) são obrigatórios em conjunto.
🧪 Testes
A suíte usa pytest + pytest-asyncio, com testes de integração reais (sobem Server e MicroService de verdade sobre sockets ipc:// temporários.
poetry install
pytest tests/ --cov=aiofase --cov-report=term-missing
O --cov-report=term-missing mostra, por arquivo, quais linhas ainda não têm teste. Para um
relatório HTML navegável:
pytest tests/ --cov=aiofase --cov-report=html
# abre htmlcov/index.html
🔄 Integração com outros sistemas
-
Pode ser facilmente integrado com sensores IoT, bancos de dados, interfaces HTTP ou MQTT.
-
Ideal para arquiteturas orientadas a eventos com múltiplos serviços independentes.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file aiofase-0.5.0.tar.gz.
File metadata
- Download URL: aiofase-0.5.0.tar.gz
- Upload date:
- Size: 6.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
poetry/2.3.1 CPython/3.12.3 Linux/7.0.0-28-generic
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c22f42a6a6ac077bd88e009bdd38e7199e7f1d654dbfc60abb468f2c32e3dbfa
|
|
| MD5 |
a05cd588be0c3323ab6b8bd0a7f62181
|
|
| BLAKE2b-256 |
c3adf137087fbede27848b172a8a79b614b2deee402d6d2d0f76c2e48f396577
|
File details
Details for the file aiofase-0.5.0-py3-none-any.whl.
File metadata
- Download URL: aiofase-0.5.0-py3-none-any.whl
- Upload date:
- Size: 8.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
poetry/2.3.1 CPython/3.12.3 Linux/7.0.0-28-generic
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0e77c26937a6b9e1d605574c59c8f31b95449765e2e1b0725f353563d4480c5e
|
|
| MD5 |
e4c7bc692470b27dc53a72417493133b
|
|
| BLAKE2b-256 |
bc2f96de53cde20308912478bd55d820e07c33f17bdc5d0db1edfbf35820e8de
|