Repository navigation
Releases: stacking-hq/ksef2
Release list
v1.1.0
Added
- Add
ksef2.certificate_storeswith sync and async signing-certificate store
protocols,SigningCertificaterecords and in-memory adapters, plus
KSeFCertificateStore*errors. Additive and optional; existing XAdES, profile and
encryption-certificate store APIs are unchanged. - Add
authentication.with_stored_certificate()on sync and async clients to
authenticate with a certificate loaded from a signing-certificate store.
Reject wrong-environment, Offline and mismatched records before contacting
KSeF. Document storing issued certificates and writing custom store adapters. - Add
FilesystemSigningCertificateStoreandAsyncFilesystemSigningCertificateStore:
one password-encrypted record per certificate, atomic publication, owner-only
files on POSIX, and metadata listing without unlocking keys.
Fixed
- Correct the certificate enrollment guide:
enroll(csr=...)takes a Base64-encoded
DER CSR, not PEM text. - Resolve XSLT code descriptions offline with bundled official country, tax-office,
tax-office ex-WUS, tax-office-head, and currency lists when
enable_code_lookups=True. Keep network access and writes blocked, and include
unresolved URIs inKSeFInvoiceRenderingErrormessages and details (#324). - Preserve the Base64 certificate text returned by
auth.certificates.retrieve()
instead of decoding DER bytes as UTF-8 (#323). Generate all OpenAPI byte fields
as strings so certificates, hashes, and encrypted data retain their wire values. - Include offending field paths and validation messages in
KSeFResponseValidationError.detailsfor individual and list responses, and
preserve the original Pydantic validation error.
v1.0.0
Fixed
-
Fix English and Polish documentation examples for limits, authentication,
token activation, imports, async entry points, certificate file paths, and
sample identifiers. Document client and session concurrency boundaries. -
Add safe filename/path hints for PEM, PKCS#12, and XML content inputs. Existing
PEM string paths retain their 1.x deprecation behavior. -
Report synchronous
close()misuse on async clients and sessions with
KSeFArgumentErrorand guidance to useawait ...aclose()orasync with. -
Enable full jitter for retry backoff through
RetryConfig.jitter, including
HTTP retries during polling.jitter=Falsekeeps deterministic backoff;
Retry-Aftervalues and their existing ceiling remain unchanged. -
Wrap invalid non-builder public model and request-conversion inputs in the
SDK validation-error hierarchy, preserving the Pydantic cause and naming the
public parameter. Validate KSeF invoice-number filters at construction,
including both current and legacy formats. -
Reject invalid PESEL checksums and PESEL/NIP formats in permission grants, mismatched
identifier types, empty permission lists, empty revoke IDs, and empty KSeF
token credentials before HTTP requests. Person and entity grants accept
snake_case strings or permission enums; PascalCase permissions suggest the
corresponding snake_case value. -
Completed exports with zero invoices return immediately from deprecated polling
helpers. Bothexport().wait()andexport().download(path)return empty
metadata and invoice lists for these packages without opening an archive. -
In-memory export downloads verify encrypted and plaintext sizes and SHA-256
hashes using the same checks as downloads to disk. -
Require an explicit FA(3) partial-payment status before building payment entries,
correct both builder guides, and report invalid builder fields as
KSeFValidationErrorwith the original validation error as the cause. Builder
amount, quantity, price, and exchange-rate hints now accept floats and numeric
strings, matching runtime decimal conversion. -
Restore deprecated
ksef2.clients.*submodule imports throughout 1.x.
ksef2 1.0.0 is being prepared as the first stable release. It targets KSeF
OpenAPI 2.8.1 and starts the 1.x compatibility contract. Collective-identifier
invoice queries change because KSeF replaced the endpoint. Old SDK import paths
and method names remain functional throughout 1.x (#171). Read
Breaking changes and Deprecated before upgrading.
Highlights
-
ExportJob.download(Path)decrypts export parts to disk with per-part size and
hash verification, andExportedInvoices.from_path()reads ZIP and TarGz
archives without loading the whole archive into memory (#305). Both accept
anyos.PathLikeand rejectstr/byteswithKSeFArgumentError. -
Offline validation rejects invoice metadata ranges longer than 100 days, documents
metadata page-size bounds, checks invoice sizes before sending or batch
encryption, computes batch part counts before encryption, validates signing
certificates and transport configuration, and defaults FA(3) XML serialization
to compact output (#299). PDF exports reject malformed roots and KSeF numbers,
and the token example stops before a placeholder can be sent. -
Public input handling follows one rule:
bytesandstrare content, while
Pathis a file. Batch preparation catches strings that name existing files,
FA(3) parsing accepts XML text with declarations, and PEM helpers warn when
legacy string paths are used (#297, #304). -
The documented import paths (
ksef2,ksef2.clients,ksef2.models,
ksef2.fa3,ksef2.xades,ksef2.logging,ksef2.profiles,
ksef2.renderers,ksef2.raw,
ksef2.raw.mappers, and the newksef2.testdata) are the compatibility
contract for the whole 1.x line. The rule is simple: a module path with no
underscore is public, and anything with an underscore is private and may change
in any release. See the
public API contract
and the 1.0.0 release notes. -
model_dump()andmodel_dump_json()redact secrets by default and are not a
persistence format. Useto_dict()/to_json()/from_dict()on resume
states andto_sensitive_dict()to persist. -
The invoice and admin workflows have their final 1.x shape: operations that
start asynchronous KSeF work return a handle with.wait(), every collection
returns onePager, and access tokens refresh automatically (#162, #163, #165).
See the 1.0.0 release notes
for a before/after. -
KSeF errors come from one pipeline with one message format, carry
ksef_code,
trace_idanddetails, and say what to do next inhint(#167). -
Public Pydantic model validation and invoice-builder validation raise SDK
exceptions; HTTP 403 raisesKSeFPermissionDeniedError, separate from
KSeFAuthError; terminal operation failures shareKSeFOperationFailedError
(#296). -
Deprecations are visible to type checkers and IDEs (PEP 702
@deprecated) and
remain functional through the 1.x line. Removal is a 2.0 decision (#171). -
Polling helpers continue through retryable server, rate-limit and transport
errors until their timeout. Invoice sends and refresh-token requests retry
only after an explicit429; ambiguous transport failures are not retried.
Connect failures are reported as non-ambiguous and lost invoice responses
include a recovery hint (#300).
Fixed
- FA(3) builder (#293, #304). Emit summary amounts for VAT buckets with
rows even when rounding or correction arithmetic produces zero, validate
foreign-currency VAT exchange rates, and document rounding, corrections, and
large-invoice performance. #304 parser string handling remains in #297; the
missing corrected-invoice error remains in #296.
Breaking changes
-
Explicit client environments and URL alignment (#294, #295).
Client,
AsyncClient, andInvoicePDFExporternow require an environment. Pass an
Environmentor a case-insensitive name such as"test". A supplied
http_clientwith nobase_urlinherits the selected environment URL; a
conflicting URL raisesKSeFArgumentErrorduring construction. This prevents
environment guards and network routing from disagreeing. -
Collective-identifier invoice queries (#128). KSeF API 2.8.1 replaced
GET /collective-identifiers/{collectiveIdentifierNumber}/invoiceswith
POST /collective-identifiers/invoices, which takes up to 10 identifiers in
the body. The old call is removed, not deprecated. Migration is mechanical:# before (0.22.x) page = auth.collective_identifiers.list_invoices(collective_identifier_number=cid) everything = auth.collective_identifiers.list_all_invoices( collective_identifier_number=cid ) # after (1.0.0) for invoice in auth.collective_identifiers.list_invoices( collective_identifier_numbers=[cid] ): ...
list_invoicesnow returns aPager(iterate items,.pages(),.first_page())
and no longer takescontinuation_token;list_all_invoicesremains as a
deprecated alias that still returns pages (#163). The high-level client
validates 1 to 10 identifiers before sending. The raw
endpoint takes a request body instead of a path parameter:from ksef2.raw import spec # before (0.22.x) auth.raw.collective_identifiers.list_invoices(cid) # after (1.0.0) auth.raw.collective_identifiers.list_invoices( spec.CollectiveIdentifierInvoicesQueryRequest(collectiveIdentifierNumbers=[cid]) )
Deprecated
-
Keep the former
ksef2.core,domain,infraandservicesimports,
including submodules, as deprecated aliases throughout 1.x (#171). The first
import loads the canonical package tree and warns once per package family. -
Keep deprecated call names, including invoice send/wait/UPO, metadata search,
download and export aliases, through 1.x. Removal is a 2.0 decision and may
happen no earlier than 2.0.0, replacing the former 1.10.0 removal schedule. -
Add English and Polish migration examples for legacy imports and workflows.
-
Former implementation imports (#153, #171). Implementations moved to
private_-prefixed paths. The old paths remain as deprecated aliases
throughout 1.x, warning with the public replacement. #171 supplies those aliases
and the migration examples. Use documented public modules rather than the private paths
in the table below for new code.Old import Private implementation ksef2.coreksef2._coreksef2.domainksef2._domainksef2.infraksef2._infraksef2.endpointsksef2._endpointsksef2.servicesksef2._servicesksef2.clients.<module>(base,auth,online,async_*, ...)ksef2._clients.<module>(ksef2.clientsstays the public facade with the same__all__)ksef2.configksef2._config(names stay exported fromksef2)ksef2._loggingksef2.logging(configure_logging)ksef2.raw.facade,ksef2.raw.async_facadeksef2.raw._facade,ksef2.raw._async_facade(names stay exported fromksef2.raw)If you imported something from an old path, import it from the public module
instead (see Added for names newly exported fromksef2.models).
Old SDK imports and method names remain functional through 1.x. Replaced
methods keep their old behavior and return type and carry deprecation warnings.
Removal is a 2.0 decision (#171), including APIs deprecated in 0.19.0. See the
deprecated APIs table
on the public API page for every alias and its replacement....
v0.22.2
v0.22.1
v0.22.0
v0.20.0
What's Changed
- chore: update OpenAPI spec to KSeF API 2.7.1 and regenerate models by @github-actions[bot] in #108
- chore: update OpenAPI spec to KSeF API 2.8.0 and regenerate models by @github-actions[bot] in #109
- chore(release): prepare v0.20.0 by @artpods56 in #110
Full Changelog: v0.19.0...v0.20.0
v0.19.0
What's Changed
- bump: version 0.18.0 → 0.18.1 by @artpods56 in #77
- [codex] expose low-level api and harden release gate by @artpods56 in #78
- chore: update OpenAPI spec to KSeF API 2.6.1 and regenerate models by @github-actions[bot] in #79
- chore: update OpenAPI spec to KSeF API 2.6.1 and regenerate models by @github-actions[bot] in #83
- chore: update OpenAPI spec to KSeF API 2.6.1 and regenerate models by @github-actions[bot] in #85
- chore: update OpenAPI spec to KSeF API 2.6.1 and regenerate models by @github-actions[bot] in #86
- chore: update OpenAPI spec to KSeF API 2.6.1 and regenerate models by @github-actions[bot] in #87
- Prepare the 1.0.0 release by @artpods56 in #84
- docs: document 1.0 release sign-off by @artpods56 in #101
- chore: update OpenAPI spec to KSeF API 2.7.0 and regenerate models by @github-actions[bot] in #102
- chore: update OpenAPI spec to KSeF API 2.7.1 and regenerate models by @github-actions[bot] in #106
- chore: update OpenAPI spec to KSeF API 2.7.1 and regenerate models by @github-actions[bot] in #107
Full Changelog: v0.18.1...v0.19.0