CLI tool to fetch, archive, process and explore GTFS-RT data
Project description
gtfs-cli
CLI tool to fetch, process, and explore GTFS transit data — both realtime (GTFS-RT) and static schedules. Follows Unix philosophy: each command does one thing and writes to stdout, composing naturally with tools like curl, unzip, and jq.
Note:
gtfs-cliis in active development. All0.x.xreleases are subject to breaking changes.
Goal
To become a Swiss Army knife CLI for working with public transit open data — GTFS static schedules, GTFS-RT real-time feeds, bike share data, and more.
Installation
uv tool install gtfs-cli
After installation, the gtfs-cli command is available globally.
Commands
static info
Inspect a static GTFS feed (a folder of .txt files). Shows agency, valid dates, feed age, stop/route/trip counts, route types, service days, and file inventory.
# Download and unzip a feed, then inspect it
curl -L "https://ckan0.cf.opendata.inter.prod-toronto.ca/dataset/7795b45e-e65a-4465-81fc-c36b9dfff169/resource/cfb6b2b8-6191-41e3-bda1-b175c51148cb/download/TTC%20Routes%20and%20Schedules%20Data.zip" -o ttc.zip
unzip ttc.zip -d ttc/
gtfs-cli static info ttc/
# Inspect the current directory
gtfs-cli static info
Example output:
Agency TTC
Timezone America/Toronto
Language en
Valid 2026-05-03 → 2026-06-06 (34 days)
Feed age 9 days · expires in 25 days
Stops 9,378
Routes 232
Trips 134,882
Stop times 4,261,259
Shapes 434,460 points across 1,550 shapes
Route types
Bus 210
Tram / Light Rail 19
Subway / Metro 3
Service days
Mon Tue Wed Thu Fri Sat Sun
Files
Required agency stops routes trips stop_times calendar
Optional shapes calendar_dates
Missing feed_info frequencies transfers fare_attributes fare_rules
Largest files
stop_times.txt 203 MB 4,261,259 rows
shapes.txt 18 MB 434,460 rows
trips.txt 12 MB 134,882 rows
For all available options, run:
gtfs-cli static info --help
fetch
Fetch a GTFS-RT feed from a URL or local file and output it as JSON.
Example output:
{
"header": {
"gtfs_realtime_version": "2.0",
"incrementality": "FULL_DATASET",
"timestamp": "1778642963"
},
"entity": [
{
"id": "1",
"trip_update": {
"trip": {
"trip_id": "39051020",
"route_id": "73",
"schedule_relationship": "SCHEDULED"
},
"stop_time_update": [
{
"stop_sequence": 31,
"arrival": { "time": "1778642961" },
"stop_id": "1732",
"schedule_relationship": "SCHEDULED"
}
]
}
}
]
}
# Fetch live trip updates
gtfs-cli fetch "https://gtfsrt.ttc.ca/trips/update?format=binary"
# Fetch vehicle positions
gtfs-cli fetch "https://gtfsrt.ttc.ca/vehicles/position?format=binary"
# Fetch service alerts
gtfs-cli fetch "https://gtfsrt.ttc.ca/alerts/all?format=binary"
# Inspect a previously saved .pb file
gtfs-cli fetch trips.pb
Filtering with jq:
# List all active alerts
gtfs-cli fetch "https://gtfsrt.ttc.ca/alerts/all?format=binary" | jq '.entity[] | .alert'
# Count entities in a feed
gtfs-cli fetch "https://gtfsrt.ttc.ca/trips/update?format=binary" | jq '.entity | length'
# Extract all trip IDs
gtfs-cli fetch "https://gtfsrt.ttc.ca/trips/update?format=binary" \
| jq '[.entity[].trip_update.trip.trip_id]'
Watch mode — continuously poll a feed and stream NDJSON (one JSON object per line):
# Poll every 30 seconds
gtfs-cli fetch --watch 30 "https://gtfsrt.ttc.ca/trips/update?format=binary"
# Count entities on each snapshot
gtfs-cli fetch --watch 30 "https://gtfsrt.ttc.ca/trips/update?format=binary" \
| jq --unbuffered '.entity | length'
# Save a long-running collection to a file
gtfs-cli fetch --watch 30 "https://gtfsrt.ttc.ca/trips/update?format=binary" \
>> snapshots.ndjson
Watch mode handles transient failures gracefully: HTTP and network errors are retried with exponential backoff (1s → 2s → 4s … capped at 60s). Stop with Ctrl+C or SIGTERM.
For all available options, run:
gtfs-cli fetch --help
Development
# Install dependencies
uv sync
# Run a command
uv run gtfs-cli fetch "https://gtfsrt.ttc.ca/trips/update?format=binary"
# Run tests
uv run pytest tests/ -v
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gtfs_cli-0.3.0.tar.gz.
File metadata
- Download URL: gtfs_cli-0.3.0.tar.gz
- Upload date:
- Size: 485.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fc32f5c545a02fad95dfab9aa182a47d87accfe020dcf24e32a369024c723cf7
|
|
| MD5 |
64decbc079ed9ca604f5da1d1e49ecb0
|
|
| BLAKE2b-256 |
848f9073f97f7efdc6222f2dcea26f21cf4fbe0e7e774a7f77facb55836ca40a
|
File details
Details for the file gtfs_cli-0.3.0-py3-none-any.whl.
File metadata
- Download URL: gtfs_cli-0.3.0-py3-none-any.whl
- Upload date:
- Size: 11.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4566e32a4ee2b81fffa0483b5b892ca77d44499f18cc7c7f759093e4a67e04c4
|
|
| MD5 |
0e6eda4755191a7c9418731d40641553
|
|
| BLAKE2b-256 |
6d8ed7bc5556ec40e0f201100465361a2b3495fc987ac6c68fe2cd0fc7a4bb80
|