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 e em produção real 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. Pin recomendado:PyNFSeNacionalGT>=0.3.0— a v0.1.0 tem o bug de ordem da<IM>(corrigido na 0.2.0) e a 0.3.0 traz o leiaute RTC 1.01.
🚀 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
- ✅ Publicado no PyPI (
PyNFSeNacionalGT) - ✅ Tomador completo:
IM, endereço, telefone e e-mail no<toma>(v0.2.0) - ✅ Leiaute RTC 1.01 da DPS (NT 004 v2.0 / NT 007) — pronto para as validações obrigatórias de 03/08/2026
- ⏳ Endurecimento a partir de mais emissões reais
- ⏳ Tomador estrangeiro / sem documento; não-optantes (Lucro Presumido/Real)
- ⏳ Grupo IBS/CBS na DPS — obrigatório só para Regime Regular a partir de 03/08/2026 (o Simples é dispensado do destaque em 2026); ainda não emitido
- ⏳ Eventos (cancelamento)
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).
Metadata
Release files for PyNFSeNacionalGT 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pynfsenacionalgt-0.3.0.tar.gz | 90.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pynfsenacionalgt-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 120.5 kB
Release files / pynfsenacionalgt-0.3.0.tar.gz
| Download URL | pynfsenacionalgt-0.3.0.tar.gz |
|---|---|
| Size | 90.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c1608de5ed7e4187a52db2a54f492bdbcff6c927693a97483daa18cd1156f1b7
|
|
BLAKE2b-256 checksum How to use checksums |
70c3c57f5bfaa8f9e43ca9ec80c1605ec5aced71e43b30c35de3bb83f5ca2a54
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 17, 2026.
Transparency logRelease files / pynfsenacionalgt-0.3.0-py3-none-any.whl
| Download URL | pynfsenacionalgt-0.3.0-py3-none-any.whl |
|---|---|
| Size | 30.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6b8a91da3c71dfd2721a4b8fc6606edb9da7d14749eff4c1a502526a1a0a5616
|
|
BLAKE2b-256 checksum How to use checksums |
bbfc233dc4150029c003ac9a9ad966c3bf5c1cd48b8819adc8f09faf9cd4e9f2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 17, 2026.
Transparency log