GTFS Guru Python
High-performance GTFS feed validator with Python bindings. Written in Rust, exposed via PyO3.
Installation
pip install gtfs-guru
From Source
pip install maturin
maturin build --release
pip install target/wheels/gtfs_guru-*.whl
Quick Start
import gtfs_guru
# Validate a GTFS feed
result = gtfs_guru.validate("/path/to/gtfs.zip")
print(f"Valid: {result.is_valid}")
print(f"Errors: {result.error_count}")
print(f"Warnings: {result.warning_count}")
# Print errors
for error in result.errors():
print(f"{error.code}: {error.message}")
API Reference
Functions
validate(path, country_code=None, date=None) -> ValidationResult
Validate a GTFS feed.
Parameters:
path(str): Path to GTFS zip file or directorycountry_code(str, optional): ISO country code (e.g., "US", "RU")date(str, optional): Validation date in YYYY-MM-DD format
Returns: ValidationResult object
Example:
result = gtfs_guru.validate(
"/path/to/gtfs.zip",
country_code="US",
date="2025-01-15"
)
async validate_async(path, country_code=None, date=None, on_progress=None) -> ValidationResult
Validate a GTFS feed asynchronously (non-blocking).
Parameters:
path(str): Path to GTFS zip file or directorycountry_code(str, optional): ISO country codedate(str, optional): Validation date in YYYY-MM-DD formaton_progress(Callable[[ProgressInfo], None], optional): Callback for progress updates
Example:
import asyncio
async def main():
def on_progress(info):
print(f"{info.stage}: {info.current}/{info.total}")
result = await gtfs_guru.validate_async(
"/path/to/gtfs.zip",
on_progress=on_progress
)
asyncio.run(main())
version() -> str
Get validator version.
>>> gtfs_guru.version()
'1.0.0'
notice_codes() -> list[str]
Get list of all available notice codes.
>>> len(gtfs_guru.notice_codes())
190
>>> gtfs_guru.notice_codes()[:3]
['attribution_without_role', 'bidirectional_exit_gate', 'block_trips_with_overlapping_stop_times']
notice_schema() -> dict
Get schema for all notice types with descriptions and severity levels.
>>> schema = gtfs_guru.notice_schema()
>>> schema['missing_required_field']
{'severity': 'ERROR', 'description': '...'}
Classes
ValidationResult
Result of GTFS validation.
Attributes:
| Attribute | Type | Description |
|---|---|---|
is_valid |
bool |
True if no errors |
error_count |
int |
Number of errors |
warning_count |
int |
Number of warnings |
info_count |
int |
Number of info notices |
validation_time_seconds |
float |
Validation time in seconds |
notices |
list[Notice] |
All validation notices |
Methods:
# Get notices by severity
errors = result.errors() # List[Notice]
warnings = result.warnings() # List[Notice]
infos = result.infos() # List[Notice]
# Filter by notice code
notices = result.by_code("missing_required_field") # List[Notice]
# Export
result.save_json("/path/to/report.json")
result.save_html("/path/to/report.html")
json_str = result.to_json() # str
report = result.to_dict() # dict
Notice
A single validation notice.
Attributes:
| Attribute | Type | Description |
|---|---|---|
code |
str |
Notice code (e.g., "missing_required_field") |
severity |
str |
"ERROR", "WARNING", or "INFO" |
message |
str |
Human-readable message |
file |
str | None |
GTFS filename |
row |
int | None |
CSV row number |
field |
str | None |
Field name |
Methods:
# Get context field
value = notice.get("fieldName") # Any | None
# Get all context
ctx = notice.context() # dict[str, Any]
Examples
Basic Validation
import gtfs_guru
result = gtfs_guru.validate("/path/to/gtfs.zip")
if result.is_valid:
print("Feed is valid!")
else:
print(f"Found {result.error_count} errors")
for error in result.errors():
print(f" - {error.code}: {error.message}")
Detailed Analysis
from collections import Counter
result = gtfs_guru.validate("/path/to/gtfs.zip")
# Count notices by code
error_counts = Counter(e.code for e in result.errors())
for code, count in error_counts.most_common(10):
print(f"{code}: {count}")
# Find all missing required fields
for notice in result.by_code("missing_required_field"):
file = notice.file
field = notice.get("fieldName")
row = notice.row
print(f"{file}:{row} - missing {field}")
Save Reports
result = gtfs_guru.validate("/path/to/gtfs.zip")
# Save JSON report (same format as Java validator)
result.save_json("report.json")
# Save HTML report
result.save_html("report.html")
# Get as Python dict
report = result.to_dict()
summary = report["summary"]
print(f"Agencies: {summary.get('agencies', [])}")
print(f"Routes: {summary.get('routes', {}).get('count', 0)}")
Validation with Options
# Validate for specific country (affects some rules)
result = gtfs_guru.validate(
"/path/to/gtfs.zip",
country_code="DE"
)
# Validate as of specific date
result = gtfs_guru.validate(
"/path/to/gtfs.zip",
date="2025-06-01"
)
Supported Platforms
| Platform | Architecture | Python |
|---|---|---|
| macOS | ARM64 (M1/M2) | 3.8+ |
| macOS | x86_64 (Intel) | 3.8+ |
| Windows | x86_64 | 3.8+ |
| Linux | x86_64 | 3.8+ |
Performance
Typical validation times (compared to Java validator):
| Feed Size | Java | Rust/Python |
|---|---|---|
| Small (<1MB) | ~2s | ~0.05s |
| Medium (10MB) | ~10s | ~0.5s |
| Large (100MB) | ~60s | ~3s |
License
Apache-2.0
Metadata
Release files for gtfs-guru 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| gtfs_guru-1.0.0.tar.gz | 362.7 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| gtfs_guru-1.0.0-cp38-abi3-win_amd64.whl | CPython 3.8 | abi3 | Windows x86-64 | Details |
| gtfs_guru-1.0.0-cp38-abi3-manylinux_2_28_aarch64.whl | CPython 3.8 | abi3 | Linux glibc 2.28+ ARM64 | Details |
| gtfs_guru-1.0.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.8 | abi3 | Linux glibc 2.17+ x86-64 | Details |
| gtfs_guru-1.0.0-cp38-abi3-macosx_11_0_arm64.whl | CPython 3.8 | abi3 | macOS 11.0+ ARM64 | Details |
| gtfs_guru-1.0.0-cp38-abi3-macosx_10_12_x86_64.whl | CPython 3.8 | abi3 | macOS 10.12+ x86-64 | Details |
Total release size: 12.1 MB
Release files / gtfs_guru-1.0.0.tar.gz
| Download URL | gtfs_guru-1.0.0.tar.gz |
|---|---|
| Size | 362.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
986f0a42103d9c3ead3bb441b879261392d3d8365be36fbcf6549ced17fd01de
|
|
BLAKE2b-256 checksum How to use checksums |
e3708620016b2dfb1828c3f511c76475a0bcb308c339ad5b330bc9bf5dc09469
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|
Release files / gtfs_guru-1.0.0-cp38-abi3-win_amd64.whl
| Download URL | gtfs_guru-1.0.0-cp38-abi3-win_amd64.whl |
|---|---|
| Size | 2.5 MB |
| Tags | CPython 3.8 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
27907d178bccf5be60ff13d3e9144888e49e6b1610de96545af03e4c5b6618e4
|
|
BLAKE2b-256 checksum How to use checksums |
21db6313bb8082b66443880c6effefe7cf07aa6c557b416de9d0d837703f7aed
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|
Release files / gtfs_guru-1.0.0-cp38-abi3-manylinux_2_28_aarch64.whl
| Download URL | gtfs_guru-1.0.0-cp38-abi3-manylinux_2_28_aarch64.whl |
|---|---|
| Size | 2.3 MB |
| Tags | CPython 3.8 Linux glibc 2.28+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
889479e5d79f733c70e1c51d7c7fc2537b2fe90b595090fc2e15634751d84520
|
|
BLAKE2b-256 checksum How to use checksums |
3970c9f57b995ea60fe3c645c881f2d9b64414228ee5a84bf44d9f40b90bd51d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|
Release files / gtfs_guru-1.0.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | gtfs_guru-1.0.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 2.4 MB |
| Tags | CPython 3.8 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
79f016aafb8ee422b64cd4ff03a8fbf97cc53a7b65ab36e59f9761ebca070f99
|
|
BLAKE2b-256 checksum How to use checksums |
12aceff712226292ab84c006542d41495ed5517310615479eaa1fb0af19fe129
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|
Release files / gtfs_guru-1.0.0-cp38-abi3-macosx_11_0_arm64.whl
| Download URL | gtfs_guru-1.0.0-cp38-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 2.2 MB |
| Tags | CPython 3.8 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
eace212710373b393e047000b1fee4d2b0d9060a4788edf024c16b566207db11
|
|
BLAKE2b-256 checksum How to use checksums |
827ca19ea2ced683b091ab64f05bbdd12b343b74fd7211a3574fda724c1bf482
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|
Release files / gtfs_guru-1.0.0-cp38-abi3-macosx_10_12_x86_64.whl
| Download URL | gtfs_guru-1.0.0-cp38-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 2.4 MB |
| Tags | CPython 3.8 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
5d82f1bc38adf720d18f2dd019a3d30123b0014855a97e5842a21d463816dc4e
|
|
BLAKE2b-256 checksum How to use checksums |
89add75c6861c16b2c7b9feeeabad8b463162674ae840b0dffc934ac1307a505
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|