Skip to main content

otb-kbo-opendata-pyclient

CI Release Coverage PyPI Python versions Licence

Python client for the SFTP server of the Belgian Crossroads Bank for Enterprises (KBO/BCE), which publishes daily KBO Open Data ZIP files. Use it as a library or through the kbo-opendata command.

Features

  • Discover the latest publication, or look one up by index or by date
  • List everything on the server, filter by index or date range, and spot skipped indices
  • Download by filename, index, date, or "the latest", choosing update files, full files, or both
  • Write to a local directory or straight to S3, streaming rather than buffering whole files
  • Host-key verification against known_hosts by default
  • Fully typed, with a py.typed marker

Installation

pip install otb-kbo-opendata-pyclient

Getting access

KBO Open Data is free but not anonymous. Two steps are needed before this client can connect:

  1. Register on the KBO Open Data portal and accept the licence. This alone gives you manual downloads through the website.
  2. Request SFTP access separately, in advance, by emailing kbo-bce-webservice@economie.fgov.be. Portal registration does not grant it.

The credentials you receive are what this package uses. There is no test or sandbox server.

Credentials

The client needs the username and password issued by KBO. The library accepts them directly; the CLI reads them from the environment.

Variable Purpose
KBO_OPENDATA_USERNAME SFTP account name, which also names the remote directory
KBO_OPENDATA_PASSWORD SFTP password

About the published files

KBO snapshots its database daily and publishes two ZIP files per snapshot:

  • a full file — every active registered entity and establishment unit at the moment of the snapshot
  • an update file — the differences between the last full file and the one before it

Files are kept for 31 days only. Anything older is gone from the server, so list_all(), missing_indices() and date lookups only ever see roughly the last month. Download the full file first, then keep up with either update files or a periodic full file.

The XXXX in a filename is the ExtractNumber, incremented by one per publication. It is not a date: KBO can skip a calendar day, which is why missing_indices() reports gaps in the sequence rather than missing dates.

What is inside a ZIP

This package downloads and stores the ZIP files; it does not extract or parse them. Each archive holds CSV files — meta.csv, code.csv, enterprise.csv, establishment.csv, denomination.csv, address.csv, contact.csv, activity.csv and branch.csv — joined on the enterprise number, establishment number or branch id. The CSV conventions are a comma delimiter, double-quoted text, a full stop as decimal point, and dd-mm-yyyy dates.

meta.csv carries SnapshotDate, ExtractTimestamp, ExtractType (full or update), ExtractNumber and the format Version, which is the reliable way to confirm what an archive actually contains.

An update archive splits each table into a _delete and an _insert file. Applying one means deleting every row for the listed entity numbers, then inserting the rows from the _insert file — the insert file repeats all current rows for a changed entity, not only the changed ones. The files carry no history: only the current state of active entities.

Documentation

  • Cookbook — file structure, CSV field descriptions and the update procedure
  • Data catalogue, the reusable data fields — no English version exists, only Dutch and French
  • KBO Open Data page

Library usage

import datetime as dt

from kbo_opendata import KboOpenDataClient, LocalDestination, S3Destination

with KboOpenDataClient(username="...", password="...") as client:
    latest = client.latest()
    print(latest.update_filename, latest.full_filename)

    pair = client.get_by_index(423)  # None when the index was skipped
    pair = client.get_by_date(dt.date(2026, 8, 7))

    client.download_latest(LocalDestination("./downloads"))
    client.download_index(423, S3Destination("my-bucket", "kbo/"), kinds=["full"])

KboOpenDataClient.from_env() builds the same client from the environment variables above.

Queries

Method Returns
latest() The pair with the highest index, or None
latest_n(count) The most recent pairs, newest last
get_by_index(index) The pair for that index, or None
get_by_date(date) The pair for that date, or None
list_all() Every pair, oldest first
list_by_index_range(start, end) Pairs within inclusive index bounds
list_by_date_range(start, end) Pairs within inclusive date bounds
missing_indices() Indices skipped between the lowest and highest present
exists(filename) Whether the server holds that file
stat(filename) Size and modification time

A KboFilePair carries update_filename and full_filename, either of which is None when the server holds only one of the two. Both are bare filenames, without a path.

Downloads

Method Downloads
download(filenames, destination) The named files
download_index(index, destination) The files for one index
download_date(date, destination) The files for one date
download_latest(destination) The most recent files

Every download method accepts kinds (defaults to update and full), overwrite (defaults to False, so existing files are skipped) and dry_run. They return a DownloadResult whose written, skipped, missing and planned tuples say what happened to each file.

The index and date variants raise RemoteFileNotFoundError when nothing matches; download reports unknown names as missing instead, so a multi-file request always reports on every name.

S3

S3Destination("my-bucket", "kbo/", extra_args={"ServerSideEncryption": "AES256"})

A boto3 client is created from the ambient AWS configuration on first use. Pass client= to supply one built from your own session, and extra_args to forward parameters to the upload.

Command line usage

export KBO_OPENDATA_USERNAME=...
export KBO_OPENDATA_PASSWORD=...

kbo-opendata show-latest
kbo-opendata check-index 0423
kbo-opendata check-date 2026-08-07
kbo-opendata list-files --from-index 400 --latest 10
kbo-opendata list-gaps
kbo-opendata check-credentials

kbo-opendata download-latest --dest ./downloads
kbo-opendata download-index 423 --dest ./downloads --kind full
kbo-opendata download-date 2026-08-07 --s3-bucket my-bucket --s3-prefix kbo/
kbo-opendata download KboOpenData_0423_2026_08_07_Full.zip --dest ./downloads

Dates are accepted as 2026-08-07, 2026_08_07 or 20260807, on every supported Python version.

Add --json for machine-readable output, --overwrite to replace existing files, --dry-run to see what would be transferred, and -v/-vv/-q to adjust logging.

Exit codes

Code Meaning
0 Success
1 Nothing matched the request
2 Usage error
3 Configuration, authentication or connection failure
4 The destination could not be written to

Host keys

The client verifies the server's host key against ~/.ssh/known_hosts and refuses to connect to an unknown host. Add the server once with ssh-keyscan, or pass accept_unknown_host_key=True (--accept-unknown-host-key on the CLI) to trust it on first use.

Logging

The package logs through the standard logging module under the kbo_opendata logger and installs no handlers of its own. The CLI configures a stderr handler for its own process.

Development

uv sync --group dev
uv run ruff check . && uv run ruff format --check .
uv run mypy
uv run coverage run -m pytest && uv run coverage report

The test suite is fully offline: the SFTP transport and the download destinations sit behind typed protocols, and the tests drive real in-memory implementations of them rather than mocks.

Reusing the data

The data is covered by the KBO Open Data licence, which you accept at registration — separate from this package's MIT licence, which covers only the code. One restriction is worth stating plainly: personal data from these files may not be reused for direct marketing purposes. See the licence and the CBE privacy statement.

Licence

MIT

Metadata

Release files for otb-kbo-opendata-pyclient 1.0.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 otb-kbo-opendata-pyclient 1.0.0
File Size Uploaded
otb_kbo_opendata_pyclient-1.0.0.tar.gz 24.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for otb-kbo-opendata-pyclient 1.0.0
File Interpreter ABI Platform
otb_kbo_opendata_pyclient-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 55.0 kB

Release files / otb_kbo_opendata_pyclient-1.0.0.tar.gz

Download URL otb_kbo_opendata_pyclient-1.0.0.tar.gz
Size 24.5 kB
Tags Source
SHA-256 checksum
How to use checksums
081cf082416db7d45e8f728a2a67c0dba74437596f5b36feb07fcc8a6324508d
BLAKE2b-256 checksum
How to use checksums
21a2dc2b28de2502b0dc167e9875f30c02a9d51f276df1297408f81ff48d688c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Aug 7, 2026.

Transparency log

Release files / otb_kbo_opendata_pyclient-1.0.0-py3-none-any.whl

Download URL otb_kbo_opendata_pyclient-1.0.0-py3-none-any.whl
Size 30.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9bad0869baa959619cc6179056f05ee6ef6c96484086482c50be610850f5d3d2
BLAKE2b-256 checksum
How to use checksums
eee7f25d399c36da72310b00478a5816ce2adcf682d3682524b51863f72ff797
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Aug 7, 2026.

Transparency log

Release history Release notifications | RSS feed

2.0.0

2 release files

This release

1.0.0 This release

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