19 — Integração¶
Esta página responde ao que um sistema hospedeiro precisa saber antes de embutir a biblioteca: de que ela cuida, do que ela não cuida, e onde ficam as responsabilidades que sobram.
O que a biblioteca não faz¶
Nada disso é omissão — é fronteira deliberada, e cada item vira responsabilidade sua:
- Não fala rede. Não há cliente HTTP, nem chamada a API de banco. Ela transforma dados em arquivos e documentos, e só.
- Não escreve em disco.
gera_arquivo()devolvestr;render_boleto_pdf()devolvebytes. Onde isso é gravado, e com qual nome, é decisão do hospedeiro. - Não persiste estado. Não há banco de dados, cache nem arquivo de controle. Nada é lembrado entre uma chamada e outra.
- Não numera. Nosso número e sequencial de remessa vêm de você — ver Numeração.
- Não agenda nem repete. Não há fila, retentativa ou idempotência embutidas.
Estado e concorrência¶
O pacote não mantém estado global mutável. Todo objeto (Boleto, Pagamento, Remessa*,
Retorno) carrega os próprios dados, e o registro de bancos é populado uma vez, na importação,
e depois só é lido.
Na prática:
- Criar e usar instâncias em paralelo é seguro; não é preciso lock nem processo dedicado.
- Não há vazamento entre requisições ou entre empresas — o que separa um contexto do outro são os objetos que você passa, não configuração global.
- Não reaproveite a mesma instância de
Remessa*em duas gerações concorrentes: ela é um agregado de dados, não um serviço. Instancie por operação; custa pouco.
Multiempresa não exige nada especial: são objetos diferentes, com dados diferentes.
Numeração¶
Dois números são seus, e o banco rejeita arquivo quando eles saem errados.
Nosso número é campo obrigatório de Pagamento e do boleto, sem valor padrão útil. A
biblioteca calcula o dígito verificador e a formatação de cada banco, mas não gera a
sequência — ela não sabe qual foi o último título emitido. Persistir e avançar esse contador,
sem repetir e sem furo, é do sistema hospedeiro.
Sequencial de remessa identifica o arquivo dentro da conta. É o campo sequencial_remessa,
com valor padrão "1":
Dois cuidados:
- O padrão
"1"é conveniência para teste. Em produção, mandar todo arquivo com"1"costuma fazer o banco recusar o segundo do dia por sequência duplicada. - Nem todo layout usa esse campo. Ele aparece no header de Banco do Brasil, Bradesco, C6, CrediSIS, Sicoob e Unicred no CNAB 400, e na base do CNAB 240 (incluindo Santander). No Itaú 400, por exemplo, o header não tem essa posição, e mudar o valor não altera o arquivo. Confira a página do banco antes de assumir que o campo tem efeito.
O sequencial de registro dentro do arquivo (linha 1, 2, 3… e o total no trailer) é calculado pela biblioteca. Esse você não precisa controlar.
Formato da saída¶
O arquivo CNAB sai pronto para o banco, com três transformações já aplicadas:
- Acentos normalizados.
JOSÉ AÇÚCAR & CIAviraJOSE ACUCAR CIA;Rua São JoãoviraRUA SAO JOAO. A saída é ASCII puro — não há byte acima de 127 para o banco recusar. - Caixa alta nos campos de texto.
- Terminação CRLF (
\r\n), inclusive na última linha, como o padrão FEBRABAN espera.
Como gera_arquivo() devolve str já com \r\n, grave em modo binário ou desligue a tradução
de fim de linha — caso contrário o Windows duplica o \r:
conteudo = remessa.gera_arquivo()
# Correto: não deixa o Python mexer nas quebras de linha.
with open("CB250807.REM", "w", encoding="ascii", newline="") as arquivo:
arquivo.write(conteudo)
# Equivalente, em bytes:
with open("CB250807.REM", "wb") as arquivo:
arquivo.write(conteudo.encode("ascii"))
O nome do arquivo é convenção de cada banco e não é gerado pela biblioteca.
Valores monetários¶
Campos de valor aceitam Decimal, float e str, e são formatados com duas casas para o
arquivo. Use Decimal: é a convenção do projeto e evita que o erro de arredondamento do
float apareça em algum ponto do seu próprio cálculo, antes mesmo de chegar aqui.
Contrato de erros¶
Todas as exceções herdam de PyCobrancaError, então um except cobre a biblioteca inteira:
| Exceção | Quando |
|---|---|
BancoNaoRegistrado |
código FEBRABAN desconhecido em Bancos.find() |
BoletoInvalido |
campo fora das regras do banco |
RetornoInvalido |
arquivo de retorno vazio ou sem header reconhecível |
OFXInvalido |
arquivo que não é OFX |
BoletoInvalido carrega .erros, uma lista com um item por problema — dá para devolver
todas as violações de uma vez, em vez de o usuário descobrir uma por tentativa:
from pycobranca.bancos import Bancos
from pycobranca.exceptions import BoletoInvalido
try:
boleto.validar()
except BoletoInvalido as erro:
for problema in erro.erros:
print(problema)
# carteira '999' não suportada (use uma de: 104, 109, 112, 115, 175, 177, 188)
Chame validar() explicitamente antes de renderizar ou gerar remessa: é onde as regras por banco
são conferidas. Pagamento.validar() faz o mesmo para encargos.
A geração da remessa tem ainda uma conferência final de tamanho do registro, que impede o arquivo malformado de sair:
A mensagem informa o registro, não o campo. Ao receber esse erro, confira antes de mais nada
a largura dos campos de identificação da conta — agência, conta corrente, dígito e convênio —
contra a especificação do banco na página correspondente em docs/bancos/.
Um campo com tamanho diferente do previsto desloca todas as posições seguintes.
Lotes¶
gera_arquivo() monta o arquivo inteiro em memória e devolve de uma vez. Medido nesta máquina,
com o layout do Itaú 400:
| Títulos | Tempo | Arquivo |
|---|---|---|
| 1.000 | ~44 ms | 0,4 MB |
| 10.000 | ~465 ms | 3,8 MB |
O crescimento é linear e o custo é baixo, mas é tudo memória residente. Para remessas muito grandes, o limite prático não é a CPU — é o pico de memória do processo somado ao que o hospedeiro fizer com a string depois (cópia para resposta HTTP, anexo, etc.).
Homologação com o banco¶
Este é o item que mais distorce cronograma, e não depende da biblioteca.
Antes de liberar produção, o banco exige homologar o arquivo de remessa: você envia um arquivo de exemplo, a área técnica confere posição a posição, aponta divergências e repete o ciclo. Leva de semanas a meses, varia por banco e por agência, e costuma incluir exigências que não estão no manual público — máscara de nosso número, faixa de carteira liberada para o convênio, código de cedente com formato próprio.
O que a PyCobrança oferece para encurtar isso: a remessa é validada byte a byte contra arquivos de referência (ver 17 — Compatibilidade), então a divergência tende a estar no cadastro do convênio, não na montagem do registro. Vale começar a homologação cedo, em paralelo ao desenvolvimento, e não depois.
Checklist¶
- [ ] Nosso número persistido e avançado pelo hospedeiro, sem repetição.
- [ ]
sequencial_remessacontrolado, e conferido se o layout do banco usa o campo. - [ ] Gravação em
newline=""ou em bytes, para não duplicar o\r. - [ ] Valores em
Decimal. - [ ]
validar()chamado, e.errospropagado para a interface. - [ ]
PyCobrancaErrortratado na fronteira do módulo. - [ ] Homologação bancária iniciada em paralelo ao desenvolvimento.