Skip to main content

🛰️ 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+
  • pyzmq
  • asyncio
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_timeout segundos, o hook on_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

aiofase-0.5.0.tar.gz (6.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

aiofase-0.5.0-py3-none-any.whl (8.3 kB view details)

Uploaded Python 3

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

Hashes for aiofase-0.5.0.tar.gz
Algorithm Hash digest
SHA256 c22f42a6a6ac077bd88e009bdd38e7199e7f1d654dbfc60abb468f2c32e3dbfa
MD5 a05cd588be0c3323ab6b8bd0a7f62181
BLAKE2b-256 c3adf137087fbede27848b172a8a79b614b2deee402d6d2d0f76c2e48f396577

See more details on using hashes here.

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

Hashes for aiofase-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0e77c26937a6b9e1d605574c59c8f31b95449765e2e1b0725f353563d4480c5e
MD5 e4c7bc692470b27dc53a72417493133b
BLAKE2b-256 bc2f96de53cde20308912478bd55d820e07c33f17bdc5d0db1edfbf35820e8de

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.5.0 This release

2 files

0.4.1

2 files

0.4.0

2 files

0.3.0

2 files

0.2.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page