r1cc4rdo / PTV_v3

Public Transport Victoria (PTV) API

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Public Transport Victoria (PTV) Timetable API v3

The PTV Timetable API provides programmatic access to public transport data for the state of Victoria, Australia.

Find below a minimal Python implementation with no external dependencies, or have a look at the javascript version. I'm happy to host here any more minimal, tested implementations; if you have one you'd like to share, send a pull request!

import requests
import hashlib
import hmac

class PTVv3:    
    base_url = 'https://timetableapi.ptv.vic.gov.au'

    def __init__(self, ptv_id, ptv_key):
        self.id = ptv_id
        self.key = ptv_key.encode('utf-8')

    def __call__(self, endpoint, **params):
        params['devid'] = self.id
        encoded = [f'{k}={v}'
                   for k, vs in params.items()
                   for v in (vs if isinstance(vs, (list, tuple)) else [vs])]

        request = f'{endpoint}?{"&".join(encoded)}'
        hashed = hmac.new(self.key, request.encode('utf-8'), hashlib.sha1)
        url = f'{PTVv3.base_url}{request}&signature={hashed.hexdigest()}'

        response = requests.get(url)
        response.raise_for_status()
        return response.json()

which can be used as follows:

ptv = PTVv3('your id here', 'your key here')
print(ptv('/v3/disruptions', route_types=2))

You will need to obtain your own id/key pair from PTV to use the API.

API model

Intuitively, these are the API concepts:

  • a route is an ordered collection of stops that can run in one or more directions;
  • a run represents a vehicle (bus, tram, train, etc) travelling along a route in a direction;
  • a departure gives the planned and predicted time (if available) of passing through a stop.

The API also provides information regarding service disruptions, fare estimates and station facilities.

A more detailed description of the relation between stops, directions and routes can be found in here.

Usage

The Jupyter notebook in this repository shows how to use the PTVv3 class to:

  • compose, sign and make a request,
  • discover bus stops from GPS coordinates, and
  • find realtime location of buses and expected departures.

The notebook is also available in markdown and PDF formats.

Tracking information

What follows are unverified educated guesses. If you have any better information, ideally firsthand, I'd like to hear from you!

PTV provides each transport modality through several operators. For example, in the Melbourne area:

PTV API for live tracking of buses has been occasionally unreliable, not returning a vehicle_position structure for otherwise active vehicles.

Ventura's own live tracker does not have an API but has been historically more dependable. It appears to either share or piggyback on tracking technology from BusMinder, which does not have a public-facing API either. Both the web tracker and the app can only display the company's services; several weekend routes are served by different operators.

The tracking devices on buses are produced by Smartrak, and transmit GPS coordinate over the 4G cellular network. The device model most likely installed on buses is a Smartrak OBD II.

API url and schema validation

The PTV API OpenAPI schema can be downloaded with:

wget http://timetableapi.ptv.vic.gov.au/swagger/docs/v3 -O ptv_api_spec.json

The OpenAPI specification version used in it is 2.0. The v3 on the website and documentation refers to the revision of the PTV API!

The schema is not valid. It can be made to pass validation by applying the following superficial patch:

cat ptv_api_spec.json | python -m json.tool > prettyprinted.json
--- prettyprinted.json	2024-03-26 01:38:49
+++ modified.json	2024-03-26 01:39:11
@@ -3571,6 +3571,23 @@
                 }
             }
         },
+        "V3.FareEstimateResponse": {
+            "type": "object",
+            "properties": {
+                "fare_estimate": {
+                    "$ref": "#/definitions/V3.FareEstimate",
+                    "description": "Resultant set fare estimates"
+                },
+                "status": {
+                    "$ref": "#/definitions/V3.Status",
+                    "description": "API Status / Metadata"
+                }
+            }
+        },
+        "V3.FareEstimate": {
+            "type": "object",
+            "properties": {}
+        },
         "V3.Disruptions": {
             "type": "object",
             "properties": {

Using tools like openapi-core (OpenAPI v3) or Flex (OpenAPI v2) it's then possible to validate a url prior to making a request:

from requests import Request
from flex.core import load, validate_request, normalize_request

schema = load('ptv_api_spec.json')
request = Request('GET', 'https://timetableapi.ptv.vic.gov.au/v3/route_types')
validate_request(normalize_request(request.prepare()), schema)

The validation code above is supposed to check the compliance of both url path and parameters, but only works properly for the first.

Timetable API v2 support

In theory, this code should be able to support v2 of the Timetable API (e.g. ptv('v2/healthcheck')), which is still advertised on PTV's website, but I had no luck with either http or https protocols. Support for v2 endpoints might have been discontinued.

Links

About

Public Transport Victoria (PTV) API

License:The Unlicense


Languages

Language:Jupyter Notebook 82.7%Language:Python 10.6%Language:JavaScript 5.9%Language:HTML 0.8%