Skip to main content

shab-parser

PyPI Documentation

Typed Python client for the Swiss Official Gazette of Commerce (SHAB/SOGC/FUSC).

Fetches publications from the Amtsblattportal public API, parses the XML into dataclasses, and classifies each publication into eleven structured event types — incorporation, branch creation, seat move, address change, rename, purpose change, capital increase, merger, officer change, liquidation, deletion.

Built and maintained by Prospex, a Swiss B2B sales intelligence platform.

Install

pip install shab-parser

To use the HTTP client (for fetching from the live API):

pip install shab-parser[http]

Quick start

Parse XML you already have

from shab_parser import parse_xml

with open("publication.xml", "rb") as f:
    pub = parse_xml(f.read())

print(pub.company_name)  # "Alpenblick Handel AG"
print(pub.uid)           # "CHE-123.456.789"
print(pub.canton)        # "ZH"

for event in pub.events:
    print(event.event_type, event.effective_date, event.payload)

Fetch and parse from the API

from datetime import date
from shab_parser.client import ShabClient
from shab_parser import parse

with ShabClient() as client:
    refs = client.discover(date(2026, 6, 15), date(2026, 6, 15))

    for ref in refs[:5]:
        raw = client.fetch(ref)
        pub = parse(raw)
        print(f"{pub.company_name}: {[e.event_type.value for e in pub.events]}")

The client rate-limits itself to one request per second and retries transient failures with exponential backoff.

Event types

The parser classifies each publication into one or more of eleven events:

Event Sub-rubric Trigger
INCORPORATION HR01 <registration>true</registration>
BRANCH_CREATED HR01 A branch designation in the publication text
SEAT_MOVED HR02 Different seat in commonsNew vs. commonsActual
ADDRESS_CHANGED HR02 <addressChanged>true</addressChanged>
NAME_CHANGED HR02 Different company name in commonsNew vs. commonsActual
PURPOSE_CHANGED HR02 Different purpose in commonsNew vs. commonsActual
CAPITAL_INCREASED HR02 Structured nominal comparison, phrase fallback
MERGER any A merger clause in the publication text
OFFICERS_CHANGED HR02 A person block in the text that mutates an office
LIQUIDATION any Dissolution flags or "in Liquidation" added to name
DELETED HR03 <delete> block with deletion date

Events come back in the order above, also available as shab_parser.TAXONOMY_ORDER.

Seven of the eleven come from machine-readable XML fields. Four do not: the register has no flag for a branch creation, a merger or an officer change, and states them only in the publication's prose.

Text extractors

shab_parser.extractors holds the free-text extractors behind those four types. Each is language-aware across German, French and Italian, returns a plain dict, and works standalone — useful for mining a corpus of publication text where the structured XML was never kept.

from shab_parser.extractors import extract_merger

text = ("Fusion: reprise des actifs et passifs de First SA, à Nyon "
        "(CHE-106.145.608), selon contrat de fusion du 28.11.2025.")

extract_merger(text, "fr")
# {'extractor_version': 'shab-merger/1.0.0',
#  'transactions': [{'direction': 'absorbing',
#                    'counterparty_name': 'First SA', ...}]}
Module Reads
extractors.branches Branch registrations, and the foreign head office behind them
extractors.mergers Mergers, plus FusG asset transfers and demergers
extractors.persons Officers appointed, resigned, or with changed signature rights
extractors.purposes The new statutory purpose
extractors.renames The old and new firm, and the marker that makes it a rename

Data model

parse() and parse_xml() return a Publication dataclass:

@dataclass(frozen=True)
class Publication:
    external_id: str
    publication_date: date
    language: str          # "de", "fr", or "it"
    source_url: str
    company_name: str
    raw_text: str
    sub_rubric: str        # "HR01", "HR02", or "HR03"
    effective_date: date | None
    canton: str | None
    uid: str | None        # CHE-xxx.xxx.xxx
    legal_form_code: str | None
    publication_state: str # "PUBLISHED" or "CANCELLED"
    events: list[Event]
    company_new: Company | None
    company_actual: Company | None
    capital_new: float | None
    capital_actual: float | None

API reference

shab_parser.parse(raw: RawResponse) -> Publication

Parse a RawResponse (as returned by ShabClient.fetch()) into a Publication.

shab_parser.parse_xml(xml_bytes, *, source_url="", ref_state=None) -> Publication

Parse raw XML bytes directly. Use this when you already have the XML and don't need the HTTP client.

shab_parser.client.ShabClient

HTTP client for the Amtsblattportal API. Requires the http extra.

  • discover(start, end) lists all HR publications in a date range. Queries both PUBLISHED and CANCELLED states, deduplicating by external ID.
  • fetch(ref) downloads one publication's full XML.

shab_parser.client.parse_bulk_export(xml_bytes) -> (list[PublicationRef], int)

Parse a bulk-export list page into publication references and a total count. Useful if you handle pagination yourself.

shab_parser.extractors

The free-text extractors. See the table above and the documentation.

Background

SHAB (Schweizerisches Handelsamtsblatt) is the official gazette where Swiss commercial register entries are published. Every new company, every seat change, every capital increase, every deletion passes through it. The same publication appears in German, French, and Italian, each under a different namespace (HR01:, HR02:, HR03:), but with identical XML structure.

This library handles the namespace differences transparently using ElementPath's {*} wildcard, so you get the same parsed output regardless of language.

License

MIT

Metadata

Release files for shab-parser 0.2.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 shab-parser 0.2.0
File Size Uploaded Provenance
shab_parser-0.2.0.tar.gz 58.9 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for shab-parser 0.2.0
File Interpreter ABI Platform
shab_parser-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 126.2 kB

Release files / shab_parser-0.2.0.tar.gz

Download URL shab_parser-0.2.0.tar.gz
Size 58.9 kB
Tags Source
SHA-256 checksum
How to use checksums
4318de2c7fbbc4bc761f69f5f0521d7835190d8234abc8bfe1a000cdc1920a46
BLAKE2b-256 checksum
How to use checksums
a4833230f6ba7d323fc7c4b73b1391a4237dbf3aa8d65931dccac2bc0b46b7db
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.32 {"installer":{"name":"uv","version":"0.11.32","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / shab_parser-0.2.0-py3-none-any.whl

Download URL shab_parser-0.2.0-py3-none-any.whl
Size 67.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6805beb907ecc284d3d5889542ca17d42387eb06e1a80f02052f6ca6e5d0eac0
BLAKE2b-256 checksum
How to use checksums
a9d935b7d77407fa282a0b76e1dfae67997d1d1ba917f6d8183c41377a067cf2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.32 {"installer":{"name":"uv","version":"0.11.32","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for shab-parser 0.2.0

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files No provenance

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