Skip to main content

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.

CI PyPI Python License: MIT Ruff Checked: mypy Status

⚠️ 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

  1. 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.
  2. ambGer não é ambiente. O indicador Produção/Homologação é o tpAmb, não o ambGer (toda nota nacional tem ambGer=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 nome PyNFSeNacional esbarra na proteção do PyPI por semelhança com outro projeto); o import continua pynfsenacional. 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:

{
  "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 DigestValue do 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.


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)

Source distribution for PyNFSeNacionalGT 0.3.0
File Size Uploaded
pynfsenacionalgt-0.3.0.tar.gz 90.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for PyNFSeNacionalGT 0.3.0
File Interpreter ABI Platform
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 log

Release 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

Release history Release notifications | RSS feed

1.0.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

This release

0.3.0 This release

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page