Skip to main content

transitio

AOI-driven OSM and GTFS acquisition, validation and repair — companion to pyrosm and cafein. transitio moves the raw ingredients of routing — OSM extracts and GTFS timetables — from the open data ecosystem to your area of interest, validated and repaired, ready for cafein to brew into routing results.

Status: early development. Acquisition (Mobility Database catalog, the feed index + OSM extracts), GTFS validation, repair and cropping are in place, tied together by the one-call transitio.fetch pipeline.

The feed index that transitio.index reads is built in a separate repository, transitio-dev/transitio-index.

Quick example

import transitio

# One call: OSM extract + validated GTFS feeds for an area of interest.
result = transitio.fetch(helsinki_polygon)        # any shapely geometry,
                                                   # bbox tuple or place name
result.osm_pbf     # cropped OSM extract (path)
result.feeds       # downloaded, cropped and validated GTFS feeds (paths)
result.reports     # per-feed merged validation reports
result.skipped     # (feed id, reason) for anything left out

net = result.to_cafein()   # routable cafein.TransportNetwork
osm = result.to_pyrosm()   # pyrosm.OSM reader over the extract

fetch shows its progress on stderr, a bar per download (a widget in Jupyter with pip install "transitio[notebook]", which adds ipywidgets); progress=False turns it off.

fetch accepts when="2026-09-01" to pick the dataset versions covering a service day (needs a free Mobility Database API token, passed as refresh_token= or via the MOBILITY_API_REFRESH_TOKEN environment variable), modes=["rail", "tram"] to keep only feeds serving given modes, repair=True to repair feeds after the crop, osm=False to skip the OSM extract when only the timetables are needed, and crop=False to keep feeds whole. With a token, GTFS downloads are catalogued dataset versions verified against catalog checksums; without one, the latest hosted zips are fetched as-is — unverified moving targets.

With the feed index installed (below), fetch takes the feeds of the index places that cover the area, when they cover at least half of its land, and result.places lists those places. Otherwise it searches the Mobility Database catalogue for feeds whose bounding box meets the area's, and a warning gives the reason and the number of feeds before anything is downloaded; index=False searches the catalogue without the index or a warning.

Feeds for a place

The feed index lists the feeds serving each place, by the tier of service they run there: local, regional, national or international. Install it once, then fetch a place's feeds by tier:

import transitio

transitio.index.refresh()            # once: install the newest feed index

augsburg = transitio.place("Augsburg")
result = transitio.fetch(
    place=augsburg,
    tiers=["local", "regional"],     # leave out long-distance services
    osm=False,                       # timetables only
)
transitio.merge_feeds(result.feeds, "augsburg.gtfs.zip", check=False)

The first refresh downloads about 420 MB (about 35 s at 100 Mbit/s, 3 minutes at 20 Mbit/s) and takes about 10 s more to unpack and check it; it prints its progress to stderr unless called with progress=False. A snapshot takes about 550 MB on disk, and the cache keeps the newest three plus a pinned one, up to about 2.2 GB; a refresh needs about 1 GB free while it runs.

Each feed is cropped to the place's boundary; a national feed such as Germany's is streamed through the crop, so it fits in memory bounded by the area. merge_feeds writes one feed from the cropped ones; with check=False it keeps the file when the validator reports errors, which the returned report lists. A bare name resolves to the city before the metros named after it. Where different places share a name and none clearly leads, as for London in the UK and in Canada, place raises AmbiguousPlaceError; a qualifier names the region or country that holds the place, as in "London, Ontario" or "City of London, UK", kind="city" (or "metro", "region", "country") restricts the scope, and a Wikidata id picks one place. A metro delineated under several definitions resolves to one of them, by the order functional urban area, metropolitan statistical area, metropolitan region, FAO city-region, though a city's own metros (those in its country) keep every definition; definition= names one instead. A partial name raises PlaceNotFoundError, which lists the places it partly matches; transitio.suggest completes names.

Inferring missing route shapes

Many feeds ship without shapes.txt, leaving every consumer to draw straight lines between stops. infer_shapes fills that gap from an OSM extract — matching OSM route relations where they exist, map matching over tram, rail and bus-drivable networks where they do not — and writes a feed carrying real alignments:

report = transitio.infer_shapes(
    "feed.zip", "shaped.zip", pbf, strictness="strict"
)
report["written"]     # shapes written
report["shapes"]      # per shape: method, matched OSM relation, score
report["skipped"]     # per refused pattern: the stage that refused it

How much inference is acceptable is yours to choose. "strict" (the default) writes only unambiguous matches; "relaxed" and "permissive" trade certainty for coverage, which is the trade worth making where a feed has no shapes at all and the alternative is a straight line. Every shape is validated against the pattern's own stops before it is written — each stop must lie on the alignment, in order — so no level writes a shape the feed's own data contradicts.

On the Helsinki tram fixture with the feed's shapes withheld, the levels measured (scripts/validate_shapes.py):

level shapes written median length error worst offset
strict 35/80 0.9% 42 m
relaxed 40/80 0.9% 34 m
permissive 43/80 0.9% 184 m

Helsinki's OSM data is unusually good; expect a worse trade where it is not, and keep the report.

Lower-level access

Each pipeline stage is available on its own:

db = transitio.MobilityDatabase()

feeds = db.search_feeds(aoi=helsinki_polygon)
dataset = db.dataset_for(feeds[0], when="2026-09-01")
path = db.download(dataset)                        # cached, checksum-verified
report = db.validation_report(dataset)             # hosted canonical-validator report

pbf = transitio.fetch_pbf(helsinki_polygon)       # cropped OSM extract
validation = transitio.validate_feed(path)        # canonical-code notices
transitio.repair_feed(path, "repaired.zip")       # gtfstidy-contract repair
transitio.crop_feed(path, "cropped.zip", aoi=helsinki_polygon)

Documentation

The Sphinx site lives in docs/. Building it needs transitio itself installed (autodoc imports the real package) plus the Sphinx toolchain:

pip install . -r docs/requirements.txt
sphinx-build -b html docs docs/_build/html

The hosted version lives at https://transitio.readthedocs.io.

Installation

pip install transitio

Binary wheels cover Linux, macOS and Windows. Building from source instead requires a Rust toolchain (pip install .). pip install "transitio[notebook]" also installs ipywidgets, so the download progress bars show as widgets in Jupyter.

License

MIT

Metadata

Release files for transitio 0.21.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 transitio 0.21.0
File Size Uploaded
transitio-0.21.0.tar.gz 384.5 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for transitio 0.21.0
File
transitio-0.21.0-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details
transitio-0.21.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.10 abi3 Linux glibc 2.17+ x86-64 Details
transitio-0.21.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.10 abi3 Linux glibc 2.17+ ARM64 Details
transitio-0.21.0-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details
transitio-0.21.0-cp310-abi3-macosx_10_12_x86_64.whl CPython 3.10 abi3 macOS 10.12+ x86-64 Details

Total release size: 9.0 MB

Release files / transitio-0.21.0.tar.gz

Download URL transitio-0.21.0.tar.gz
Size 384.5 kB
Tags Source
SHA-256 checksum
How to use checksums
e36e878f230ae27ca20f9627402217993f519d65176737e3aa4e47565db9d1e6
BLAKE2b-256 checksum
How to use checksums
bdaa687369c58225854dcc61e1c0e48a283b64d1379af46d11b537941b15bfa0
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 Oct 7, 2026.

Transparency log

Release files / transitio-0.21.0-cp310-abi3-win_amd64.whl

Download URL transitio-0.21.0-cp310-abi3-win_amd64.whl
Size 1.6 MB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
850e03a6d8df27dd0585c5d4795c27bbab1a496ed33caf1ccbe0800b0731d3c2
BLAKE2b-256 checksum
How to use checksums
7692b8eb8f47a21ad51ded68dbc89292233f77aa39bd67f83ff1f4a4f4e7b02a
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 Oct 7, 2026.

Transparency log

Release files / transitio-0.21.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL transitio-0.21.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 1.8 MB
Tags CPython 3.10 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
e1162e41358aec9c24513620b4bbd513659f9b36251ee6ae5a963b5ad9d4ca6a
BLAKE2b-256 checksum
How to use checksums
4df7f590c2ee77adef58424887d94301afeca1a05e8134a861f76de234ee9a0a
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 Oct 7, 2026.

Transparency log

Release files / transitio-0.21.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL transitio-0.21.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 1.8 MB
Tags CPython 3.10 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
ed9506b5f054d9ca209925636a5a6e36f1a1abda066c185a91450a87afbb9af1
BLAKE2b-256 checksum
How to use checksums
faae39998f0c62293e417a976d701e280720334ee8b7eec0198f1a1035ee7b1b
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 Oct 7, 2026.

Transparency log

Release files / transitio-0.21.0-cp310-abi3-macosx_11_0_arm64.whl

Download URL transitio-0.21.0-cp310-abi3-macosx_11_0_arm64.whl
Size 1.6 MB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
8f2340e08d3a81e1f5c9b5fde6f34c6c3667274f16774972c0d6581742eeb62f
BLAKE2b-256 checksum
How to use checksums
94bf79128d429f4120c2ea99e57fb83cb3c9241b7128130100c173a92be1fc27
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 Oct 7, 2026.

Transparency log

Release files / transitio-0.21.0-cp310-abi3-macosx_10_12_x86_64.whl

Download URL transitio-0.21.0-cp310-abi3-macosx_10_12_x86_64.whl
Size 1.8 MB
Tags CPython 3.10 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
5e70154f1927c38fb78c23f439d62409472b1d063851e3111a06b1832ec6113c
BLAKE2b-256 checksum
How to use checksums
d993052ae3b7b2497de1c8309efe96de8d4161b275d1b041d66d0f4dd89c0336
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 Oct 7, 2026.

Transparency log
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