Parsing GTFS format transit data in real time with Python

Image for post
Image for post

Get yourself an API key

Before we start, you’ll need to decide what GTFS transit data you want to access.

Install Google’s GTFS Python library

Google has already created a library of GTFS bindings for Python. This took me a little while to find and start using, so I’ll help you out with some setup instructions.

pip install --upgrade gtfs-realtime-bindings
python -m google.transit.gtfs_realtime_pb2

Install requests if you haven’t already

Most Python developers will already have the requests library installed. It allows you to make HTTP requests from within a Python program.

pip install --upgrade requests
python
>>> import requests
>>> requests.__version__
'2.21.0'

Building a barebones data feed

Now the fun part. Let’s get some data!

  1. Get the response from the API
  2. Pass the response to the parser

1. Initialize an instance of FeedMessage

Google defines a FeedMessage class in its library. We’ll add data to this class later, but right now we just need to initialize it.

feed = gtfs_realtime_pb2.FeedMessage()

2. Get the response from the API

Let’s go get the data from the API now that we’ll pass to the FeedParser in step 3.

response = requests.get(<URL OF YOUR GTFS SOURCE>, allow_redirects=True)

3. Pass the response to the parser

The FeedMessage class has a ParseFromString() method to read in the data.

feed.ParseFromString(response.content)
>>> len(feed.entity)
373
>>> feed.entity[0]
id: "000001"
trip_update {
trip {
trip_id: "057150_1..N03R"
start_date: "20190422"
route_id: "1"
}
stop_time_update {
arrival {
time: 1555943380
}
stop_id: "101N"
}
}

Use trip_update

Not every entity in the feed will have a real-time update of transit status. Destinations and departure locations might also be included.

for entity in feed.entity:
if entity.HasField('trip_update'):
# Do something
>>> len(feed.entity)
373
>>> sum([1 for ent in feed.entity if ent.HasField('trip_update')])
218
>>> sum([1 for ent in feed.entity if not ent.HasField('trip_update')])
155

Put it all together

Want to see a barebones application to pull GTFS data in action?

Read more

Like what you’ve read here? I have an email list you can subscribe to.

Top writer in Technology | Backend Web Developer | bennettgarner.com

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store