O eSocial continua sendo um dos maiores desafios de integração para empresas de software no Brasil, especialmente para aquelas que utilizam sistemas ERP como o 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 e a manutenção de módulos de localização para o Odoo custosos e propensos a erros.
Apresentamos 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. Ela é a ferramenta ideal para desenvolvedores Odoo que buscam uma integração robusta e eficiente.
pip install esocialib
O Problema
Quem já integrou com o eSocial sabe que o ciclo de vida de um evento envolve várias etapas:
- 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 jul/2024)
Cada etapa tem suas armadilhas. O tipos.xsd do eSocial é um chameleon schema (sem targetNamespace), o que confunde a maioria dos geradores de bindings. A assinatura exige RSA-SHA1, não SHA256. E os envelopes SOAP têm namespaces diferentes para envio e consulta.
A Solução
A esociallib resolve cada etapa com uma API simples:
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,
"nat_atividade": 1,
"tp_reg_trab": 1,
"tp_reg_prev": 1,
"nm_cargo": "ANALISTA DE SISTEMAS",
"cod_cbo": "212405",
"vr_sal_fx": "8500.00",
"und_sal_fixo": 5,
"tp_contr": 1,
})
# 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 (não xsdata para serialização)
O tipos.xsd do eSocial é um chameleon schema — ele não declara targetNamespace. Isso faz com que geradores como xsdata atribuam namespace incorreto aos tipos compartilhados durante a serialização. A solução: usamos xsdata apenas para deserialização (parsear respostas do governo) e construímos o XML de saída diretamente com lxml.etree, que respeita os namespaces perfeitamente.Cada builder é um módulo Python que transforma um dicionário em XML:
# 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. Isso economiza o round-trip até o portal do governo, que retorna mensagens genéricas e demora para responder.
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 a roda. Assinatura e transmissão são delegadas para bibliotecas especializadas e já validadas em produção:•erpbrasil.assinatura — ICP-Brasil A1/A3, RSA-SHA1, XML-DSig•erpbrasil.transmissao — SOAP 1.1 com mTLSIsso significa que a mesma infraestrutura de certificados e transmissão usada para NF-e, CT-e e MDF-e funciona para o eSocial.
Tabelas de referência versionadas
As 60 tabelas oficiais do eSocial (CBO, CNAE, CID, motivos de afastamento, categorias de trabalhadores, etc.) são baixadas do portal oficial e versionadas no repositório git. Isso permite acompanhar mudanças nas tabelas entre versões do leiaute.
# Atualizar tabelas ./scripts/download_tabelas.sh git diff esociallib/tabelas/ # ver o que mudou
Testando sem certificado real
A lib inclui suporte a certificados fake para testes, usando erpbrasil.assinatura.misc.create_fake_certificate_file():
from erpbrasil.assinatura.misc import create_fake_certificate_file
from esociallib import to_xml, assinar
# Certificado auto-assinado para testes
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)
A transmissão também pode ser mockada nos testes unitários, sem depender de rede ou do portal do governo.
Atualizando para novos leiautes
Quando o governo publicar uma nova Nota Técnica:
./scripts/download_xsds.sh # baixa os XSDs atualizados ./scripts/generate_bindings.sh # regenera os bindings xsdata pytest tests/ # verifica se tudo continua funcionando
Começando
pip install esociallib Para desenvolvimento:
git clone https://github.com/erpbrasil/esociallib cd esociallib pip install -e ".[dev]" ./scripts/download_xsds.sh pytest tests/
A lib é distribuída sob licença MIT e aceita contribuições.
- PyPI: pypi.org/project/esociallib
- GitHub: github.com/erpbrasil/esociallib
- Documentação: README do repositório + docstrings nos builders