Odoo e eSocial S-1.3: Automatizando a transmissão de eventos com Python
Como a biblioteca esociallib simplifica geração, validação XSD, assinatura digital ICP-Brasil e transmissão de eventos eSocial no Odoo com Python.
Gustavo Ferraz
O eSocial permanece como um dos principais desafios de integração para empresas de software no Brasil, especialmente aquelas utilizando ERP Odoo. A complexidade dos leiautes XML, a quantidade de eventos (mais de 40 tipos) e as particularidades da assinatura digital ICP-Brasil tornam o desenvolvimento custoso e propenso a erros.
A esociallib é uma biblioteca Python focada em geração, validação XSD, assinatura digital e transmissão de eventos eSocial no leiaute S-1.3, publicada no PyPI e mantida pela KMEE como parte do ecossistema erpbrasil.
pip install esociallib
O Problema
O ciclo de vida de um evento eSocial envolve várias etapas críticas:
- Montar o XML respeitando o XSD oficial (namespace, ordem dos elementos, tipos)
- Validar localmente antes de enviar (economiza tempo e evita rejeições)
- Assinar digitalmente com certificado ICP-Brasil A1/A3
- Montar o envelope SOAP com namespaces específicos
- Transmitir via mTLS para os webservices da Receita Federal
- Consultar o resultado assincronamente (polling obrigatório desde julho/2024)
Cada etapa apresenta suas próprias complexidades. O tipos.xsd do eSocial é um chameleon schema (sem targetNamespace), confundindo geradores de bindings. A assinatura exige RSA-SHA1, não SHA256. Os envelopes SOAP possuem namespaces diferentes para envio e consulta.
A Solução
A esociallib resolve cada etapa com uma API simplificada:
from esociallib import to_xml, assinar, enviar_lote, consultar_lote
# 1. Dict → XML validado contra XSD
xml = to_xml("S-2200", {
"tp_insc": 1,
"nr_insc": "12345678000199",
"cpf_trab": "12345678901",
"nm_trab": "MARIA DA SILVA",
"dt_nasc": "1990-05-15",
"dt_adm": "2024-03-01",
"matricula": "000123",
"cod_categ": 101,
"nm_cargo": "ANALISTA DE SISTEMAS",
"cod_cbo": "212405",
"vr_sal_fx": "8500.00",
"und_sal_fixo": 5,
})
# 2. Assinar com certificado A1
pfx = open("certificado.pfx", "rb").read()
xml_assinado = assinar(xml, cert_pfx=pfx, cert_password="senha")
# 3. Enviar lote
protocolo = enviar_lote(
[xml_assinado],
cert_pfx=pfx,
cert_password="senha",
environment="restricted", # ou "production"
)
# 4. Consultar resultado
resultado = consultar_lote(protocolo, cert_pfx=pfx, cert_password="senha")
for evento in resultado.eventos:
print(f"{'Aceito' if evento.aceito else 'Rejeitado'}: {evento.description}")
Decisões Técnicas
Builders com lxml.etree
O tipos.xsd do eSocial não declara targetNamespace, causando atribuição incorreta de namespace pelos geradores como xsdata durante serialização. A solução utiliza xsdata apenas para deserialização (parsear respostas do governo) e constrói o XML de saída diretamente com lxml.etree:
# esociallib/builders/s_2200.py
@register_builder("S-2200")
def build_s2200(data: dict, environment: str = "restricted") -> EventoXml:
ns = "http://www.esocial.gov.br/schema/evt/evtAdmissao/v_S_01_03_00"
root, evt = make_esocial(ns)
# constrói a árvore XML a partir do dict
return EventoXml(root, ns)
Validação XSD local
Todo XML gerado é validado contra o XSD oficial antes da assinatura, economizando round-trip até o portal do governo:
from esociallib.validators import validate_xsd
erros = validate_xsd(xml_string, "S-2200")
if erros:
print("Erros de validação:", erros)
Os schemas são compilados uma vez e cacheados em memória.
Delegação para o ecossistema erpbrasil
A esociallib não reinventa funcionalidades existentes. Assinatura e transmissão são delegadas para bibliotecas especializadas:
- erpbrasil.assinatura — ICP-Brasil A1/A3, RSA-SHA1, XML-DSig
- erpbrasil.transmissao — SOAP 1.1 com mTLS
A mesma infraestrutura usada para NF-e, CT-e e MDF-e funciona para o eSocial.
Testando sem Certificado Real
A lib inclui suporte a certificados fake para testes:
from erpbrasil.assinatura.misc import create_fake_certificate_file
from esociallib import to_xml, assinar
cert_pfx = create_fake_certificate_file(
valid=True, passwd="teste123",
issuer="TEST CA", country="BR",
subject="EMPRESA TESTE:12345678000199",
)
xml = to_xml("S-1000", dados_empregador)
xml_assinado = assinar(
xml, cert_pfx=cert_pfx,
cert_password="teste123",
raise_expirado=False
)
Recursos
- PyPI: pypi.org/project/esociallib
- GitHub: github.com/erpbrasil/esociallib
- Licença: MIT — contribuições são bem-vindas
Conclusão
A esociallib elimina a complexidade do eSocial para equipes de desenvolvimento Odoo no Brasil. Com uma API simples e bem documentada, é possível implementar a transmissão completa de eventos — da geração do XML à consulta do protocolo — com poucas linhas de código e sem reinventar a roda.
Faz parte da filosofia da KMEE construir infraestrutura open source de qualidade que beneficie todo o ecossistema Odoo no Brasil.
Sobre o autor
Gustavo Ferraz
Especialista Odoo · KMEE
Especialista Odoo com experiência em integrações fiscais, eSocial e automação de processos para empresas brasileiras.
Ver perfil no LinkedIn