Skip to content

sellnov/ksef-python

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ksef

A lightweight, framework-agnostic Python client for the Polish National e-Invoicing System (Krajowy System e-Faktur - KSeF) API 2.0.

This library is designed to be simple, synchronous (ideal for frameworks like Django or Flask), and relies on requests for HTTP communication and cryptography for RSA token encryption required by the authentication process.

Features

  • Full implementation of the KSeF API 2.0 endpoints (Auth, Sessions, Invoices, Certificates, Permissions, Batch, Limits).
  • Built-in automatic handling of the complex token authentication flow (Challenge -> RSA Encryption -> Init -> Wait -> Redeem).
  • Automatic KSeF error parsing into readable Python exceptions (Error, AuthError, TimeoutError).
  • Clean, Pythonic syntax with proper type hinting and Context Manager support.

Installation

Install the package and its dependencies using pip:

pip install ksef

(Note: If installing from source, you can run pip install -e . in the directory containing pyproject.toml)

Quick Start & Example Usage

Here are some common examples of how to use the client using Python best practices (context managers and specific exceptions).

1. Initialization, Authentication & Context Management

To connect to KSeF, you need your NIP (Tax Identification Number) and an Authorisation Token generated in the KSeF portal. It is recommended to use the client as a Context Manager (with block) to ensure the underlying HTTP session is correctly closed.

from ksef import Client
from ksef.exceptions import AuthError, Error

# By default, test=True connects to the test environment (api-test.ksef.mf.gov.pl)
with Client(test=True) as client:
    try:
        print("Logging into KSeF...")
        client.login(nip='1111111111', token='YOUR_KSEF_AUTHORISATION_TOKEN')
        print(f"Login successful! Active Token: {client.token}")

        # You can now safely make other KSeF calls...
        status = client.session_status()
        print(f"Session reference: {status.get('referenceNumber') if status else 'None'}")

    except AuthError as e:
        print(f"Authentication failed: {e}")
    except Error as e:
        print(f"KSeF API Error: {e}")

2. Sending an Invoice (Online Mode)

You no longer need to extract tokens manually; the client automatically uses its authenticated token for the required Session-Token header.

from ksef import Client
from ksef.exceptions import Error

invoice_payload = {
    "invoiceHash": {
        "hashSHA": {
            "algorithm": "SHA-256",
            "encoding": "Base64",
            "value": "base64_encoded_sha256_hash_of_xml"
        },
        "fileSize": 1024
    },
    "invoicePayload": {
        "type": "plain",
        "invoiceBody": "base64_encoded_xml_invoice_content"
    }
}

with Client(test=True, nip='1111111111', ksef_token='YOUR_TOKEN') as client:
    try:
        client.login()  # Authenticates using credentials from initialization
        
        response = client.invoices.send_online(invoice_data=invoice_payload)
        
        print("Invoice sent successfully!")
        print(f"Reference Number: {response.get('referenceNumber')}")
        
    except Error as e:
        print(f"Failed to send invoice: {e}")

3. Querying Invoices

You can search for invoices within a specific date range:

search_criteria = {
    "queryCriteria": {
        "subjectType": "subject1",
        "type": "incremental",
        "acquisitionTimestampThresholdFrom": "2023-10-01T00:00:00Z",
        "acquisitionTimestampThresholdTo": "2023-10-31T23:59:59Z"
    }
}

with Client(test=True) as client:
    client.login(nip='1111111111', token='YOUR_TOKEN')
    
    response = client.invoices.query_metadata(
        filters=search_criteria, 
        params={"PageSize": 10, "PageOffset": 0}
    )
    print(f"Found {len(response.get('items', []))} invoices in the current page.")

4. Terminating the Session

It's good practice to terminate your session when you're done, even when using the context manager.

with Client(test=True) as client:
    client.login(nip='1111111111', token='YOUR_TOKEN')
    
    # ... perform operations ...

    print("Terminating KSeF session...")
    client.sessions.terminate_current()

Architecture

The client is split into modular managers mimicking the KSeF domain logic:

  • client.auth - Authentication flows
  • client.sessions - Session management
  • client.invoices - Invoice sending, querying, and downloading
  • client.certificates - Certificate operations
  • client.permissions - Permission management
  • client.batch - Batch operations
  • client.limits - API limit inquiries

About

Python KSeF 2.0 API Client

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages