I am trying to use the API from Société du Métro de Montréal (STM), a transportation GTFS transportation API.
I get error code 400 ("Too many requests") when trying the Python code below. I wonder if anyone is working with transportation APIs and can give me some hints on what I did wrong.
import requests
api_key = "API-KEY-FROM-DEVELOPER-ACCOUNT"
api_url = f"https://api.stm.info/pub/od/gtfs-rt/ic/v2/vehiclePositions"
# Prepare the request headers with the API key
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
}
# Send the HTTP GET request to the API endpoint
response = requests.get(api_url, headers=headers)
# if you get 200 as response... everything ok
print("response.status_code",response.status_code)
# Check if the request was successful (status code 200)
if response.status_code == 200:
try:
# Parse the JSON response
data = response.json()
# Process and use the retrieved data as needed
print(data)
except ValueError as e:
print("Error parsing JSON:", e)
print("Response content:", response.text)
else:
# Handle unsuccessful request
print(f"Error: {response.status_code}")
I expected a response 200 for:
print("response.status_code",response.status_code)
LATER UPDATE Actually the issue was in the authentication method. I replaced the headers by the ones below and it gave me the response 200, confirming that I was able to connect to the API. = issue closed
headers = { "apiKey":api_key, "Content-Type": "application/json" }
Thanks to all who tried to help... and thanks a lot to ChatGPT !!! :)
After some fiddling (in the APIs page you can try the APIs real time), I found out that the field name for the API key is apikey
. Thus, the following code should work:
import requests
api_key = "API-KEY-FROM-DEVELOPER-ACCOUNT"
api_url = f"https://api.stm.info/pub/od/gtfs-rt/ic/v2/vehiclePositions"
# Prepare the request headers with the API key
headers = {
"apikey": api_key,
}
# Send the HTTP GET request to the API endpoint
response = requests.get(api_url, headers=headers);
print(f"{response.status_code}: {response.content}")
A few points to notice:
It will be easier to use the Python language bindings to read the results. You can use the example below (adapted to python3):
from google.transit import gtfs_realtime_pb2
from urllib.request import Request, urlopen
api_key = "API-KEY-FROM-DEVELOPER-ACCOUNT"
api_url = f"https://api.stm.info/pub/od/gtfs-rt/ic/v2/vehiclePositions"
feed = gtfs_realtime_pb2.FeedMessage()
request = Request(api_url)
request.add_header('apikey', api_key)
response = urlopen(request)
print(f'Status: {response.status_code}')
feed.ParseFromString(response.read())
for i, entity in enumerate(feed.entity):
if entity.HasField('vehicle') and entity.vehicle.HasField('position'):
pos = entity.vehicle.position
print(f'{i} lat: {pos.latitude}, long: {pos.longitude}')