Skip to main content

zeitwide

Is this a business day, and what is the next one? Answers for payment rails (Fedwire, FedACH, FedNow, T2, CHAPS) and public holiday calendars, each with the entry that decided it and the official sources behind it.

pip install zeitwide            # needs only httpx
pip install "zeitwide[mcp]"     # adds the local MCP server

Offline

ZeitWide() answers from the dataset release bundled with the library. It never touches the network, and it passes the same conformance suite as the hosted API.

from datetime import date
from zeitwide import ZeitWide

zw = ZeitWide()
zw.is_business_day("US-FEDWIRE", date(2026, 11, 26)).is_business_day  # False
answer = zw.next_business_day(["US-FEDWIRE", "EU-T2"], date(2026, 11, 25))
answer.date, [day.date for day in answer.skipped]  # 2026-11-27, [2026-11-26]
zw.add_business_days("GB-CHAPS", date(2026, 12, 24), 2).date  # 2026-12-30
zw.explain_date("US-FEDWIRE", date(2026, 11, 26)).calendars[0].reason  # 'Thanksgiving Day'
zw.list_closures("EU-T2", date(2026, 1, 1), date(2026, 12, 31)).closures

Every answer names its dataset_release, the calendar_revisions it used and the as_of instant it answers for. Pass as_of= to ask what Zeitwide had recorded at an earlier moment. A date outside a calendar's published coverage raises OutOfRangeError: the library never guesses. combine="any_open" asks whether at least one calendar is open instead of all of them.

Online

With an API key (free from the Zeitwide app), the same calls ask the hosted API. They return the same types, with the latest data, as_of back to the first recorded version, and a signed receipt with every answer.

with ZeitWide(key="zw_live_…") as zw:
    answer = zw.is_business_day("US-FEDWIRE", date(2026, 11, 26))
    answer.receipt.id  # 'rcpt_…'

The online types come from api/openapi.yaml through the generated zeitwide.api_types (make generate-clients; never edit them by hand).

Receipts

Check a receipt offline: its hash, ID, Ed25519 signature, and that its key was valid when it was issued. The public keys are a bundled copy of /.well-known/zeitwide-keys.json (--keys or KeyRing.parse(...) to use a newer ring).

zeitwide verify answer.json      # a receipt, or an answer that carries one; '-' for stdin
from zeitwide import verify_receipt

verify_receipt(answer.receipt)  # Verification(valid=True, …), falsy when invalid

Webhooks

from zeitwide import webhooks

event = webhooks.verify(request.body, request.headers["Zeitwide-Signature"], secret)

It checks the HMAC-SHA256 signature over the raw body and refuses deliveries signed more than five minutes from now. It returns the event only once verified, and raises WebhookVerificationError otherwise.

Local MCP server

uvx zeitwide-mcp --offline

--offline answers from the bundled release. Without it, the server asks the hosted API with the key in ZEITWIDE_API_KEY. With the library installed, zeitwide mcp --offline runs the same server. In an MCP client:

{ "mcpServers": { "zeitwide": { "command": "uvx", "args": ["zeitwide-mcp", "--offline"] } } }

Tools: is_business_day, next_business_day, add_business_days, explain_date and list_closures, with the same names, arguments and answers as the hosted server at /mcp (offline answers have no receipt), plus verify_webhook.

Licenses

The code is MIT (LICENSE). The bundled dataset is under CC BY-NC 4.0 (LICENSE-DATA); commercial use of the data needs the hosted API or a separate agreement.

Development

uv sync --all-packages
uv run python -m ruff format . && uv run python -m ruff check .
uv run python -m mypy
uv run python -m pytest --cov

The bundled release in src/zeitwide/data/releases/ must be the newest file in dataset/releases/ (a test checks); copy a new release there when one is cut. The zeitwide-mcp/ folder is a launcher package so uvx zeitwide-mcp works; keep its version in step. Tag lib-python-v<version> to publish both to PyPI (.github/workflows/publish-lib-python.yml). The library supports Python 3.12 and later, and CI tests 3.12, 3.13 and 3.14.

Metadata

Release files for zeitwide 0.1.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 zeitwide 0.1.0
File Size Uploaded Provenance Actions
zeitwide-0.1.0.tar.gz 36.0 kB Without provenance Details for zeitwide-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for zeitwide 0.1.0
File Interpreter ABI Platform Actions
zeitwide-0.1.0-py3-none-any.whl Python 3 none any Details for zeitwide-0.1.0-py3-none-any.whl

Total release size: 77.7 kB

Release files / zeitwide-0.1.0.tar.gz

Download URL zeitwide-0.1.0.tar.gz
Size 36.0 kB
Tags Source
SHA-256 checksum
How to use checksums
bbfda83b1eb7eb1075e2b147b193c2a5a7b6f2136784d028ccfc12d50d44ecff
BLAKE2b-256 checksum
How to use checksums
1817bcb49d57b78b1e1168cadc0c42e6b238ca3d77797254e88896fd008d3f7b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.6 {"installer":{"name":"uv","version":"0.13.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / zeitwide-0.1.0-py3-none-any.whl

Download URL zeitwide-0.1.0-py3-none-any.whl
Size 41.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e6513bc8afc67c88f2a417711762c8be3bbc285f93a1eaca67fc8293148048f9
BLAKE2b-256 checksum
How to use checksums
c278b95523cc87478209a48a647ec9be08a4cc68b886badda8ad911c650e5cbb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.6 {"installer":{"name":"uv","version":"0.13.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for zeitwide 0.1.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.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.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