CryptoSys Home > FirmaSAT > Python Interface

Python Interface to FirmaSAT

A Python interface to FirmaSAT for Windows.

Download and installation | Documentation | Classes | Errors | Examples | Tests | System requirements | Contact

Download and installation

Automatic install from PyPi

pip install firmasatpy

To upgrade if an older version is already installed:

> pip install --upgrade firmasatpy

Manual install

  1. Download the distribution zip file: firmasatpy-<x.x.x>.zip from the Python Package Index (PyPi).
  2. Open a command-line console in the same directory as the zip file and type
    pip install firmasatpy-<x.x.x>.zip


Read the FirmaSAT Py documentation.


Operates on the sello (signature) node in a SAT XML document.
Operates on the Timbre Fiscal Digital (TFD) element, if present.
PKI X.509 security utilities. Operates on private keys and X.509 certificates.
XML utilities. Operates on SAT-specific XML documents.
General info about the core library DLL, e.g. version number, compile date.
Details of errors returned by the core library DLL.

All code in is one module for simplicity of distribution. All methods are static methods.


To use in Python's REPL:

>>> from firmasat import *
>>> Gen.version()

If you don't like import * and find firmasat a bit long to type each time, try

>>> import firmasat as fs
>>> fs.Gen.version()

To sign a CFDI document, create the base XML file (example XML base) with all the required data except the following nodes


You must add the 20-digit serial number of your signing certificate to the NoCertificado node. See below.

Then run the Sello.sign_xml() method with full paths to your key and cer files.

n = Sello.sign_xml('new.xml', 'base.xml', "emisor.key", password, "emisor.cer")

This creates a new file new.xml with the sello and certificado nodes completed (example XML signed).

Finding a certificate's serial number

>>> firmasat.Pkix.query_cert('emisor.cer', 'serialNumber')

or using FirmaSAT from the command line

> firmasat NUMBERCERT emisor.cer

More examples. See also tests below.

>>> Sello.make_digest('cfdv40-ejemplo.xml')

>>> Pkix.query_cert('AC4_SAT.cer', Pkix.Query.KEYSIZE)

>>> Xmlu.get_attribute('cfdv40-ejemplo.xml', "Nombre", "cfdi:Emisor")
'Esta es una demostración'


Most errors (missing files, invalid format) will result in a firmasat.Error exception, although some methods are more forgiving and will return a negative error code instead. Passing a bad argument will result in an ArgumentError exception

>>> Sello.make_digest('missingfile.xml')
Traceback (most recent call last):
firmasat.Error: ERROR CODE 1: Cannot open input file/No se puede abrir archivo de entrada: 
Cannot open file 'missingfile.xml'/No se puede abrir el archivo
>>> Pkix.query_cert('AC4_SAT.cer', 666)
Traceback (most recent call last):
ctypes.ArgumentError: argument 4: <type 'exceptions.TypeError'>: wrong type


There is a series of tests in test/ (source code). You should find an example there of what you want to do.

These tests require a subdirectory work in the same folder which must contain all the required test files.

    |   emisor.cer
    |   emisor.key
    |   <...all required test files>
            <..temporary files...>

The test function creates a new temporary subdirectory each time, which is deleted automatically. If you want to keep this temp folder for debugging, then add the argument nodelete on the command line.

This structure is already set up in the distribution file, so unzip the file and open a command-line prompt in the test subdirectory. You can do any of the following.

  1. python
  2. py.test -v
  3. Open the file using IDLE and select Run > Run Module (F5).

We've tested this using the Python 3.10.8 interpreter and IDLE, PyCharm 2020.3, and py.test.

System requirements

Windows platforms only. Python 3 must be installed on your system (at least 3.6). FirmaSAT v10.50 or above must also be installed.


To comment on this page, make a suggestion for improvement, or just to say you liked it, please send us a message.

This page first published 28 August 2016. Last updated 19 April 2023.