Skip to main content

State machine framework for BotCity automation bots

Project description

beapro-state-machine

BeaPro (BotCity Enterprise Automation Process) é uma biblioteca Python de automação baseada em máquina de estados para construir bots de processamento de dados com integração nativa à plataforma BotCity Maestro.

Fornece uma arquitetura declarativa com quatro estados padrão e um pipeline de tratamento de erros embutido, deixando ao desenvolvedor apenas a responsabilidade de implementar a lógica de negócio no estado PROCESS.

Instalação

pip install beapro-state-machine

Configuração de Credenciais

Chame beapro.configure() antes de instanciar ExecutionContext. Ela carrega as credenciais do Maestro a partir de um arquivo .env (por padrão) ou de parâmetros explícitos, sem sobrescrever variáveis já definidas no ambiente de processo.

import beapro
beapro.configure()  # lê do .env sem sobrescrever vars já definidas no ambiente

from beapro import BeaproStateMachine, ExecutionContext, ContextProvider

Parâmetros de configure()

Parâmetro Padrão Descrição
server "" URL do servidor Maestro — sobrescreve DEFAULT_SERVER
login "" UUID de login — sobrescreve DEFAULT_LOGIN
key "" Chave de API — sobrescreve DEFAULT_KEY
beapro.configure(
    server="https://developers.botcity.dev",
    login="<uuid>",
    key="<chave>"
)

Fluxo de Estados

INIT → GET_DATA → PROCESS → END
  ↓        ↓          ↓
  └──────→ ErrorHandler (retry → fallback → abort)
Estado Responsabilidade
INIT Valida ambiente e prepara serviços
GET_DATA Fornece o próximo item para processamento
PROCESS Lógica de negócio — ponto de extensão principal
END Reporta contagens ao Maestro e finaliza a task
ErrorHandler Captura exceções, executa retries e envia alertas em fallback

Modos de Operação

BeaproStateMachine suporta dois modos, definidos pelo parâmetro mode:

Modo mode= Fonte dos dados Iteração
datapool (padrão) "datapool" Itens do DataPool do Maestro Loop até esgotar todos os itens
task "task" Parâmetros da task atual Processa uma única vez

No modo task não é necessário definir datapool_label. Os parâmetros configurados na Automação do Maestro ficam disponíveis em context.item.data dentro do ProcessState, com o mesmo contrato do modo datapool.

Passar get_data_state explicitamente tem prioridade sobre mode.

Uso Básico

1. Implemente o estado PROCESS

from beapro.state_templates import ProcessState

class MeuProcessState(ProcessState):
    def execute(self):
        item = self.context.item
        self.services.log(f"Processando: {item.data}")
        # lógica de negócio aqui
        return "SUCCESS"

Valores de retorno aceitos por execute():

Retorno Efeito
"SUCCESS" Item marcado como sucesso no DataPool; avança para o próximo
"BUSINESS_ERROR" Item marcado como erro de negócio; avança para o próximo
qualquer outro / exceção Aciona pipeline de retry → fallback → abort

2. Inicialize e execute — modo datapool

import beapro
beapro.configure()

from beapro import BeaproStateMachine, ExecutionContext, ContextProvider

context = ExecutionContext(datapool_label="meu-datapool")
ContextProvider.initialize(context)

try:
    machine = BeaproStateMachine(process_state=MeuProcessState())
    machine.activate_initial_state()
finally:
    ContextProvider.reset()

3. Inicialize e execute — modo task

Ideal para bots acionados diretamente pelo Maestro com parâmetros configurados na Automação. Não requer DataPool.

import beapro
beapro.configure()

from beapro import BeaproStateMachine, ExecutionContext, ContextProvider

context = ExecutionContext()
ContextProvider.initialize(context)

try:
    machine = BeaproStateMachine(mode="task", process_state=MeuProcessState())
    machine.activate_initial_state()
finally:
    ContextProvider.reset()

ContextProvider.reset() no bloco finally limpa o singleton ao final de cada execução.

Tratamento de Erros

Lance as exceções da lib para acionar comportamentos específicos do pipeline:

from beapro import BusinessException, SystemException, StopProcessException
from beapro.state_templates import ProcessState

class MeuProcessState(ProcessState):
    def execute(self):
        item = self.context.item

        if not item.data.get("cpf"):
            raise BusinessException("CPF ausente — item inválido")

        if not self._conectar_erp():
            raise SystemException("Timeout ao conectar ao ERP")

        return "SUCCESS"
Exceção Efeito
BusinessException Item marcado como erro de negócio; sem retry
SystemException Aciona retry; em abort, reinicia a task automaticamente
StopProcessException Parada controlada sem registrar erro
InterruptRequested Interrupção via Maestro; relançada sem retry

Pipeline completo:

  1. Exceção não tratada → fail()ErrorHandler.retry
  2. Retries esgotados → fallback → log crítico + alerta enviado
  3. abort → executa END para limpeza final

Credenciais de Sistema

CredentialService (acessível via self.services.credential) recupera segredos armazenados no cofre do Maestro — senhas, tokens de API, chaves, etc.

Cache de sessão: cada par (label, key) é buscado uma única vez por execução. Chamadas subsequentes retornam o valor em cache sem nova requisição ao Maestro.

class MeuProcessState(ProcessState):
    def execute(self):
        senha = self.services.credential.get(label="sistema-erp", key="senha")
        usuario = self.services.credential.get(
            label="sistema-erp",
            key="usuario",
            fallback="admin_local",  # retornado se Maestro estiver indisponível
        )
        return "SUCCESS"
Situação Resultado
Maestro disponível valor do cofre (cacheado)
Maestro indisponível + fallback fornecido fallback retornado silenciosamente
Maestro indisponível + sem fallback exceção original relançada
# Invalidar cache (força nova busca no próximo get)
self.services.credential.invalidate(label="cofre", key="chave")
self.services.credential.invalidate_all()

Reporte de Erros ao Maestro

ErrorReporter (acessível via self.services.error_reporter) envia exceções ao painel de erros do Maestro com anti-spam: cada combinação (tipo_de_exceção, estado) é reportada no máximo uma vez por execução. Erros repetidos em loop de DataPool são suprimidos silenciosamente.

class MeuProcessState(ProcessState):
    def execute(self):
        try:
            # lógica de negócio
            return "SUCCESS"
        except Exception as e:
            screenshot = self.services.screenshot.capture()
            self.services.error_reporter.report(
                exception=e,
                state="PROCESS",
                screenshot=screenshot,
            )
            raise
Comportamento Detalhe
task_id ausente ignorado silenciosamente (execução sem Maestro)
StopProcessException nunca reportada (parada controlada, não é erro)
BusinessException marcada como type=BUSINESS no painel
demais exceções marcadas como type=SYSTEM

Logging

O logger escreve simultaneamente em três destinos:

  1. ConsoleINFO e acima
  2. Arquivo localoutput/<timestamp>.log (todos os níveis)
  3. BotCity Maestro — via SDK (falha silenciosa se indisponível)
BEAPRO_LOG_DIR=/caminho/para/logs   # padrão: output/

API Pública

import beapro
beapro.configure()

from beapro import (
    BeaproStateMachine,   # orquestrador principal
    ExecutionContext,     # estado compartilhado da execução
    TransactionItem,      # item de dados atual
    ContextProvider,      # singleton de contexto global
    BusinessException,
    SystemException,
    StopProcessException,
    InterruptRequested,
)

from beapro.state_templates import ProcessState  # base para extensão

Estrutura da Biblioteca

beapro/
├── __init__.py               # API pública + configure()
├── core/
│   ├── state_machine.py      # BeaproStateMachine
│   ├── base_state.py         # BaseState (abstrata)
│   ├── context_provider.py   # ContextProvider (singleton)
│   ├── execution.py          # ExecutionContext + TransactionItem
│   ├── container.py          # ServicesContainer (DI)
│   ├── exceptions.py         # Hierarquia de exceções
│   └── settings.py           # Leitura de variáveis de ambiente
├── services/
│   ├── logger.py             # MaestroLogger
│   ├── datapool.py           # DataPool (lazy init)
│   ├── alert.py              # Alert
│   ├── screenshot.py         # ScreenshotService
│   ├── credential.py         # CredentialService (cofre do Maestro + cache)
│   └── error_reporter.py     # ErrorReporter (anti-spam para painel do Maestro)
└── state_templates/
    ├── init.py               # InitState
    ├── get_data.py           # GetDataState (modo datapool)
    ├── get_task.py           # GetTaskState (modo task)
    ├── process.py            # ProcessState (ponto de extensão)
    └── end.py                # EndState

Dependências

Pacote Versão
botcity-maestro-sdk ==0.9.0
python-statemachine >=3.0.0,<4.0.0
python-dotenv >=1.0.0
mss >=9.0.0

Padrões de Design

Padrão Onde
Singleton ContextProvider
Template Method BaseState.execute()
Dependency Injection ServicesContainer
Iterator DataPool
Strategy Estados concretos substituem comportamento padrão

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

beapro_state_machine-0.1.4.tar.gz (28.8 kB view details)

Uploaded Source

Built Distribution

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

beapro_state_machine-0.1.4-py3-none-any.whl (30.1 kB view details)

Uploaded Python 3

File details

Details for the file beapro_state_machine-0.1.4.tar.gz.

File metadata

  • Download URL: beapro_state_machine-0.1.4.tar.gz
  • Upload date:
  • Size: 28.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.0

File hashes

Hashes for beapro_state_machine-0.1.4.tar.gz
Algorithm Hash digest
SHA256 b0e8fc33eb1047bdf53bf0843a7bb8c2328d6ae7da43df655567aa0107117f9a
MD5 bf958427dc588d01d973b9d2dd1a3131
BLAKE2b-256 e017519203faec6e97ba943db7a4280393d4185977ece8ccf1509f6e0cfe4741

See more details on using hashes here.

File details

Details for the file beapro_state_machine-0.1.4-py3-none-any.whl.

File metadata

File hashes

Hashes for beapro_state_machine-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 d70016f18d92b84b5a0dcb6e109b504e82cce4496c2a19cfa0420eebff7daa1a
MD5 df012f2e040d049d386e4d7aff9fc844
BLAKE2b-256 9d1cc173fbf7040d61a0b34c715655486484d32807e18ff09c1299edea53bdb9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page