Skip to main content

otb-cbso-webservice-pyclient

Download Belgian annual accounts from the National Bank's Central Balance Sheet Office (CBSO). Use the Python package or the cbso-fetch command.

The package downloads selected batches and files accounts by enterprise. Validation and repair run as separate operations. Downloads and repairs run sequentially. The package can also download missing PDFs for PDF-only filings and collect consolidated accounts.

Installation

Use Python 3.10 or later.

pip install otb-cbso-webservice-pyclient

Install the S3 extra for S3 destinations.

pip install 'otb-cbso-webservice-pyclient[s3]'

The core dependencies are urllib3 and fsspec. The S3 extra adds s3fs and its dependencies.

Configure subscriptions

Each CBSO product requires its own subscription key. Choose the products that match your subscriptions and the data you need.

Batch product Contents Environment variable
extracts Daily batches of accounts as filed CBSO_KEY_EXTRACTS
authentic-archive Archive batches of accounts as filed CBSO_KEY_AUTHENTIC_ARCHIVE
improved Daily batches of corrected or converted accounts CBSO_KEY_IMPROVED
improved-archive Archive batches of corrected or converted accounts CBSO_KEY_IMPROVED_ARCHIVE

Set the key for each product you want to download.

export CBSO_KEY_EXTRACTS='your-extracts-subscription-key'

Repair and PDF-only downloads can need individual-access subscriptions.

Environment variable Used for
CBSO_KEY_AUTHENTIC Missing enterprise references and individual accounts as filed
CBSO_KEY_IMPROVED Individual improved references and account files

A batch request checks its product key. Reusing retained ZIP files requires no CBSO keys. Repair reports missing keys and continues with work that can use available subscriptions or saved data. Validation does not require CBSO subscription keys.

Command line

Subcommand Purpose Changes saved files?
download Fetch and extract selected batches Yes
validate Check selected formats against authentic references No
validate-improved Check improved JSON and expected OCR files No
repair-improved Restore missing improved JSON across saved references Yes
repair Restore missing files and resolve enterprise information Yes
download-pdf-only-accounts Download missing PDFs for PDF-only filings Yes
filter-consolidated-accounts Collect consolidated references and move their PDFs Yes

download requires dates, --products, and --destination. Supply past dates in YYYY-MM-DD form. Replace the example dates with the dates you need. Product availability determines which dates the service can supply. All other commands accept an input directory and scan files across all dates. validate and repair accept --formats; the default is json. validate-improved and repair-improved handle improved JSON only. repair-improved, download-pdf-only-accounts, and filter-consolidated-accounts also support --dry-run.

Download batches

download fetches references and accounts for each selected date and product. References connect deposit numbers to enterprise numbers. The command uses that connection to file accounts into enterprise folders.

Download one date as JSON-XBRL.

cbso-fetch download 2024-08-03 --products extracts --destination ./data

Download multiple dates and formats, with copies of the original ZIP files.

cbso-fetch download 2024-08-03 2024-08-04 \
  --products extracts \
  --destination ./data \
  --formats json xbrl pdf \
  --keep-zip

Select archive products directly to request archive batches. This example stores both authentic and improved JSON-XBRL accounts in S3.

cbso-fetch download 2024-08-03 \
  --products authentic-archive improved-archive \
  --destination s3://my-bucket/cbso
Option Behaviour
--formats json xbrl pdf Select account formats. The default is json.
--keep-zip Retain original reference and account ZIP files. The default is off.

json selects JSON-XBRL account data. Reference files use ordinary JSON. Authentic products support all three formats. Improved products support only json. A command containing improved products must select only JSON. Use separate commands when you need other formats from authentic products.

Existing ZIP files under archives/{product}/{date}/ are reused without a batch request. Every run extracts the selected ZIP files, including retained copies. Existing output files are overwritten. Without retained ZIP files, repeated runs download the batches again. ZIP retention is off by default. Dates are processed in the supplied order. Entries without usable enterprise information remain under pending/ for inspection or repair. Downloading does not request individual accounts or automatically repair missing files.

Validate saved files

validate scans JSON files under references/ and checks the selected account formats. It uses reference contents to determine enterprise numbers, deposit numbers, and expected file paths. The scan includes all dates. It does not require download history.

cbso-fetch validate ./data --formats xbrl pdf

Omit --formats to check JSON only. Missing XBRL for PDF-only accounts appears under unavailable. Pending reference files and pending accounts in selected formats appear under unresolved.

Validation checks file presence. It does not inspect account contents or validate XBRL schemas. It makes no CBSO requests and leaves stored files unchanged. An S3 destination still requires access to its stored objects. A missing reference directory is an error unless matching pending files exist.

A reference scan cannot detect a deposit when both its reference and account files are absent. An empty reference directory produces an empty report. This does not confirm that all service data was downloaded. Run download again to restore missing references from batches.

Validate improved files

validate-improved scans JSON files under improved-references/. It checks the improvement named by each reference and reports unresolved pending improvements. For PDF-based deposits, it also checks OCR JSON, even without a separate OCR reference.

cbso-fetch validate-improved ./data
cbso-fetch validate-improved s3://my-bucket/annual-accounts

Improved accounts support JSON only, so this command has no --formats option. It makes no CBSO requests and changes no files. Run repair-improved to restore missing improved files.

Repair missing files

repair scans authentic references across all dates and restores selected account formats.

cbso-fetch repair ./data --formats xbrl pdf

It first resolves damaged references and missing enterprise numbers through individual reference requests. It then files pending accounts using saved or recovered references. The pending directory supplies each file's product and format. The filename supplies its deposit number. Repair preserves existing accounts and removes pending copies only after the destination file exists. It requests remaining account gaps individually. These requests require CBSO_KEY_AUTHENTIC.

The final report includes restored paths and any work that remains incomplete. Unreadable references, missing keys, and unavailable accounts remain visible in the report. Repair does not request XBRL for PDF-only accounts.

Repair does not download or extract batch ZIP files. Run download to extract retained ZIP files or download batches whose ZIP files were not retained. Use repair-improved for improved references and accounts.

Repair improved accounts across all dates

export CBSO_KEY_IMPROVED='your-improved-subscription-key'
cbso-fetch repair-improved ./data
cbso-fetch repair-improved s3://my-bucket/annual-accounts

repair-improved scans all JSON files beneath improved-references/, including enterprise subdirectories. It uses no date or product filters. It accepts camelCase and PascalCase reference fields.

It checks the improvement identified by each reference:

Reference improvement Output filename
Annual-account correction {reference}-aa-corrected.json
Social-balance correction {reference}-sb-corrected.json
OCR extraction {reference}-ocr-authentic.json
Euro conversion {reference}-euro-authentic.json

For models ending in -p, it also requests missing OCR JSON, even without a matching OCR reference. It does not infer additional corrections or euro conversions without their reference metadata.

Files go into improved-jsons/{enterprise}/. Existing files remain unchanged. Duplicate references cause at most one request per output path during a run. Processing is sequential. Individual requests use CBSO_KEY_IMPROVED. Use --env test for UAT2 and the same environment as the source references. S3 requires the optional s3 installation and storage credentials.

The command first resolves pending improvements and missing enterprise information. Individual improved-reference requests must match both the deposit number and improvement label. Recovered metadata goes into improved-references/{enterprise}/. Repair does not substitute authentic metadata for missing improved metadata.

Inferred OCR downloads create account files only. They do not create reference metadata or invent publication dates. Future validation and repair scans check those OCR files through the original PDF-based references. The command does not scan authentic references/.

Preview downloads without CBSO requests or file changes:

cbso-fetch repair-improved ./data --dry-run

The preview prints readable DOWNLOAD, EXISTS, and INVALID lines. Paths are relative to the input directory. No CBSO key is needed for a preview. Pending files appear as INVALID; the preview does not resolve their metadata or plan their recovery.

Use the same operation from Python:

from cbso_webservice_client import repair_improved

report = repair_improved("./data")
print(report.to_dict())

preview = repair_improved("./data", dry_run=True)
print(preview.planned)

The function also accepts environment="test" and a caller-owned client. Normal runs create and close a client when none is supplied. Dry runs create no client.

The report lists restored, existing, planned, missing, unavailable, and unresolved paths. Invalid references, missing enterprise numbers, missing keys, and HTTP 404 responses remain visible; processing continues. Normal CLI runs print JSON. Exit code 1 indicates incomplete work. Other service or storage failures stop processing and produce exit code 4. A missing improved-references/ directory is a storage failure unless pending improvements exist.

Download PDFs for PDF-only accounts

export CBSO_KEY_AUTHENTIC='your-authentic-subscription-key'
cbso-fetch download-pdf-only-accounts ./data
cbso-fetch download-pdf-only-accounts s3://my-bucket/annual-accounts

Preview the downloads without changing files:

cbso-fetch download-pdf-only-accounts ./data --dry-run

Dry runs print readable DOWNLOAD, EXISTS, and INVALID lines with paths relative to the input directory. They read references and check PDF locations, but make no CBSO requests or file changes. No CBSO subscription key is needed. S3 still requires storage access. A planned download does not confirm that CBSO has the PDF or that the destination permits writes. Invalid references produce exit code 1; planned downloads alone produce exit code 0.

This command scans all JSON files beneath references/, including enterprise subdirectories. It selects references whose model code ends in -p, which marks a PDF-based filing. It accepts camelCase and PascalCase fields. It uses no date or product filters.

Each missing PDF is requested individually through the authentic service and saved under pdfs/{enterpriseNumber}/{referenceNumber}.pdf. This is the same path used by PDF batch downloads. Existing PDFs remain unchanged. Duplicate references cause at most one request per output path during a run. The operation makes no batch requests and leaves references unchanged. Processing is sequential.

Use --env test for UAT2. Use the same environment as the source references. S3 requires the optional s3 installation and storage credentials. The authentic subscription key is needed only when a PDF request is necessary.

Use the library function with the same input directory:

from cbso_webservice_client import download_pdf_only_accounts

report = download_pdf_only_accounts("./data")
print(report.to_dict())

Pass dry_run=True to preview downloads from Python:

report = download_pdf_only_accounts("./data", dry_run=True)
print(report.planned)

Dry runs populate planned with output paths and leave written empty. Normal runs leave planned empty. The function also accepts environment="test" and an optional client=Client(...). The caller owns an explicitly supplied client. Otherwise, normal runs create and close their own client. Dry runs create no client.

The returned Report uses these fields:

  • written: saved PDFs.
  • skipped: PDFs already present.
  • unresolved: invalid references or PDF-based references without a valid enterprise number.
  • missing: PDFs that could not be downloaded because of missing keys or HTTP 404 responses.
  • unavailable: PDFs for which CBSO returned HTTP 404.
  • missing_keys: required subscription keys that were absent.

Invalid references, missing keys, and HTTP 404 responses do not stop processing other references. The CLI prints a JSON report. Exit code 1 indicates incomplete work; exit code 0 indicates completion. Other service or storage failures stop processing and produce exit code 4. A missing references/ directory is a storage failure.

Run this command before filter-consolidated-accounts. PDF-only downloads also check consolidated_accounts/BE{enterpriseNumber}_{referenceNumber}.pdf. If filtering has moved a PDF there, later downloads and dry runs report that path as skipped. Validation continues to use the formats recorded during batch downloads; this operation does not add PDF validation records.

Filter consolidated accounts

Run validation and any required repair before filtering. Filtering moves PDFs out of their original folders. Later validation can report them as missing, and repair can download them again.

cbso-fetch filter-consolidated-accounts ./data
cbso-fetch filter-consolidated-accounts s3://my-bucket/annual-accounts

Preview the copies and moves without changing files:

cbso-fetch filter-consolidated-accounts ./data --dry-run

Dry runs print readable COPY and MOVE lines with source and destination paths. Paths are relative to the input directory shown in the first line. EXISTS, MISSING, and INVALID lines report existing output PDFs, missing PDFs, and invalid references. Dry runs read references and check file locations. They do not create directories, write files, delete files, or read PDF contents. Exit codes follow the normal filtering rules.

This command scans all JSON files beneath references/, without date or product filters. It selects the fixed model codes m120-f-p, m121-f-p, m122-f-p, and m123-f-p. It accepts camelCase and PascalCase reference fields. S3 requires the optional s3 installation and storage credentials. CBSO keys are unnecessary.

For each selected reference, the command checks pdfs/{enterpriseNumber}/{referenceNumber}.pdf. When that PDF exists, it writes these files:

consolidated_accounts/BE{enterpriseNumber}_{referenceNumber}-reference.json
consolidated_accounts/BE{enterpriseNumber}_{referenceNumber}.pdf

The reference copy preserves the original bytes. Source references remain in place. Existing output files are overwritten. The source PDF is deleted only after the output PDF is saved successfully. Processing is sequential.

If the source PDF is absent but the output PDF exists, the command treats the PDF as complete. It still refreshes the output reference. If both PDFs are absent, the reference is copied to this error path:

consolidated_accounts_errors/BE{enterpriseNumber}_{referenceNumber}-reference.json

Existing error copies remain after later successful runs. Invalid JSON, missing required fields, and unsafe identifiers appear in the report. Processing continues with other references. Storage failures stop processing. A missing references/ directory is a storage failure.

The JSON report includes planned_copies, planned_moves, copied_references, and moved_pdfs. It also includes existing_pdfs, missing_pdfs, invalid_references, and complete. Missing PDFs alone produce exit code 0. Invalid references produce exit code 1; storage failures produce exit code 4. For this command, complete means no invalid references were found. Missing PDFs do not change that value.

Use the same operation from Python:

from cbso_webservice_client import filter_consolidated_accounts

report = filter_consolidated_accounts("./data")
print(report.to_dict())

The function accepts a local path or S3 URL and returns a ConsolidatedReport. Pass dry_run=True to preview transfers from Python:

report = filter_consolidated_accounts("./data", dry_run=True)
print(report.planned_copies)
print(report.planned_moves)

planned_copies and planned_moves map source paths to destination paths. Dry runs leave copied_references and moved_pdfs empty. Normal runs leave the planned transfer mappings empty. It does not download files.

Argument order and help

Options can precede positional dates. However, --products and --formats accept multiple values and can consume dates that follow them directly. Use -- to separate trailing dates from those options.

cbso-fetch download --destination ./data --products extracts -- 2024-08-03 2024-08-04

View command descriptions and options with --help.

cbso-fetch --help
cbso-fetch download --help
cbso-fetch validate --help
cbso-fetch validate-improved --help
cbso-fetch repair --help
cbso-fetch repair-improved --help
cbso-fetch download-pdf-only-accounts --help
cbso-fetch filter-consolidated-accounts --help

Environments and logging

Production is the default CBSO environment. Use --env test with download, repair, repair-improved, or download-pdf-only-accounts to select UAT2. Both validation commands and consolidated filtering have no CBSO environment option.

cbso-fetch download 2024-08-03 \
  --products extracts \
  --destination ./test-data \
  --env test

Configure subscription keys for the selected environment. Use separate destinations for production and test data. Use the same environment when repairing a destination.

Add -v or --verbose to enable informational logging. Use cbso-fetch --version to show the installed package version.

Python package

Import operations from cbso_webservice_client. download accepts one date string or a sequence of date strings. Pass products as a sequence of strings or Product enum members. The other operations accept an input directory. validate and repair also accept selected formats. repair_improved, download_pdf_only_accounts, and filter_consolidated_accounts accept an optional dry_run=True argument.

Download from Python

from cbso_webservice_client import Product, download

report = download(
    dates=["2024-08-03", "2024-08-04"],
    products=[Product.EXTRACTS],
    destination="./data",
    formats=["json", "pdf"],
    keep_zip=True,
)

print(report.written)
print(report.unresolved)

formats defaults to JSON. keep_zip defaults to False. destination accepts a local path or an S3 URL. Use environment="test" with download, repair, repair_improved, or download_pdf_only_accounts for UAT2.

Validate and repair from Python

These functions scan stored reference files. No earlier download process or saved format selection is required.

from cbso_webservice_client import repair, repair_improved, validate, validate_improved

validation = validate("./data", formats=["xbrl", "pdf"])
print(validation.to_dict())

repaired = repair("./data", formats=["xbrl", "pdf"])
print(repaired.to_dict())

improved_validation = validate_improved("./data")
improved_repaired = repair_improved("./data")

Validation never invokes repair. Call repair only when you want to restore files.

Supply keys directly

Use a Client context to pass keys in code and reuse its HTTP connections. Non-empty keys supplied to the client take precedence over environment variables.

from cbso_webservice_client import Client, download, repair

with Client(
    keys={
        "extracts": "your-extracts-subscription-key",
        "authentic": "your-authentic-subscription-key",
    },
    environment="production",
) as client:
    downloaded = download("2024-08-03", ["extracts"], "./data", client=client)
    repaired = repair("./data", formats=["json"], client=client)

An explicitly supplied client determines the request environment. The caller owns that client; the context closes it after use. Operations that make CBSO requests create and close their own clients when none is supplied. Directory dry runs create no CBSO client and do not use a supplied client.

Reports and errors

Downloads and repairs return Report; validation also returns Report. Consolidated filtering returns ConsolidatedReport, with the fields described in its command section. Both types provide to_dict() for JSON-compatible output.

Field Meaning
planned Output paths proposed by a dry run
written Paths stored or restored during the operation
skipped Reused ZIP files or accounts already present
missing Expected files that are absent
missing_batches Batch ZIP paths awaiting publication during download
unresolved Entries or reference data that cannot be processed or filed
unavailable Requested files unavailable from the service or the reference's model
missing_keys Missing subscription keys for individual requests
complete Whether the operation has no outstanding work

complete describes the operation performed, not the entire destination. For dry runs, planned downloads do not make the report incomplete or confirm service availability. Report paths are relative to the input directory or destination. Use validate to check file presence, including files removed after an earlier download. A repair report can list a file as both missing and unavailable.

Library failures raise exceptions. These include MissingKeyError, HttpError, ValueError, storage errors, and urllib3 connection errors. Missing keys during individual repair and PDF-only requests appear in the report instead.

Completed CLI commands print a JSON report, including any incomplete work. Consolidated filtering, PDF-only downloads, and improved repair scans with --dry-run print readable text instead. The filtering command treats missing PDFs as informational; its exit behaviour is described below. Command failures write an error message to standard error.

Exit code Meaning
0 The operation completed without outstanding work.
1 Work remains incomplete, or stored data cannot be processed.
2 Command arguments are invalid.
3 A selected batch subscription key is missing.
4 A service request or storage operation failed.

Storage and repeated runs

Account and reference paths include the enterprise number and deposit number. Improved filenames also identify the improvement type.

references/0203201340/2024-123.json
jsons/0203201340/2024-123.json
pdfs/0203201340/2024-123.pdf
improved-jsons/0203201340/2024-123-aa-corrected.json
archives/extracts/2024-08-03/json.zip
pending/extracts/2024-08-03/json/2024-456.json

Commands do not read or write _state/. Existing contents can remain; they have no effect on operations. References and pending files provide the metadata needed for validation and repair.

A repeated download reuses each ZIP file that exists at its expected archive path. It extracts retained ZIP files again, restoring their references and accounts. Remove a retained ZIP file if you need to fetch that batch again from CBSO. Without --keep-zip, newly fetched ZIP files are not saved.

Before 05:00 Belgian time on the following day, HTTP 404 and empty successful responses appear under missing_batches. After that time, the downloader treats either response as an empty batch for that run. Empty responses are not saved as ZIP files. A later run requests those batches again. Non-empty invalid ZIP data remains an error. A retained invalid ZIP must be replaced before extraction can succeed.

For S3, permit object reads and writes beneath the destination prefix. Permit object deletion for pending-file recovery and consolidated PDF moves. Permit bucket listing for storage inspection and directory scans. Storage permission failures remain errors; they never count as absent files.

Development

See CONTRIBUTING.md for setup, tests, coverage, and release instructions.

Licence

Proprietary. © openthebox.

Metadata

Release files for otb-cbso-webservice-pyclient 2.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-cbso-webservice-pyclient 2.0.0
File Size Uploaded
otb_cbso_webservice_pyclient-2.0.0.tar.gz 29.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for otb-cbso-webservice-pyclient 2.0.0
File Interpreter ABI Platform
otb_cbso_webservice_pyclient-2.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 58.1 kB

Release files / otb_cbso_webservice_pyclient-2.0.0.tar.gz

Download URL otb_cbso_webservice_pyclient-2.0.0.tar.gz
Size 29.3 kB
Tags Source
SHA-256 checksum
How to use checksums
6bc68912abbb16356542357da5772e0ece9f8b9c69139aa6c620f428e1357ebb
BLAKE2b-256 checksum
How to use checksums
99c09577d3bf536c90ce75e75eaeb23baad854575670d735eb1d4b2cab395c7b
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 Sep 15, 2026.

Transparency log

Release files / otb_cbso_webservice_pyclient-2.0.0-py3-none-any.whl

Download URL otb_cbso_webservice_pyclient-2.0.0-py3-none-any.whl
Size 28.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bd1c0e5ebbc2a8fbc8f534dca281c886c9f8e0c84fe7e83f5284373c320f15ad
BLAKE2b-256 checksum
How to use checksums
1c65d573d03bd5f31d20862e7946a3c586fcbfb5f8824e5cefac1aa622c94e7f
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 Sep 15, 2026.

Transparency log

Release history Release notifications | RSS feed

2.1.1

2 release files

2.1.0

2 release files

This release

2.0.0 This release

2 release files

1.0.0

2 release files

0.1

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