• Home
  • Exercises 08
  • Swiftly
  • Swiftly

    The questions below are due on Thursday April 20, 2023; 10:00:00 AM.
     
    You are not logged in.

    Please Log In for full access to the web site.
    Note that this link will take you to an external site (https://shimmer.mit.edu) to authenticate, and then you will be redirected back to this page.

    This should be a relatively quick setup of the swiftly API that provides information about the bus network. We'll be asking you to use Postman to interact with the bus API so make sure you installed this (and still have it installed) from teh previous assignments that used it.

    Switfly Overview

    Switfly is a company that provides data about transportation networks

    We're working with Miami's system. Within this system, we'll have two large classes of information (which are going to be accessible each with a different API key):

    • Miami Dade Geneneral: which will allow one to acquire information about the Miami Dade bus system in general. (Static things like names/info on routes, bus stops, etc.)
    • Miami Dade Real Time: which will allow us to acquire information about the current state of the Miami bus system.

    You should have a key for each of these. You will need to use the appropriate key for the appropriate resources. Mixing them up will result in 403/Permission Denied errors.

    If you do not have a general-use API key (which I'm being told is the case for some of you, having only been given a real-time key), use this one: 81ee30b5d4fc8c9836dc7585889004d2. Do not abuse it. I'm not sure how much they rate-limit on a given key.

    https://dashboard.goswift.ly/miami/api-guide/reference

    For those of you who have never taken a bus, in general, bus systems are broken down into bus lines. These lines will have a number. In addition, each route will have two directions associated with it. In most areas, these are diferentiated with names like "inbound" and "outbound" where "in" usually refers loosely to the center of the universe around which the system is working. This can get tricky however for busses that run cross-town or from suburb to suburb through a city, in which case the idea of inbound and outbound gets transient. For API purposes, each route will have two directions, that will generally be specified with a 0 or a 1 when needed. Whether that is inbound/outbound, northbound/southbound, etc is variable and just needs to be determined on a case-by-case basis1

    To get a sense of what a single bus route "looks" like in terms of a data structure, let's use the routes endpoint. Documentation for this endpoing is here.

    In Postman, formulate a GET request to this endpoint:

    https://api.goswift.ly/info/miami/routes
    

    Add on two query arguments:

    • route=27435
    • verbose=true

    The result of this will be a full URL query of:

    https://api.goswift.ly/info/miami/routes?route=27435&verbose=true
    

    And also add in a single additional header element of:

    • Authorization: {Your Miami Dade General API Token}

    Fire this GET request off and you should get a JSON data structure back that describes all of the relevant information about the bus route with ID 27435. It will be about 1000 lines of JSON. If we had left the route query argument out, we'd get information on ALL bus lines, which would end up being about 200,000 lines of JSON. Consumable, but a little overwhelming. Looking at one makes it a little easier. The data that comes back should look (at least the start) like the following:

    {
        "success": true,
        "route": "/info/miami/routes GET",
        "data": {
            "agencyKey": "miami",
            "routes": [
                {
                    "id": "27435",
                    "name": "1 - So.Miami Hts-Perrine Via Southland",
                    "shortName": "1",
                    "longName": "So.Miami Hts-Perrine Via Southland",
                    "color": "FF00FF",
                    "textColor": "FFFFFF",
                    "type": "3"
                    "directions": [
    ... (and so on)
    

    OK so what all comes back? Well there's some nesting of stuff, some of which will seem redundant in particular since we only requested info on one single bus route. Ignoring that, we'll see the following entries inside the JSON dictionary in the routes entry in the data dictionary that can fully describe one single bus line in Miami-Dade.

    • "id": This is the ID of the particular bus route. It is unique to the Miami Dade bust system.
    • "name": The name of the bus line
    • "shortName": The "nickname" of the bus line. So like a cool kid would say, "I'm going to take the Number 1 bus to go get some snacks."
    • "longName": the long name of the line (usually seems the same as the regular name).
    • "color": I think mainly used for display purposes in the API. This is the color purple, which lines up with the color of the line in the dashboard.
    • "textColor": Similar to above.
    • "type": Not really sure. Likely telling us this is a bus line as opposed to something else.
    • "directions: [...: This is itself referring to a dictionary which describes the two "directions" of this bus route. The values are:
      • "id": The 0 or 1 value to differentiate direction
      • "title": The destination/front title card on the bus for that particular direction. This is what shows up on the front of the bus sign. For example "To 1 - SW 168 St". This is like how the red line in Boston has either Alewife-bound trains or Ashmont- or Braintree-bound trains.
      • "stops": [...: This is a json list of stop dictionaries. A list is an ordered collection of data, so the order of entries in this list tells you the stops for that particular direction in order. Each stop is itself a dictionary with teh following values:
        • "id": The unique identifier of the bust stop
        • "lat": The latitude of the bus stop on earth
        • "lon": The longitude of the bus stop on earth
        • "name": The name of the bus stop. For example, "SW 107th Ave @ SW 112th St"
        • "code": The code of the bus stop, which largely seems to be the same as the id. Except as a number not a string. Iunno.
    • "shapes": [...: This is yet another nested JSON object that at its core contains data (and some metadata) about the exact GPS locations of the bus route. Since Miami Dade is, like all cities comprised of roads and the bus can only go on those roads, in order to fully specify the spatial location of a bus route, you cannot simply draw lines from one stop to another (see the stops list above); that would simply draw the route as if you could move through buildings. Instead we need an entirely set of GPS lat/lon waypoints that will let express the exact bust route (via roads).

    Ok so pretty cool. With this ablity we can now "tap" into the entire Miami-Dade system and can use the id numbers for routes and stops and directions to effectively access other aspects of the system.

    Other Data

    Once we have the ability to know what the id numbers are for various routes and stops, we can use this information to probe the real-time state of the system. Specific details of the real-time API are here. One example of something that might be useful in your project would be to probe what the expected time is going to be for a person at a stop. This could be accessed via the predictions endpoint. For example, consider stop ID 3614. This stop is on the #1 bus (route id 27435 and would have been spotted on the request you did earlier on the page). Using your real-time API key (not the same as your general API key), you could formulate a request like the following:

    https://api.goswift.ly/real-time/miami/predictions?stop=3614
    

    What comes back will look something like this:

    {
        "success": true,
        "route": "/real-time/miami/predictions GET",
        "data": {
            "agencyKey": "miami",
            "predictionsData": [
                {
                    "routeShortName": "1",
                    "routeName": "1 - So.Miami Hts-Perrine Via Southland",
                    "routeId": "27435",
                    "stopId": "3614",
                    "stopName": "SW 107th Ave @ SW 128th St",
                    "stopCode": 3614,
                    "destinations": [
                        {
                            "directionId": "0",
                            "headsign": "1 - SW 168 St",
                            "predictions": [
                                {
                                    "time": 1680275870,
                                    "sec": 1511,
                                    "min": 25,
                                    "tripId": "5414399",
                                    "vehicleId": "LSF434"
                                },
                                {
                                    "time": 1680278387,
                                    "sec": 4028,
                                    "min": 67,
                                    "tripId": "5414405",
                                    "vehicleId": "LSF417"
                                },
                                {
                                    "time": 1680280839,
                                    "sec": 6481,
                                    "min": 108,
                                    "tripId": "5414413",
                                    "vehicleId": "LSF434"
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    }
    

    This JSON object looks overly nested, but that's because the stop in question is only serviced by one particular direction of one particular route. In a more general sense, some stations/stops will service multiple routes and even multiple directions on that route (think of a bus terminal) and so having all these various means of specifying is important. The data structure that comes back, howver reports the predicted time until the next bus for a particular stop (and then usually a few other busses after that, however going into the future too far isn't possible to predict). You can see the predicted time in seconds or minutes is provided. As well as the ID of the trip (and you could use this trip id to get other info). The vehicle associated with the upcoming stop is also listed.

    Another endpoint to explore is the state of particular vehicles.

    https://api.goswift.ly/real-time/miami/vehicles?route=27435
    

    will ask for the state of all vehicles on the 27435 route (the one we've been studying). When I ran mine just now I got the following as a response:

    {
        "success": true,
        "route": "/real-time/miami/vehicles GET",
        "data": {
            "agencyKey": "miami",
            "vehicles": [
                {
                    "id": "LSF434",
                    "routeId": "27435",
                    "routeShortName": "1",
                    "headsign": "1 - South Miami Heights",
                    "vehicleType": "3",
                    "loc": {
                        "lat": 25.57266,
                        "lon": -80.36472,
                        "time": 1680274580,
                        "speed": 0,
                        "heading": 249.2
                    },
                    "directionId": "1"
                },
                {
                    "id": "LSF417",
                    "routeId": "27435",
                    "routeShortName": "1",
                    "headsign": "1 - SW 168 St",
                    "vehicleType": "3",
                    "loc": {
                        "lat": 25.57614,
                        "lon": -80.3727,
                        "time": 1680274583,
                        "speed": 0,
                        "heading": 221.5
                    },
                    "directionId": "0"
                }
            ]
        }
    }
    

    Which could be used to plot locations of busses if needed.

    There are several other endpoints under the real-time umbrella which provide data in General Transit Feed Specification (GTFS) format. The documentation on the site is pretty good and in testing, everythign seems to mostly work.

    As a tiny assignment to do at the end of this page, please answer the following questions:

    What is the name of bus stop #7937?

    How many bus routes service bus stop #4097?

    What is the headsign for the the #24 bus going through stop #1587?