This release is a pre-release and may not be stable for production use.
xtransit
Collect public transit data, keep its history, and explore it on a map.
xtransit brings together GTFS schedules (routes, stops, and timetables) and GTFS Realtime feeds (vehicle positions, arrival updates, and alerts). It finds feeds in the MobilityDatabase catalog, saves them to PostgreSQL, and provides a small web app for viewing routes and following vehicles across multiple networks.
This is an early alpha. It is useful for local exploration and building a transit dataset; commands and database schemas may change between releases.
What you can do
- Download public schedules and realtime snapshots for selected networks or the U.S.
- Keep collecting arrivals and vehicle positions, with recovery after interrupted imports.
- View routes, stops, current vehicle positions, and recorded trails on a map.
- Select several networks at once, including networks that overlap the visible map.
- Query the collected history with SQL or Python.
Get started
You need Python 3.9+, curl, and a running Docker daemon or a Podman Docker-compatible socket. PostgreSQL runs in a container that xtransit creates and reuses. The download-only commands do not need a database.
Install the first alpha in a virtual environment:
python3 -m venv .venv
source .venv/bin/activate
python -m pip install "xtransit[data,web]==0.1.0a1"
The commands here use a macOS/Linux shell. Run the following steps from the same
directory; downloads and capture files are saved under data/ there.
1. Download a small network
Start with Arlington Transit in Virginia. This downloads its schedule, arrival updates, and vehicle positions:
xtransit --feed-id mdb-485 --feed-id mdb-1372 --feed-id mdb-1790
These are catalog feed IDs, not route numbers. To find other feeds, run
xtransit --catalog-only and browse data/us/catalog.csv.
2. Start the database and import the downloads
xtransit-db
xtransit-ingest import-files
The database command creates or reuses a local PostgreSQL instance and checks the connection. Importing the same files again is safe.
3. Open the map and keep collecting
xtransit-web --poll-feed mdb-1790 --poll-feed mdb-1372
Open http://127.0.0.1:8000. Leave the terminal running to keep collecting new positions and arrival updates. Press Ctrl+C to stop the web app and its pollers; the database and collected history remain available.
The app polls these feeds every 30 seconds and refreshes the map every 15 seconds.
Vehicles appear when the agency is publishing positions; an empty map can mean
there is no current service. Check xtransit-ingest status if imports failed.
Explore the map
Open Your networks to search for and select multiple networks. Click a route to see its path, or a vehicle to view its latest observation and a 1-, 6-, or 24-hour trail. Network stops adds stops from the selected networks.
To select networks geographically, pan or zoom and click Select networks in view. A network only needs to overlap the map; it does not need to fit entirely inside it. In map area only filters the network picker as you move the map. Coverage comes from catalog bounding boxes, so a match does not guarantee a route passes through every part of the visible area.
Fresh only shows positions observed within the past 90 seconds. Older positions appear in amber. Trails contain the observations you have collected; they do not reconstruct trips from before collection began.
The API documentation is available at http://127.0.0.1:8000/docs.
Common commands
| Task | Command |
|---|---|
| List available U.S. feeds | xtransit --catalog-only |
| Download one schedule | xtransit --kind schedule --feed-id mdb-485 |
| Refresh that schedule | xtransit --kind schedule --feed-id mdb-485 --refresh |
| Import saved downloads | xtransit-ingest import-files |
| Check imports and errors | xtransit-ingest status |
| Recover pending captures | xtransit-ingest replay |
| Open the map without polling | xtransit-web |
To keep collecting separately from the web app:
xtransit-ingest poll --feed-id mdb-1372 --feed-id mdb-1790 --cycles 0
Without --cycles 0, polling runs once. Use --help on the collector, importer,
or web command for more options.
Collect more networks
Repeat --feed-id to add feeds. Include a network's schedule and its corresponding
realtime feeds so the map can connect vehicle observations to routes.
For a nationwide collection, the following downloads public feeds, imports them, and then continuously polls the available realtime feeds:
xtransit
xtransit-ingest import-files
xtransit-ingest --workers 8 poll --cycles 0
Start small if you are trying the project for the first time. Nationwide schedules can occupy tens of gigabytes after import, and realtime history keeps growing. This version retains history and capture files indefinitely; it does not automatically archive or delete old data.
Data coverage and reliability
xtransit uses the public MobilityDatabase catalog.
U.S. collection covers active catalog entries marked US, not every transit
operator. Feeds requiring agency credentials are reported rather than fetched;
public schedule mirrors may still be available.
Realtime means the latest observation the agency published and we successfully collected. It is not a continuous GPS stream. Agency delays, outages, and the polling interval all affect freshness.
The importer saves captured responses before processing them, deduplicates repeated data, and updates the current snapshot only after an import succeeds. Failed imports can be replayed; invalid feeds are retained for inspection. Polling cannot recover observations that an agency replaced between requests. Back up the database and capture files if you need to protect against disk loss.
Where the data lives
| Location | Contents |
|---|---|
data/us/ |
Feed catalog, downloaded schedules, snapshots, and run reports |
data/ingest-spool/ |
Durable captures used to recover interrupted imports |
~/.xtransit/postgres.json |
Local database settings and generated credentials |
~/.xtransit/postgresql/ |
Persistent PostgreSQL data |
Set XT_HOME before starting xtransit to change the database storage location.
The default database port is 127.0.0.1:55432.
See the operations guide for SQL examples, database configuration, polling behavior, and recovery details.
Development
git clone https://github.com/ysenarath/xtransit.git
cd xtransit
uv sync --extra data --extra web
uv run --extra data --extra web python -m unittest discover -s tests -v
node --test tests/web_networks.test.mjs
Node.js 18+ is needed only for the frontend tests. To run the database integration tests too, start Docker or Podman and use:
XTRANSIT_TEST_DATABASE=1 uv run --extra data --extra web python -m unittest discover -s tests -v
Bug reports and contributions are welcome through GitHub issues.
License and attribution
xtransit's code is MIT licensed. Bundled Leaflet assets retain their BSD 2-Clause license. Transit feeds keep their providers' own licenses; see the catalog for each feed's terms.
Map tiles come from OpenStreetMap and need an internet connection. Follow the OpenStreetMap tile usage policy when deploying a public viewer.
Metadata
Release files for xtransit 0.1.0a1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| xtransit-0.1.0a1.tar.gz | 209.5 kB | Without provenance | Details for xtransit-0.1.0a1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| xtransit-0.1.0a1-py3-none-any.whl | Python 3 | none | any | Details for xtransit-0.1.0a1-py3-none-any.whl |
Total release size: 330.6 kB
Release files / xtransit-0.1.0a1.tar.gz
| Download URL | xtransit-0.1.0a1.tar.gz |
|---|---|
| Size | 209.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
83dcb1e0aa2a01a411153c6a84f326a9071b784d70333f1dd6dbcf08f27f0181
|
|
BLAKE2b-256 checksum How to use checksums |
202592e317c2913e8207e1cdf71219f7c1c11acd8b1d30ff65fc2d2bc235c751
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / xtransit-0.1.0a1-py3-none-any.whl
| Download URL | xtransit-0.1.0a1-py3-none-any.whl |
|---|---|
| Size | 121.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3736dfb004be4af3fbf5537721ff9201c051368e5aa49050ebe8f515a26a130c
|
|
BLAKE2b-256 checksum How to use checksums |
1dc258ad01ad57160290a503807367d0a063abc11dec2e84cb448f8de3a5d1dd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for xtransit 0.1.0a1
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.