Emissão de NFS-e pela API SEFIN Nacional (DPS) + geração local do DANFSe, em Python puro.
Project description
PyNFSeNacional
Emissão de NFS-e pela API do Sistema Nacional (SEFIN) e geração do DANFSe — em Python.
Feito por um contador, para contadores e desenvolvedores que precisam emitir nota fiscal de serviço no padrão nacional sem depender de robô de navegador nem da API de PDF do governo.
⚠️ Status: alpha. O pipeline está completo e funciona ponta a ponta —
config → certificado → DPS → assinatura → transporte mTLS → DANFSe— e já emitiu em homologação contra o SEFIN Nacional. A montagem da DPS é validada byte a byte contra uma implementação de referência em PHP que já emite em produção. Ainda assim, é uma biblioteca de emissão de NFS-e em estágio inicial: valide cada emissão.
Por que existe
Com a obrigatoriedade do Sistema Nacional NFS-e chegando para o Simples Nacional (~set/2026), todo escritório de contabilidade vai precisar emitir NFS-e pelo padrão nacional. O ecossistema PHP já tem bibliotecas maduras para isso; o Python, não — falta uma solução turnkey, ponta a ponta. Este projeto preenche essa lacuna, integrando o que o ecossistema fiscal Python já tem de melhor e adicionando o que faltava (o transporte ao SEFIN nacional + o acabamento).
Duas confusões que este projeto já resolve
- Existem duas APIs do governo. A de emissão (SEFIN Nacional) recebe a DPS assinada e devolve a NFS-e — é viva e é o futuro. A de geração de PDF/DANFSe (ADN) é descontinuada em 01/07/2026 (NT-008/2026). Por isso, aqui o DANFSe é gerado localmente.
ambGernão é ambiente. O indicador Produção/Homologação é otpAmb, não oambGer(toda nota nacional temambGer=2). Confundir os dois marca nota de produção como "sem validade".
✨ Destaques
- 🧾 Emite NFS-e pela API oficial (SEFIN Nacional) com certificado A1 — sem robô de navegador.
- 🖨️ DANFSe gerado localmente (PDF), antecipando o fim da API de PDF do governo.
- 🔐 Assinatura XMLDSIG por biblioteca madura (
erpbrasil.assinatura), validada byte a byte. - ✅ Validação fiscal antes de enviar — pega E0312/E0712/E1235… e CPF/CNPJ (mód-11) localmente.
- 🔁 Idempotência nativa (
verificarDps) — não duplica nota num reenvio. - 🧩 Núcleo enxuto e MIT-limpo; a geração de PDF é uma dependência opcional.
- 🐍 Tipado (
mypy --strict), testado (incl. golden contra a referência) e com CLI turnkey.
📦 Instalação
# núcleo: emite a NFS-e (sem gerar PDF)
pip install PyNFSeNacionalGT
# + geração local do DANFSe (PDF) — dependência opcional
pip install "PyNFSeNacionalGT[danfse]"
Requer Python 3.10+. No PyPI o pacote se chama
PyNFSeNacionalGT(o nomePyNFSeNacionalesbarra na proteção do PyPI por semelhança com outro projeto); o import continuapynfsenacional. Durante o alpha ainda não há release publicado — para testar agora, instale do código (ver Desenvolvimento).
🚀 Quickstart
Em Python
from pynfsenacional import Emissor
emissor = Emissor("config/cliente.json") # certificado A1 + dados do prestador
nota = emissor.emitir( # monta DPS → assina → envia ao SEFIN
valor=150.00,
descricao="Sessão de psicoterapia",
tomador={"cpf_cnpj": "00000000000", "nome": "Fulano de Tal"},
)
print(nota.emitida, nota.numero_nfse, nota.chave_acesso)
nota.danfse("nota.pdf") # gera o PDF do DANFSe localmente
Pela linha de comando
nfse-nacional emitir config/cliente.json \
--valor 150,00 --descricao "Sessão de psicoterapia" \
--tomador-doc 00000000000 --tomador-nome "Fulano de Tal" \
--ambiente homologacao \
--pdf nota.pdf
| Saída | Significado |
|---|---|
✅ emitida — nNFSe 13 · chave 3304… |
nota emitida; o nNFSe é atribuído pelo SEFIN |
❌ não emitida: [E0312] … |
rejeitada pelo SEFIN, com o código do erro |
❌ config inválida: … |
barrada antes do envio pela validação local |
🔧 Configuração (passo a passo)
Cada prestador é descrito por um JSON puro. Comece copiando o exemplo anotado:
- 📄
examples/config-exemplo.json— pronto para copiar (JSON puro). - 📝
examples/config-exemplo.jsonc— o mesmo, comentado campo a campo. - 📚 Schema completo em
docs/conhecimento-fiscal.md(§3).
{
"id": "exemplo",
"nome_cliente": "EMPRESA EXEMPLO LTDA",
"ambiente": "homologacao", // homologacao (teste) | producao (nota real)
"certificado": { // ★ certificado A1 do PRÓPRIO prestador (.pfx)
"path": "certs/exemplo.pfx", // NUNCA versionar — fica fora do git
"senha": "0000"
},
"prestador": {
"cnpj": "00000000000000", // ★ 14 dígitos
"codigo_municipio": "0000000", // ★ IBGE 7 díg do município do emitente
"regime": { // ★ regime tributário
"opSimpNac": 3, // 1=Não Optante · 2=MEI · 3=Optante ME/EPP
"regApTribSN": 1,
"regEspTrib": 0
}
// nome/endereço do prestador NÃO entram aqui: o SEFIN puxa do cadastro (E0128/E0121)
},
"servico": {
"codigo_municipio_prestacao": "0000000", // ★ IBGE do local da prestação
"cTribNac": "041601", // ★ Código de Tributação NACIONAL (6 díg, LC116)
"cTribMun": "001", // ★ desdobro municipal (sem ele → E0312)
"descricao_padrao": "Serviço Prestado",
"tributos": { "pTotTribSN": "6.00" }// ★ se Simples: % efetiva do Simples Nacional
}
}
O que cada prestador precisa fornecer
| Dado | Onde obter |
|---|---|
| Certificado A1 (.pfx) + senha | do próprio prestador (anuência); renove antes de vencer |
| CNPJ | cadastro |
| Código do município (IBGE) | município de atuação do prestador |
Regime (opSimpNac/regApTribSN) |
contabilidade (é Simples? MEI ou ME/EPP?) |
cTribNac (6 díg) |
item da LC116 da atividade (mesmo código do portal) |
cTribMun (desdobro) |
o que o município administra p/ aquele cTribNac |
pTotTribSN (% Simples) |
alíquota efetiva do Simples (contabilidade) |
🔒 Nada sensível vai para o git. O
.pfx, as configs reais (config/) e os XML/PDF de notas são ignorados por padrão (ver.gitignore). Os dados de exemplo são fictícios.
🧩 Como funciona
Este pacote integra as libs maduras do ecossistema fiscal Python e escreve só o que faltava
(o transporte ao SEFIN nacional + o acabamento). Ver docs/roadmap.md.
config (JSON) → montar DPS (XML) → assinar (XMLDSIG) → gzip+base64 → POST /nfse (mTLS)
│ │ │
lxml erpbrasil.assinatura SEFIN Nacional
│
NFS-e (XML)
│
render DANFSe local (PDF)
│
BrazilFiscalReport
| Peça | Biblioteca | Módulo |
|---|---|---|
| Montar/serializar o XML da DPS | lxml |
dps.py |
| Assinatura digital XMLDSIG | erpbrasil.assinatura |
assinatura.py |
Ler o certificado A1 .pfx |
cryptography |
certificado.py |
| Transporte mTLS ao SEFIN | requests + requests-pkcs12 + código próprio |
sefin.py |
| Gerar o DANFSe (PDF) | BrazilFiscalReport |
danfse.py |
| Validação fiscal + CLI | — | config.py, cli.py |
🗺️ Status e roadmap
✅ Implementado e validado · ⏳ próximo
- ✅ Config + validação fiscal (E-codes, CPF/CNPJ mód-11)
- ✅ Leitura do certificado A1 (
.pfx) - ✅ Montagem da DPS — C14N idêntico, byte a byte, à referência PHP (golden)
- ✅ Assinatura XMLDSIG (mesmo
DigestValuedo gabarito) - ✅ Transporte mTLS + idempotência — emissão real validada em homologação
- ✅ DANFSe local (PDF)
- ✅ CLI turnkey + logging
- ⏳ Endurecimento a partir de mais emissões reais; publicação no PyPI
- ⏳ Tomador estrangeiro / sem documento; não-optantes (Lucro Presumido/Real)
- ⏳ Eventos (cancelamento); IBS/CBS (reforma tributária)
Detalhes em docs/roadmap.md e CHANGELOG.md.
🧪 Desenvolvimento
git clone https://github.com/Gomes343/PyNFSeNacional.git
cd PyNFSeNacional
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]" # dev já inclui o extra [danfse]
pytest # testes (inclui o golden contra a referência)
ruff check . # lint
mypy # tipos (strict)
Como contribuir: CONTRIBUTING.md. Reportar vulnerabilidades: SECURITY.md.
⚖️ Aviso legal
Biblioteca para emissão de NFS-e, em estágio alpha. Use por sua conta e risco e valide cada emissão — a responsabilidade pela nota é sempre do contribuinte/emitente. Não é um produto fiscal homologado/certificado e não substitui orientação contábil. Sem garantia de qualquer tipo (ver LICENSE).
📄 Licença
MIT — ver LICENSE. O núcleo usa só dependências permissivas. A geração do DANFSe
(opcional, [danfse]) usa a BrazilFiscalReport (LGPL-3.0), empregada como dependência — quem
só emite não a instala.
🙏 Créditos
Construído sobre o trabalho da comunidade fiscal Python brasileira — Akretion/erpbrasil
(erpbrasil.assinatura) e Engenere (BrazilFiscalReport).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pynfsenacionalgt-0.1.0.tar.gz.
File metadata
- Download URL: pynfsenacionalgt-0.1.0.tar.gz
- Upload date:
- Size: 85.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
28e23fa81552e5265596086475468d6a62b10a16891603e9ccc1708e8fa851af
|
|
| MD5 |
e1bf13dc433606b0e053521848b37622
|
|
| BLAKE2b-256 |
e930bbe97faaaa408c6791bb106b5ca9c339afd1abdfd84580519951469a8d82
|
Provenance
The following attestation bundles were made for pynfsenacionalgt-0.1.0.tar.gz:
Publisher:
release.yml on Gomes343/PyNFSeNacional
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pynfsenacionalgt-0.1.0.tar.gz -
Subject digest:
28e23fa81552e5265596086475468d6a62b10a16891603e9ccc1708e8fa851af - Sigstore transparency entry: 1940007505
- Sigstore integration time:
-
Permalink:
Gomes343/PyNFSeNacional@d7691d1716341afe5e7299d90c18ba0fce3e6eb0 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Gomes343
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d7691d1716341afe5e7299d90c18ba0fce3e6eb0 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pynfsenacionalgt-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pynfsenacionalgt-0.1.0-py3-none-any.whl
- Upload date:
- Size: 28.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bb9ca29dd793c02f261817c13038ccfb2a43b7454dd85698b4a3935c33ed8aa7
|
|
| MD5 |
40724287db30d57ec0fc5b0be0243fe2
|
|
| BLAKE2b-256 |
2a9ad9043118445d047f0e11794cc015ac8bc6a7bac3a5f3175a95b4387a54ab
|
Provenance
The following attestation bundles were made for pynfsenacionalgt-0.1.0-py3-none-any.whl:
Publisher:
release.yml on Gomes343/PyNFSeNacional
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pynfsenacionalgt-0.1.0-py3-none-any.whl -
Subject digest:
bb9ca29dd793c02f261817c13038ccfb2a43b7454dd85698b4a3935c33ed8aa7 - Sigstore transparency entry: 1940007681
- Sigstore integration time:
-
Permalink:
Gomes343/PyNFSeNacional@d7691d1716341afe5e7299d90c18ba0fce3e6eb0 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Gomes343
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d7691d1716341afe5e7299d90c18ba0fce3e6eb0 -
Trigger Event:
push
-
Statement type: