Tooling Tuesday: Get Transport Data
Need to get public transport data? Just ask JSON!
So what is it?
Transportapi is an API (Application Programming Interface) which collates data from various public transport services.
- Live train, tube and bus times across the UK.
- Journey Planning.
- Transport options by location.
- Timetables for train, bus, coach and ferry.
If you like what you read...
Sorry to interrupt! But would you like to buy me a cup of coffee? It helps me to pay for hosting this blog, and to buy stuff to hack from Poundshops / Dollar Stores which are used in free projects on this blog. Thanks!
So how do I get started?
Head over to their website and sign up for a free account.
Then login and you will see your App ID and Key. Keep these safe and do not share them, even on Github!
So how do I get data?
We need to create a special URL which will contain the details of our request. Here is an example which will get the details for Blackpool North train station (BPN). I wrote this URL in the address bar of my browser and pressed enter to see the output.
http://transportapi.com/v3/uk/places.json?query=BPN&type=train_station&app_id=APPID&app_key=API_KEY
And here is the output.
{"request_time":"2020-02-03T18:01:25+00:00","source":"Network Rail","acknowledgements":"Contains information of Network Rail Infrastructure Limited. License http://www.networkrail.co.uk/data-feeds/terms-and-conditions/","member":[{"type":"train_station","name":"Blackpool North","latitude":53.821913,"longitude":-3.049275,"accuracy":100,"station_code":"BPN","tiploc_code":"BLCKPLN"}]}
So what if I wanted to see all of the trains that would depart from Blackpool North, after 19:00 on February 3rd 2020? Again I wrote this in the browser.
https://transportapi.com/v3/uk/train/station/BPN/2020-02-03/19:00/timetable.json?app_id=APPID&app_key=API_KEY&train_status=passenger
And here are the train times, destinations, platform details and operators of the services.
{"date":"2020-02-03","time_of_day":"19:00","request_time":"2020-02-03T18:17:45+00:00","station_name":"Blackpool North","station_code":"BPN","departures":{"all":[{"mode":"train","service":"12249820","train_uid":"Y20896","platform":"3","operator":"NT","operator_name":"Northern Rail","aimed_departure_time":"19:05","aimed_arrival_time":null,"aimed_pass_time":null,"origin_name":"Blackpool North","destination_name":"Liverpool Lime Street (High Level)","source":"ATOC","category":"XX","service_timetable":{"id":"https://transportapi.com/v3/uk/train/service/train_uid:Y20896/2020-02-03/timetable.json?app_id=APPID\u0026app_key=API_KEY"}},
Viewing the output in Firefox
Viewing the output in Firefox is AWESOME! The JSON structure is simplified using a series of collapsible markers to hide / show data!
So what is JSON?
JSON aka Jo Hinchcliffe
JavaScript Object Notation is a data structure which can contain any information that we wish. From cinema times, flight data, ingredients, JSON can do it all. It is also an open standard that is not fixed to a certain operating system or language. It can be used with Python, JavaScript, Node-RED and even BASH!
So can we make something with this?
To show how to use the data, I am going to make a quick app that will get all of the current departures from my home station, Blackpool North. For this I shall be using Python 3 and creating a file called get-train-data.py
I start the code by importing a few libraries / modules.
import requests
from datetime import datetime, date
from secrets import *
The first is requests
and I use that to get the data from the Transportapi service. I then import datetime
and date
from the datetime
library. These are used to get the current date and time.
The final library is a custom file called secrets
.
Can you keep a secret?
To store my app ID and key, I created a file calledsecrets.py
and in there I stored the details as soapp_id = "My secret ID" app_key = "The long and secret key"
This means that I can change the data in
secrets.py
and tell Git to ignore this file when saving the work to Github.
The next step is to create three variables.
current_time = str(datetime.now().time())
current_time = current_time[0:5]
current_date = str(date.today())
station = "BPN"
First I get the current time, the time at that exact moment...to a very high level of accuracy. So on line two I use slicing to trim the first six digits from the time and update the contents of the current_time
variable. I then get the current date, before finally I set the station to Blackpool North (BPN) using the three character code via National Rail Enquiries.
Onwards, and now I want to create the URL which will get the data. This URL is saved to an object called url
.
url = "https://transportapi.com/v3/uk/train/station/"+station+"/"+current_date+"/"+current_time+"/timetable.json?app_id="+app_id+"&app_key="+api_key+"&train_status=passenger"
You can see in the URL the variables used for current_time, current_date, and station. I also use variables to get the app_id and api_key from the secrets
file.
The next step is to tell Python to use the requests
library to get the data from the Transportapi service and save it into the object r
.
r = requests.get(url)
Next step is to print the data returned from the service, but only if there is some!
if r:
Inside the if
condition I create a for loop that will iterate over every train departure from my station for the time and data specified. For this I treat the data as a Python dictionary, and search inside the departures
and then inside the all
section.
for i in range(len(r.json()['departures']['all'])):
To get the destination for each train.
destination = (r.json()['departures']['all'][i]['destination_name'])
To get the departure time.
departure = (r.json()['departures']['all'][i]['aimed_departure_time'])
To get the platform number.
platform = (r.json()['departures']['all'][i]['platform'])
To get the operator name.
operator_name = (r.json()['departures']['all'][i]['operator_name'])
I then use concatenation to add the information into a sentence, printed to the REPL for the user to read.
print("At "+departure+" the train to "+destination+" will depart from platform "+platform+". This service is provided by "+operator_name)
Complete Code Listing
import requests
from datetime import datetime, date
from secrets import *
current_time = str(datetime.now().time())
current_time = current_time[0:5]
current_date = str(date.today())
station = "BPN"
url = "https://transportapi.com/v3/uk/train/station/"+station+"/"+current_date+"/"+current_time+"/timetable.json?app_id="+app_id+"&app_key="+api_key+"&train_status=passenger"
r = requests.get(url)
if r:
for i in range(len(r.json()['departures']['all'])):
destination = (r.json()['departures']['all'][i]['destination_name'])
departure = (r.json()['departures']['all'][i]['aimed_departure_time'])
platform = (r.json()['departures']['all'][i]['platform'])
operator_name = (r.json()['departures']['all'][i]['operator_name'])
print("At "+departure+" the train to "+destination+" will depart from platform "+platform+". This service is provided by "+operator_name)
I then save the code, and run it to see output similar to this.
At 21:17 the train to York will depart from platform 4. This service is provided by Northern Rail
At 21:21 the train to Manchester Airport will depart from platform 2. This service is provided by Northern Rail
At 22:02 the train to Bradford Interchange will depart from platform 4. This service is provided by Northern Rail
At 22:18 the train to Liverpool Lime Street (High Level) will depart from platform 6. This service is provided by Northern Rail
At 22:21 the train to Manchester Airport will depart from platform 5. This service is provided by Northern Rail
At 23:00 the train to Blackburn will depart from platform 1. This service is provided by Northern Rail
At 23:13 the train to Manchester Airport will depart from platform 5. This service is provided by Northern Rail
Using this data we can build many different apps and services.