Package: nfelib
nfelib - bindings Python para e ler e gerir XML de NF-e, NFS-e nacional, CT-e, MDF-e, BP-ePorque escolher a nfelibSimples e confiável. As outras bibliotecas costumam ter dezenas de milhares de linhas de código feito tudo manualmente para fazer o que o nfelib faz tudo automaticamente com algumas linhas para gerir código com oxsdataa partir dos últimos pacotes xsd da Fazenda. O xsdata é uma biblioteca de databinding extremamente bem escrita e bem testada. A própria nfelib tem testes para ler e gerir todos documentos fiscais.Completa: já que gerir os bindings ficou trivial, a nfelib mantém atualizada todos os bindings para interagir com todos os serviços e eventos de NF-e, NFS-e nacional, CT-e, MDF-e, BP-e. Os testes detetam também quando sai uma nova versão de algum esquema.ImportanteEsta é a novaversão 2.xda nfelib onde os bindings são geridos com xsdata. Na versão 1.x os "bindings" eram geridos com generateDS. Fora algumas exceções listadas nos elementosSubstitutionno arquivo de configuração.xsdata.xml, os novos bindings tem os mesmos campos que também correspondem aos atributos dos xsd. O nome das classes dos bindings ficou diferente (mais "pythonico") porém então para ler os bindings a compatibilidade é quase perfeita, mas para montar bindings o código deve ser adaptado.
Para facilitar a fase de transição para a nfelib 2.0, as primeiras versões da nfelib 2.0 estão empacotando também os antigos bindings da versão 1.x, no mesmo caminhonfelib/v4_00.
Se vc estiver procurando o codigo "legacy da versão 1.x, ele esta na branchmaster_gen_v4_00InstalaçãopipinstallnfelibComo usarNF-e>>># Ler o XML de uma NF-e:>>>fromnfelib.nfe.bindings.v4_0.proc_nfe_v4_00importNfeProc>>>nfe_proc=NfeProc.from_path("nfelib/nfe/samples/v4_0/leiauteNFe/NFe35200159594315000157550010000000012062777161.xml")>>># (pode ser usado também o metodo from_xml(xml) )>>>>>>nfe_proc.NFe.infNFe.emit.CNPJ'59594315000157'>>>nfe_proc.NFe.infNFe.emitTnfe.InfNfe.Emit(CNPJ='59594315000157',CPF=None,xNome='Akretion LTDA',xFant='Akretion',enderEmit=TenderEmi(xLgr='Rua Paulo Dias',nro='586',xCpl=None,xBairro=None,cMun='3501152',xMun='Alumínio',UF=<TufEmi.SP:'SP'>,CEP='18125000',cPais=<TenderEmiCPais.VALUE_1058:'1058'>,xPais=<TenderEmiXPais.BRASIL:'Brasil'>,fone='2130109965'),IE='755338250133',IEST=None,IM=None,CNAE=None,CRT=<EmitCrt.VALUE_1:'1'>)>>>nfe_proc.NFe.infNFe.emit.enderEmit.UF.value'SP'>>>>>># Serializar uma NF-e:>>>nfe_proc.to_xml()'<?xml version="1.0" encoding="UTF-8"?>\n<nfeProc xmlns="http://www.portalfiscal.inf.br/nfe" versao="4.00">\n<NFe>\n<infNFe versao="4.00" Id="35200159594315000157550010000000012062777161">\n<ide>\n<cUF>35</cUF>\n<cNF>06277716</cNF>\n<natOp>Venda</natOp>\n<mod>55</mod>\n<serie>1</serie>\n<nNF>1</nNF>\n<dhEmi>2020-01-01T12:00:00+01:00</dhEmi>\n<dhSaiEnt>2020-01-01T12:00:00+01:00</dhSaiEnt>\n<tpNF>1</tpNF>\n<idDest>1</idDest>\n[...]>>>>>># Montar uma NFe do zero:>>>fromnfelib.nfe.bindings.v4_0.nfe_v4_00importNfe>>>nfe=Nfe(infNFe=Nfe.InfNfe(emit=Nfe.InfNfe.Emit(xNome="Minha Empresa",CNPJ='59594315000157')))>>>nfeNfe(infNFe=Tnfe.InfNfe(ide=None,emit=Tnfe.InfNfe.Emit(CNPJ='59594315000157',CPF=None,xNome='Minha Empresa',xFant=None,enderEmit=None,IE=None,IEST=None,IM=None,CNAE=None,CRT=None),avulsa=None,dest=None,retirada=None,entrega=None,autXML=[],det=[],total=None,transp=None,cobr=None,pag=None,infIntermed=None,infAdic=None,exporta=None,compra=None,cana=None,infRespTec=None,infSolicNFF=None,versao=None,Id=None),infNFeSupl=None,signature=None)>>>>>># Validar o XML de uma nota:>>>nfe.validate_xml()["Element '{http://www.portalfiscal.inf.br/nfe}infNFe': The attribute 'versao' is required but missing.","Element '{http://www.portalfiscal.inf.br/nfe}infNFe': The attribute 'Id' is required but missing."[...]NFS-e padrão nacional>>># Ler uma NFS-e:>>>>fromnfelib.nfse.bindings.v1_0.nfse_v1_00importNfse>>>nfse=Nfse.from_path("alguma_nfse.xml")>>>>>># Serializar uma NFS-e:>>>nfse.to_xml()>>># Ler uma DPS:>>>>fromnfelib.nfse.bindings.v1_0.dps_v1_00importDps>>>dps=Nfse.from_path("nfelib/nfse/samples/v1_0/GerarNFSeEnvio-env-loterps.xml")>>>>>># Serializar uma DPS:>>>dps.to_xml()MDF-e>>># Ler um MDF-e:>>>>fromnfelib.mdfe.bindings.v3_0.mdfe_v3_00importMdfe>>>mdfe=Mdfe.from_path("nfelib/mdfe/samples/v3_0/ComPagtoPIX_41210780568835000181580010402005751006005791-procMDFe.xml")>>>>>># Serializar um MDF-e:>>>mdfe.to_xml()CT-e>>># Ler um CT-e:>>>>fromnfelib.cte.bindings.v4_0.cte_v4_00importCte>>>cte=Cte.from_path("nfelib/cte/samples/v4_0/43120178408960000182570010000000041000000047-cte.xml")>>>>>># Serializar um CT-e:>>>cte.to_xml()BP-e>>># Ler um BP-e:>>>>fromnfelib.bpe.bindings.v1_0.bpe_v1_00importBpe>>>bpe=Bpe.from_path("algum_bpe.xml")>>>>>># Serializar um BP-e:>>>bpe.to_xml()Desenvolvimento / testesPara rodar os testes:pytestPara atualizar os bindings:baixar o novo zip dos esquemas e atualizar a pastanfelib/<nfe|nfse|cte|mdfe|bpe>/schemas/<versao>/gerir os bindings de um pacote de esquemas xsd, por examplo da NF-e:xsdatageneratenfelib/nfe/schemas/v4_0--packagenfelib.nfe.bindings.v4_0Para gerir todos bindings com xsdata:./script.shVersões dos esquemas e pastasA nfelib usa apenas 2 dígitos para caracterizar a versão. Isso foi decidido observando que a Fazenda nunca usa o terceiro dígito da versão e que a mudança do segundo dígito já caracteriza uma mudança maior. Nisso qualquer alteração de esquema que não mudar o primeiro nem o segundo dígito da versão do esquema vai na mesma pasta e se sobreponha a antiga versão, assumindo que é possível usar o mais novo esquema no lugar do antigo (por exemplo é possível ler uma NFe 4.00 pacote nº 9j (NT 2022.003 v.1.00b) com os bindings da versão nfe pacote nº 9k (NT 2023.001 v.1.20).Pelo contrário, caso houver uma mudança maior afetando os 2 primeiros dígitos como NFe 3.0 e NFe 3.1 ou NFe 3.1 e NFe 4.0, será possível também suportar as várias versões ao mesmo tempo usando pastas diferentes. Assim seria possível por exemplo emitir a futura NFe 5.0 e ainda importar uma NFe 4.0.