nyctrains API
A FastAPI-based backend and Python package for working with the MTA's real-time subway and LIRR GTFS-RT data feeds. This project fetches, parses, and exposes real-time feeds as human-readable JSON, including stop names and (for LIRR) route names. You can use it as an HTTP API or as a Python library in your own projects.
Supported Feeds
ace(A, C, E)bdfm(B, D, F, M)g(G)jz(J, Z)nqrw(N, Q, R, W)l(L)si(Staten Island Railway)1234567(1, 2, 3, 4, 5, 6, 7, S)lirr(Long Island Rail Road)
Installation
Install using pip:
pip install nyctrains
Static GTFS Data
This package relies on static GTFS data files being present in the resources/ directory for full functionality (e.g., adding stop names, route details).
Required files:
resources/stops.txt(NYC Subway + LIRR stops)resources/routes.txt(NYC Subway + LIRR routes)resources/trips.txtresources/stop_times.txt
Note: The simple mappings for LIRR stop names (stops-lirr.txt) and route names (routes-lirr.txt) used in earlier versions have been replaced by the requirement for the full static GTFS files. You can typically download these files from the MTA developer resources page.
The application loads these files into pandas DataFrames at startup using the nyctrains.static_gtfs module.
Usage
This package provides Python tools and a FastAPI backend for working with MTA GTFS-RT subway and LIRR data. No API key is required to use the package or access the feeds.
Running the API Server
# Make sure you have the static GTFS files in ./resources/
uvicorn nyctrains.main:app --reload
Access the API documentation at http://127.0.0.1:8000/docs.
Make requests to the feed endpoint, e.g.:
http://127.0.0.1:8000/subway/ace/json
Using as a Library
Example: Fetching a GTFS Feed
from nyctrains.mta_client import MTAClient
import asyncio
client = MTAClient()
feed_path = "nyct%2Fgtfs-ace" # Example feed
data = asyncio.run(client.get_gtfs_feed(feed_path))
# data contains the raw protobuf bytes
print(f"Feed data length: {len(data)} bytes")
Example: Loading Static GTFS Data
from nyctrains import static_gtfs
# Load static data (caches results)
stops_df = static_gtfs.get_stops()
routes_df = static_gtfs.get_routes()
if stops_df is not None:
print(f"Loaded {len(stops_df)} stops.")
if routes_df is not None:
print(f"Loaded {len(routes_df)} routes.")
Example Output
{
"header": {
"gtfs_realtime_version": "2.0",
"timestamp": "2025-04-15T21:04:02+00:00"
},
"entity": [
{
"id": "GO304_25_809_T",
"trip_update": {
"trip": {
"trip_id": "GO304_25_809",
"start_date": "20250415",
"schedule_relationship": 0,
"route_id": "6",
"route_long_name": "Long Beach Branch",
"direction_id": 1
},
"stop_time_update": [
{
"stop_id": "LBG",
"stop_name": "Long Beach"
}
]
}
}
]
}
Metadata
Release files for nyctrains 1.5.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 | |
|---|---|---|---|
| nyctrains-1.5.0.tar.gz | 111.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| nyctrains-1.5.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 125.6 kB
Release files / nyctrains-1.5.0.tar.gz
| Download URL | nyctrains-1.5.0.tar.gz |
|---|---|
| Size | 111.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
065f9f391874263df30ba05af348f0a4a4cdf6a611e0d2701b4cd960d2271e3b
|
|
BLAKE2b-256 checksum How to use checksums |
5f67ea41a9bbdaaaac486f7f7a8e18a45cfa5ef775ca4e919a86bb6886a436c3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.10.16
|
Release files / nyctrains-1.5.0-py3-none-any.whl
| Download URL | nyctrains-1.5.0-py3-none-any.whl |
|---|---|
| Size | 13.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
eba92da987ee80026c8dddaa03f3a0774690f1144237f332618df6ec16421a30
|
|
BLAKE2b-256 checksum How to use checksums |
9c5aa01c17559b9c83b437481a4afe5224f7982827376e0ff78f0c04ac203836
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.10.16
|