transiter icon indicating copy to clipboard operation
transiter copied to clipboard

MBTA: Massachusetts Bay Transit Authority

Open milas opened this issue 7 months ago • 8 comments

(Thanks for transiter!) I hope you don't mind the rather free-from nature of this issue -- please let me know if you'd prefer something else.

With Transiter 1.0.0, I was able to load the Massachusetts Bay Transit Authority as mbta with this config:

name: Massachusetts Bay Transit Authority (MBTA)

feeds:
  - id: gtfsstatic
    type: GTFS_STATIC
    url: "https://cdn.mbta.com/MBTA_GTFS.zip"

  - id: tripupdate
    type: GTFS_REALTIME
    url: "https://cdn.mbta.com/realtime/TripUpdates.pb"

  - id: alerts
    type: GTFS_REALTIME
    url: "https://cdn.mbta.com/realtime/Alerts.pb"

  - id: vehicles
    type: GTFS_REALTIME
    url: "https://cdn.mbta.com/realtime/VehiclePositions.pb"

not topologically sortable

On feed update, I get this error several times:

error building static map: service map cannot be topologically sorted: the provided graph is not topologically sortable because it contains a cycle" system_id=mbta feed_id=gtfsstatic

I think it's some of the bus routes tripping it up?

Here's one that doesn't have a service map, though the route isn't actually a loop, so I'm not sure if I'm just off-base here: https://www.mbta.com/schedules/104.

Transiter API response:

/systems/mbta/routes/104

{
  "id":  "104",
  "resource":  null,
  "system":  null,
  "shortName":  "104",
  "longName":  "Malden Center Station - Airport Station",
  "color":  "FFC72C",
  "textColor":  "000000",
  "description":  "Frequent Bus",
  "url":  "https://www.mbta.com/schedules/104",
  "sortOrder":  51040,
  "continuousPickup":  "NOT_ALLOWED",
  "continuousDropOff":  "NOT_ALLOWED",
  "type":  "BUS",
  "agency":  {
    "id":  "1",
    "resource":  {
      "path":  "systems/mbta/agencies/1"
    },
    "system":  {
      "id":  "mbta",
      "resource":  {
        "path":  "systems/mbta"
      }
    },
    "name":  "MBTA"
  },
  "alerts":  [],
  "estimatedHeadway":  823,
  "serviceMaps":  [
    {
      "configId":  "realtime",
      "stops":  []
    },
    {
      "configId":  "weekday",
      "stops":  []
    },
    {
      "configId":  "alltimes",
      "stops":  []
    }
  ]
}

unique constraint on transfer_system_pk_id_key

Since the logging on the feed update didn't give me a ton of details, I figured I'd try latest main as a first step and possibly add some extra attributes to the slog call to figure out which route/etc are breaking.

Unfortunately, I can no longer import the system at all on HEAD:

level=ERROR msg="failed update with reason FAILED_UPDATE_ERROR and error \"ERROR: duplicate key value violates unique constraint \\\"transfer_system_pk_id_key\\\" (SQLSTATE 23505)\" in 3.272171761s" system_id=mbta feed_id=gtfsstatic update_id=f9841009-3632-4b66-bed7-a745b2e3ab24

level=ERROR msg="install or update failed: ERROR: duplicate key value violates unique constraint \"transfer_system_pk_id_key\" (SQLSTATE 23505)" system_id=mbta

Additional Context

Again, I know this is a pretty vague issue! I will work on debugging/root causing a bit more on these, but wanted to at least share my progress publicly as a start.

With v1.0.0, things do work well in general! I'm still just getting started playing around with Transiter, but it's really awesome and something I'm SO happy exists.

milas avatar Apr 26 '25 16:04 milas

Hey, thank you for the detailed issue!

On versioning, I think we've been a bit lazy about releasing new versions. In general the expectation is that the version of Transiter on main works - and I deploy straight from main (using the Docker :latest tag). Maybe we need to autorelease versions to make this clearer...?

There's at least 2 issues here I guess:

  • The "not topologically sortable" error - if the route is not a loop, it should work. I'll try to debug this. Sometimes this can be a data issue, FWIW. E.g., if the MBTA releases a schedule in which the directions are not specified, Transiter will consider all of the trips to be in the same direction and this will necessarily cause loops. For example, if the schedule is "one trip from Malden Center to Airport" and "one trip from Airport to Malden Center", with no directionality specified, then Transiter will think there's a loop. We can probably be smarter in this case. To be clear, I'm not sure this is what's happening here.

  • The "unique constraint" error - this seems to be 100% a bug. When you add a system it shouldn't be adding a new system. The workaround here btw is to delete the transit system and then reinstall it.

jamespfennell avatar Apr 26 '25 17:04 jamespfennell

Btw, as an end goal for this issue, maybe we could get this to work and then commit your YAML config to the systems directory?

jamespfennell avatar Apr 26 '25 17:04 jamespfennell

On versioning, I think we've been a bit lazy about releasing new versions. In general the expectation is that the version of Transiter on main works

Good to know! I'm happy to use the latest tag, I just didn't want to report issues against something in-progress :)

The "unique constraint" error - this seems to be 100% a bug. When you add a system it shouldn't be adding a new system. The workaround here btw is to delete the transit system and then reinstall it.

Sorry, I wasn't super clear here - I actually did wipe everything before switching. I'm using Compose so I've been dropping my Postgres volume (docker compose down -v) between runs for testing.

Here's with debug logs:

time=2025-04-26T21:10:09.681Z level=INFO msg="recieved install or update systm request" system_id=mbta
time=2025-04-26T21:10:09.681Z level=INFO msg="config: name:\"MBTA\" feeds:{id:\"gtfsstatic\" type:\"GTFS_STATIC\" url:\"https://cdn.mbta.com/MBTA_GTFS.zip\"} feeds:{id:\"tripupdate\" type:\"GTFS_REALTIME\" url:\"https://cdn.mbta.com/realtime/TripUpdates.pb\"} feeds:{id:\"alerts\" type:\"GTFS_REALTIME\" url:\"https://cdn.mbta.com/realtime/Alerts.pb\"} feeds:{id:\"vehicles\" type:\"GTFS_REALTIME\" url:\"https://cdn.mbta.com/realtime/VehiclePositions.pb\"}" system_id=mbta
time=2025-04-26T21:10:09.705Z level=DEBUG msg="starting feed update" system_id=mbta feed_id=gtfsstatic update_id=a0f3f710-3860-4532-bbdf-127b446d2494
time=2025-04-26T21:10:19.444Z level=ERROR msg="failed update with reason FAILED_UPDATE_ERROR and error \"ERROR: duplicate key value violates unique constraint \\\"transfer_system_pk_id_key\\\" (SQLSTATE 23505)\" in 9.736733087s" system_id=mbta feed_id=gtfsstatic update_id=a0f3f710-3860-4532-bbdf-127b446d2494
time=2025-04-26T21:10:19.444Z level=ERROR msg="install or update failed: ERROR: duplicate key value violates unique constraint \"transfer_system_pk_id_key\" (SQLSTATE 23505)" system_id=mbta
time=2025-04-26T21:10:19.447Z level=INFO msg="install or update finished" system_id=mbta

milas avatar Apr 28 '25 00:04 milas

OK, I added some hacky debugging code.

updateTransfers()

import (
	"github.com/google/go-cmp/cmp"
	"google.golang.org/protobuf/testing/protocmp"
)
trans := make(map[string][]gtfs.Transfer)
for _, transfer := range transfers {
	id := fmt.Sprintf("%s_to_%s", strings.ReplaceAll(transfer.From.Id, "_", "__"), strings.ReplaceAll(transfer.To.Id, "_", "__"))
	trans[id] = append(trans[id], transfer)
}

for k, v := range trans {
	if len(v) > 1 {
		fmt.Println(k)
		for i := 1; i 

When there's multiple gtfs.Transfer objects for a key, they're generally all the same.

There's a few that do have differences, for example:

NEC-2237-03_to_NEC-2237-05
  gtfs.Transfer{
  	From:            &{Id: "NEC-2237-03", Name: "Forest Hills", Description: "Forest Hills - Commuter Rail - Track 3", ZoneId: "CR-zone-1A", ...},
  	To:              &{Id: "NEC-2237-05", Name: "Forest Hills", Description: "Forest Hills - Commuter Rail - Track 5", ZoneId: "CR-zone-1A", ...},
- 	Type:            s"TIMED",
+ 	Type:            s"REQUIRES_TIME",
- 	MinTransferTime: nil,
+ 	MinTransferTime: &124,
  }

I think that's legitimately inconsistent upstream data?

I wonder if "first-one-in wins" makes sense w/ the INSERT being conditional based on existence here

milas avatar Apr 28 '25 01:04 milas

Nice debugging!! We've actually had a similar issue for duplicate trip IDs in the realtime feeds and we explicitly handle this case in the code. This code has a "first one wins" strategy, like you describe. We would need to add a similar seen map in this function for transfers

That function already has a pretty extensive comment about transfer IDs. The GTFS spec doesn't actually have them; those IDs which are colliding are generated by Transiter. So there is an alternative which is that we change the ID generator to handle this case. Looking at the GTFS reference (https://gtfs.org/documentation/schedule/reference/#transferstxt), is it possible that we should be generating different IDs anyway? The spec says that transfers have a primary key (from_stop_id, to_stop_id, from_trip_id, to_trip_id, from_route_id, to_route_id), whereas in our ID generator we only factor in the stop_ids. Do the colliding transfers have different trips or routes?

jamespfennell avatar Apr 28 '25 21:04 jamespfennell

OK, I updated Transfer parsing in github.com/jamespfennell/gtfs to grab route + trip as well.

I then modified the ID assignment code:

  • If trip exists -> {from_stop}::{from_trip}_to_{to_stop}::{to_trip}
  • If route exists -> {from_stop}::{from_route}_to_{to_stop}::{to_route}
  • Default -> {from_stop}_to_{to_stop} (existing)

In the MBTA static feed right now, there's 2264 transfers, of which 218 are for a "trip" and the remainder are stop-to-stop. There are no "route" transfers present.

It looks like they're pretty much all because of special things like construction.

Given that, what do you think about:

  1. I open a PR to modify the GTFS parser -> https://github.com/jamespfennell/gtfs/pull/23
  2. Once updated here, a second PR to ignore any transfers that have a trip/route attached
  3. (Optional) feature request issue to track supporting trip/route transfers

I've actually got a fair amount done for (3) in terms of adding a migration for the FKs and updating the model, so hopefully I can contribute towards that as well, but at least ignoring them fixes the acute issue and is a stepping stone to full support regardless.

Open to suggestions as well (& happy to push a messy WIP branch to my fork if helpful).

All MBTA transfers for a "trip"
FB-0095-04::AttleboroWork-715730-1708_to_NEC-2192-02::AttleboroWork-715957-908
FB-0095-04::AttleboroWork-715742-1756_to_NEC-2192-02::AttleboroWork-715939-856
FB-0095-04::AttleboroWork-715906-776_to_NEC-2192-02::AttleboroWork-715946-874
FB-0095-04::AttleboroWork-715909-784_to_NEC-2192-02::AttleboroWork-729099-984
FB-0095-04::AttleboroWork-717751-5746_to_NEC-2192-02::AttleboroWork-716184-5846
FB-0095-04::AttleboroWork-717752-5724_to_NEC-2192-02::AttleboroWork-716179-5824
FB-0095-04::AttleboroWork-717753-5754_to_NEC-2192-02::AttleboroWork-716187-5856
FB-0095-04::AttleboroWork-717754-5730_to_NEC-2192-02::AttleboroWork-716180-5830
FB-0095-04::AttleboroWork-717755-5738_to_NEC-2192-02::AttleboroWork-716182-5838
FB-0095-04::AttleboroWork-717761-5784_to_NEC-2192-02::AttleboroWork-716192-5884
FB-0095-04::AttleboroWork-717765-5778_to_NEC-2192-02::AttleboroWork-716191-5878
FB-0095-04::AttleboroWork-717766-5792_to_NEC-2192-02::AttleboroWork-716194-5892
FB-0095-04::AttleboroWork-717768-5768_to_NEC-2192-02::AttleboroWork-716189-5868
FB-0095-04::AttleboroWork-722800-792_to_NEC-2192-02::AttleboroWork-715953-892
FB-0095-04::AttleboroWork-729096-5706_to_NEC-2192-02::AttleboroWork-716176-5806
FB-0095-04::SouthJune2WKDY-739054-1708_to_NEC-2192-02::SouthJune2WKDY-739234-908
FB-0095-04::SouthJune2WKDY-739066-1756_to_NEC-2192-02::SouthJune2WKDY-739216-856
FB-0095-04::SouthJune2WKDY-739184-776_to_NEC-2192-02::SouthJune2WKDY-739223-874
FB-0095-04::SouthJune2WKDY-739187-784_to_NEC-2192-02::SouthJune2WKDY-739498-984
FB-0095-04::SouthJune2WKDY-739489-792_to_NEC-2192-02::SouthJune2WKDY-739230-892
FB-0095-04::SouthJune2WKNDNewSigns-740338-5706_to_NEC-2192-02::SouthJune2WKNDNewSigns-739508-5806
FB-0095-04::SouthJune2WKNDNewSigns-740353-5778_to_NEC-2192-02::SouthJune2WKNDNewSigns-739523-5878
FB-0095-04::SouthJune2WKNDNewSigns-740354-5784_to_NEC-2192-02::SouthJune2WKNDNewSigns-739524-5884
FB-0095-04::SouthJune2WKNDNewSigns-740356-5792_to_NEC-2192-02::SouthJune2WKNDNewSigns-739526-5892
FB-0095-05::SouthJune2WKNDNewSigns-740341-5724_to_NEC-2192-02::SouthJune2WKNDNewSigns-739511-5824
FB-0095-05::SouthJune2WKNDNewSigns-740342-5730_to_NEC-2192-02::SouthJune2WKNDNewSigns-739512-5830
FB-0095-05::SouthJune2WKNDNewSigns-740344-5738_to_NEC-2192-02::SouthJune2WKNDNewSigns-739514-5838
FB-0095-05::SouthJune2WKNDNewSigns-740346-5746_to_NEC-2192-02::SouthJune2WKNDNewSigns-739516-5846
FB-0095-05::SouthJune2WKNDNewSigns-740348-5754_to_NEC-2192-02::SouthJune2WKNDNewSigns-739519-5856
FB-0095-05::SouthJune2WKNDNewSigns-740351-5768_to_NEC-2192-02::SouthJune2WKNDNewSigns-739521-5868
FR-0301-02::NorthJune2WKDY-739812-1427_to_FR-0301-01::NorthJune2WKDY-739879-429
FR-0301-02::SPRING2025V2-728445-1427_to_FR-0301-01::SPRING2025V2-728489-429
NBM-0374-01::SPRING2025V2-715751-1905_to_NBM-0374-02::SPRING2025V2-715798-2055
NBM-0374-01::SPRING2025V2-715753-1909_to_NBM-0374-02::SPRING2025V2-715799-2059
NBM-0374-01::SPRING2025V2-715756-1915_to_NBM-0374-02::SPRING2025V2-715802-2065
NBM-0374-01::SPRING2025V2-715757-1917_to_NBM-0374-02::SPRING2025V2-715803-2067
NBM-0374-01::SPRING2025V2-715759-1911_to_NBM-0374-02::SPRING2025V2-715800-2061
NBM-0374-01::SPRING2025V2-715760-1925_to_NBM-0374-02::SPRING2025V2-715805-2075
NBM-0374-01::SPRING2025V2-715763-1939_to_NBM-0374-02::SPRING2025V2-715807-2089
NBM-0374-01::SPRING2025V2-715765-1945_to_NBM-0374-02::SPRING2025V2-715809-2095
NBM-0374-01::SPRING2025V2-715784-2021_to_NBM-0374-02::SPRING2025V2-715768-1971
NBM-0374-01::SPRING2025V2-715791-2033_to_NBM-0374-02::SPRING2025V2-715774-1983
NBM-0374-01::SPRING2025V2-715793-2037_to_NBM-0374-02::SPRING2025V2-715776-1987
NBM-0374-01::SPRING2025V2-715795-2041_to_NBM-0374-02::SPRING2025V2-715778-1991
NBM-0374-01::SPRING2025V2-715797-2047_to_NBM-0374-02::SPRING2025V2-715780-1997
NBM-0374-01::SPRING2025V2-721933-1919_to_NBM-0374-02::SPRING2025V2-715804-2069
NBM-0374-01::SPRING2025V3-716284-7029_to_NBM-0374-02::SPRING2025V3-716274-6979
NBM-0374-01::SouthJune2WKDY-739075-1905_to_NBM-0374-02::SouthJune2WKDY-739120-2055
NBM-0374-01::SouthJune2WKDY-739077-1909_to_NBM-0374-02::SouthJune2WKDY-739121-2059
NBM-0374-01::SouthJune2WKDY-739079-1915_to_NBM-0374-02::SouthJune2WKDY-739124-2065
NBM-0374-01::SouthJune2WKDY-739080-1917_to_NBM-0374-02::SouthJune2WKDY-739125-2067
NBM-0374-01::SouthJune2WKDY-739082-1911_to_NBM-0374-02::SouthJune2WKDY-739122-2061
NBM-0374-01::SouthJune2WKDY-739083-1925_to_NBM-0374-02::SouthJune2WKDY-739127-2075
NBM-0374-01::SouthJune2WKDY-739086-1939_to_NBM-0374-02::SouthJune2WKDY-739129-2089
NBM-0374-01::SouthJune2WKDY-739088-1945_to_NBM-0374-02::SouthJune2WKDY-739131-2095
NBM-0374-01::SouthJune2WKDY-739106-2021_to_NBM-0374-02::SouthJune2WKDY-739091-1971
NBM-0374-01::SouthJune2WKDY-739113-2033_to_NBM-0374-02::SouthJune2WKDY-739096-1983
NBM-0374-01::SouthJune2WKDY-739115-2037_to_NBM-0374-02::SouthJune2WKDY-739098-1987
NBM-0374-01::SouthJune2WKDY-739117-2041_to_NBM-0374-02::SouthJune2WKDY-739100-1991
NBM-0374-01::SouthJune2WKDY-739119-2047_to_NBM-0374-02::SouthJune2WKDY-739102-1997
NBM-0374-01::SouthJune2WKDY-739488-1919_to_NBM-0374-02::SouthJune2WKDY-739126-2069
NBM-0374-01::SouthJune2WKNDNewSigns-739616-7029_to_NBM-0374-02::SouthJune2WKNDNewSigns-739606-6979
NBM-0374-02::SPRING2025V2-715766-1960_to_NBM-0374-01::SPRING2025V2-715782-2010
NBM-0374-02::SPRING2025V2-715767-1966_to_NBM-0374-01::SPRING2025V2-715783-2016
NBM-0374-02::SPRING2025V2-715769-1972_to_NBM-0374-01::SPRING2025V2-715785-2022
NBM-0374-02::SPRING2025V2-715770-1974_to_NBM-0374-01::SPRING2025V2-715786-2024
NBM-0374-02::SPRING2025V2-715772-1978_to_NBM-0374-01::SPRING2025V2-715788-2028
NBM-0374-02::SPRING2025V2-715773-1980_to_NBM-0374-01::SPRING2025V2-715790-2030
NBM-0374-02::SPRING2025V2-715775-1976_to_NBM-0374-01::SPRING2025V2-715787-2026
NBM-0374-02::SPRING2025V2-715777-1988_to_NBM-0374-01::SPRING2025V2-715794-2038
NBM-0374-02::SPRING2025V2-715779-1994_to_NBM-0374-01::SPRING2025V2-715796-2044
NBM-0374-02::SPRING2025V2-715801-2062_to_NBM-0374-01::SPRING2025V2-715755-1912
NBM-0374-02::SPRING2025V2-715806-2086_to_NBM-0374-01::SPRING2025V2-715762-1936
NBM-0374-02::SPRING2025V2-715808-2092_to_NBM-0374-01::SPRING2025V2-715764-1942
NBM-0374-02::SPRING2025V2-721930-1984_to_NBM-0374-01::SPRING2025V2-715792-2034
NBM-0374-02::SouthJune2WKDY-739089-1960_to_NBM-0374-01::SouthJune2WKDY-739104-2010
NBM-0374-02::SouthJune2WKDY-739090-1966_to_NBM-0374-01::SouthJune2WKDY-739105-2016
NBM-0374-02::SouthJune2WKDY-739092-1972_to_NBM-0374-01::SouthJune2WKDY-739107-2022
NBM-0374-02::SouthJune2WKDY-739093-1974_to_NBM-0374-01::SouthJune2WKDY-739108-2024
NBM-0374-02::SouthJune2WKDY-739094-1978_to_NBM-0374-01::SouthJune2WKDY-739110-2028
NBM-0374-02::SouthJune2WKDY-739095-1980_to_NBM-0374-01::SouthJune2WKDY-739112-2030
NBM-0374-02::SouthJune2WKDY-739097-1976_to_NBM-0374-01::SouthJune2WKDY-739109-2026
NBM-0374-02::SouthJune2WKDY-739099-1988_to_NBM-0374-01::SouthJune2WKDY-739116-2038
NBM-0374-02::SouthJune2WKDY-739101-1994_to_NBM-0374-01::SouthJune2WKDY-739118-2044
NBM-0374-02::SouthJune2WKDY-739123-2062_to_NBM-0374-01::SouthJune2WKDY-739078-1912
NBM-0374-02::SouthJune2WKDY-739128-2086_to_NBM-0374-01::SouthJune2WKDY-739085-1936
NBM-0374-02::SouthJune2WKDY-739130-2092_to_NBM-0374-01::SouthJune2WKDY-739087-1942
NBM-0374-02::SouthJune2WKDY-739485-1984_to_NBM-0374-01::SouthJune2WKDY-739114-2034
NEC-2192-03::AttleboroWork-715947-875_to_FB-0095-04::AttleboroWork-715747-1775
NEC-2192-03::AttleboroWork-715950-885_to_FB-0095-04::AttleboroWork-715749-1785
NEC-2192-03::AttleboroWork-715954-893_to_FB-0095-04::AttleboroWork-715912-793
NEC-2192-03::AttleboroWork-716177-5815_to_FB-0095-04::AttleboroWork-717750-5715
NEC-2192-03::AttleboroWork-716178-5821_to_FB-0095-04::AttleboroWork-717757-5721
NEC-2192-03::AttleboroWork-716181-5831_to_FB-0095-04::AttleboroWork-717756-5731
NEC-2192-03::AttleboroWork-716183-5839_to_FB-0095-04::AttleboroWork-717759-5739
NEC-2192-03::AttleboroWork-716185-5847_to_FB-0095-04::AttleboroWork-717758-5747
NEC-2192-03::AttleboroWork-716186-5855_to_FB-0095-04::AttleboroWork-717760-5755
NEC-2192-03::AttleboroWork-716188-5867_to_FB-0095-04::AttleboroWork-717762-5767
NEC-2192-03::AttleboroWork-716190-5877_to_FB-0095-04::AttleboroWork-717763-5777
NEC-2192-03::AttleboroWork-716193-5885_to_FB-0095-04::AttleboroWork-717764-5785
NEC-2192-03::AttleboroWork-716195-5893_to_FB-0095-04::AttleboroWork-717767-5793
NEC-2192-03::SouthJune2WKDY-739224-875_to_FB-0095-04::SouthJune2WKDY-739071-1775
NEC-2192-03::SouthJune2WKDY-739227-885_to_FB-0095-04::SouthJune2WKDY-739073-1785
NEC-2192-03::SouthJune2WKDY-739231-893_to_FB-0095-04::SouthJune2WKDY-739189-793
NEC-2192-03::SouthJune2WKNDNewSigns-739509-5815_to_FB-0095-04::SouthJune2WKNDNewSigns-740339-5715
NEC-2192-03::SouthJune2WKNDNewSigns-739510-5821_to_FB-0095-05::SouthJune2WKNDNewSigns-740340-5721
NEC-2192-03::SouthJune2WKNDNewSigns-739513-5831_to_FB-0095-05::SouthJune2WKNDNewSigns-740343-5731
NEC-2192-03::SouthJune2WKNDNewSigns-739515-5839_to_FB-0095-05::SouthJune2WKNDNewSigns-740345-5739
NEC-2192-03::SouthJune2WKNDNewSigns-739517-5847_to_FB-0095-05::SouthJune2WKNDNewSigns-740347-5747
NEC-2192-03::SouthJune2WKNDNewSigns-739518-5855_to_FB-0095-05::SouthJune2WKNDNewSigns-740349-5755
NEC-2192-03::SouthJune2WKNDNewSigns-739520-5867_to_FB-0095-05::SouthJune2WKNDNewSigns-740350-5767
NEC-2192-03::SouthJune2WKNDNewSigns-739522-5877_to_FB-0095-05::SouthJune2WKNDNewSigns-740352-5777
NEC-2192-03::SouthJune2WKNDNewSigns-739525-5885_to_FB-0095-04::SouthJune2WKNDNewSigns-740355-5785
NEC-2192-03::SouthJune2WKNDNewSigns-739527-5893_to_FB-0095-04::SouthJune2WKNDNewSigns-740357-5793
NEC-2237-03::AttleboroWork-715952-889_to_NEC-2237-05::AttleboroWork-715885-689
NEC-2237-03::AttleboroWork-715954-893_to_NEC-2237-05::AttleboroWork-715886-693
NEC-2237-03::SouthJune2WKDY-739229-889_to_NEC-2237-05::SouthJune2WKDY-739164-689
NEC-2237-03::SouthJune2WKDY-739231-893_to_NEC-2237-05::SouthJune2WKDY-739165-693
WML-0199-02::SPRING2025V2-716065-1561_to_WML-0199-01::SPRING2025V2-716088-565
WML-0199-02::SPRING2025V2-716070-1555_to_WML-0199-01::SPRING2025V2-716090-559
WML-0199-02::SPRING2025V2-716071-1551_to_WML-0199-01::SPRING2025V2-716093-553
WML-0199-02::SouthJune2WKDY-739277-1561_to_WML-0199-01::SouthJune2WKDY-739300-565
WML-0199-02::SouthJune2WKDY-739282-1555_to_WML-0199-01::SouthJune2WKDY-739302-559
WML-0199-02::SouthJune2WKDY-739283-1551_to_WML-0199-01::SouthJune2WKDY-739304-553
WML-0199-02::WMLFriday-733050-1561_to_WML-0199-01::WMLFriday-733073-565
WML-0199-02::WMLFriday-733055-1555_to_WML-0199-01::WMLFriday-733075-559
WML-0199-02::WMLFriday-733056-1551_to_WML-0199-01::WMLFriday-733077-553
WML-0214-02::SPRING2025V2-716089-560_to_WML-0214-01::SPRING2025V2-716068-1562
WML-0214-02::SPRING2025V2-716091-556_to_WML-0214-01::SPRING2025V2-716069-1558
WML-0214-02::SPRING2025V2-716109-520_to_WML-0214-01::SPRING2025V2-716072-1522
WML-0214-02::SouthJune2WKDY-739301-560_to_WML-0214-01::SouthJune2WKDY-739280-1562
WML-0214-02::SouthJune2WKDY-739303-556_to_WML-0214-01::SouthJune2WKDY-739281-1558
WML-0214-02::SouthJune2WKDY-739318-520_to_WML-0214-01::SouthJune2WKDY-739284-1522
WML-0214-02::WMLFriday-733074-560_to_WML-0214-01::WMLFriday-733053-1562
WML-0214-02::WMLFriday-733076-556_to_WML-0214-01::WMLFriday-733054-1558
WML-0214-02::WMLFriday-733091-520_to_WML-0214-01::WMLFriday-733057-1522
WR-0325-01::NorthJune2WKDY-739831-209-HaverhillBradfordVan_to_WR-0325-B::NorthJune2WKDY-739831-209-HaverhillBradfordVanV1
WR-0325-01::NorthJune2WKDY-739835-223-HaverhillBradfordVan_to_WR-0325-B::NorthJune2WKDY-739835-223-HaverhillBradfordVanV1
WR-0325-01::NorthJune2WKDY-739837-229-HaverhillBradfordVan_to_WR-0325-B::NorthJune2WKDY-739837-229-HaverhillBradfordVanV1
WR-0325-01::NorthJune2WKDY-739839-235-HaverhillBradfordVan_to_WR-0325-B::NorthJune2WKDY-739839-235-HaverhillBradfordVanV1
WR-0325-01::NorthJune2WKDY-739842-241-HaverhillBradfordVan_to_WR-0325-B::NorthJune2WKDY-739842-241-HaverhillBradfordVanV1
WR-0325-01::NorthJune2WKDY-739844-247-HaverhillBradfordVan_to_WR-0325-B::NorthJune2WKDY-739844-247-HaverhillBradfordVanV1
WR-0325-01::NorthJune2WKDY-739846-255-HaverhillBradfordVan_to_WR-0325-B::NorthJune2WKDY-739846-255-HaverhillBradfordVanV1
WR-0325-01::NorthJune2WKDY-739848-259-HaverhillBradfordVan_to_WR-0325-B::NorthJune2WKDY-739848-259-HaverhillBradfordVanV1
WR-0325-01::NorthJune2WKDY-739849-265-HaverhillBradfordVan_to_WR-0325-B::NorthJune2WKDY-739849-265-HaverhillBradfordVanV1
WR-0325-01::NorthJune2WKDY-739852-271-HaverhillBradfordVan_to_WR-0325-B::NorthJune2WKDY-739852-271-HaverhillBradfordVanV1
WR-0325-01::NorthJune2WKDY-739854-277-HaverhillBradfordVan_to_WR-0325-B::NorthJune2WKDY-739854-277-HaverhillBradfordVanV1
WR-0325-01::NorthJune2WKDY-739857-285-HaverhillBradfordVan_to_WR-0325-B::NorthJune2WKDY-739857-285-HaverhillBradfordVanV1
WR-0325-01::NorthJune2WKDY-739858-293-HaverhillBradfordVan_to_WR-0325-B::NorthJune2WKDY-739858-293-HaverhillBradfordVanV1
WR-0325-01::NorthJune2WKND-740085-5217-HaverhillBradfordVan_to_WR-0325-B::NorthJune2WKND-740085-5217-HaverhillBradfordVanV1
WR-0325-01::NorthJune2WKND-740087-5225-HaverhillBradfordVan_to_WR-0325-B::NorthJune2WKND-740087-5225-HaverhillBradfordVanV1
WR-0325-01::NorthJune2WKND-740089-5235-HaverhillBradfordVan_to_WR-0325-B::NorthJune2WKND-740089-5235-HaverhillBradfordVanV1
WR-0325-01::NorthJune2WKND-740091-5243-HaverhillBradfordVan_to_WR-0325-B::NorthJune2WKND-740091-5243-HaverhillBradfordVanV1
WR-0325-01::NorthJune2WKND-740092-5251-HaverhillBradfordVan_to_WR-0325-B::NorthJune2WKND-740092-5251-HaverhillBradfordVanV1
WR-0325-01::NorthJune2WKND-740095-5263-HaverhillBradfordVan_to_WR-0325-B::NorthJune2WKND-740095-5263-HaverhillBradfordVanV1
WR-0325-01::NorthJune2WKND-740097-5279-HaverhillBradfordVan_to_WR-0325-B::NorthJune2WKND-740097-5279-HaverhillBradfordVanV1
WR-0325-01::NorthJune2WKND-740099-5291-HaverhillBradfordVan_to_WR-0325-B::NorthJune2WKND-740099-5291-HaverhillBradfordVanV1
WR-0325-01::SPRING2025-728170-5217-HaverhillBradfordVan_to_WR-0325-B::SPRING2025-728170-5217-HaverhillBradfordVanV1
WR-0325-01::SPRING2025-728172-5225-HaverhillBradfordVan_to_WR-0325-B::SPRING2025-728172-5225-HaverhillBradfordVanV1
WR-0325-01::SPRING2025-728174-5235-HaverhillBradfordVan_to_WR-0325-B::SPRING2025-728174-5235-HaverhillBradfordVanV1
WR-0325-01::SPRING2025-728176-5243-HaverhillBradfordVan_to_WR-0325-B::SPRING2025-728176-5243-HaverhillBradfordVanV1
WR-0325-01::SPRING2025-728177-5251-HaverhillBradfordVan_to_WR-0325-B::SPRING2025-728177-5251-HaverhillBradfordVanV1
WR-0325-01::SPRING2025-728180-5263-HaverhillBradfordVan_to_WR-0325-B::SPRING2025-728180-5263-HaverhillBradfordVanV1
WR-0325-01::SPRING2025-728182-5279-HaverhillBradfordVan_to_WR-0325-B::SPRING2025-728182-5279-HaverhillBradfordVanV1
WR-0325-01::SPRING2025-728184-5291-HaverhillBradfordVan_to_WR-0325-B::SPRING2025-728184-5291-HaverhillBradfordVanV1
WR-0325-01::SPRING2025V2-728449-209-HaverhillBradfordVan_to_WR-0325-B::SPRING2025V2-728449-209-HaverhillBradfordVanV1
WR-0325-01::SPRING2025V2-728452-223-HaverhillBradfordVan_to_WR-0325-B::SPRING2025V2-728452-223-HaverhillBradfordVanV1
WR-0325-01::SPRING2025V2-728454-229-HaverhillBradfordVan_to_WR-0325-B::SPRING2025V2-728454-229-HaverhillBradfordVanV1
WR-0325-01::SPRING2025V2-728456-235-HaverhillBradfordVan_to_WR-0325-B::SPRING2025V2-728456-235-HaverhillBradfordVanV1
WR-0325-01::SPRING2025V2-728458-241-HaverhillBradfordVan_to_WR-0325-B::SPRING2025V2-728458-241-HaverhillBradfordVanV1
WR-0325-01::SPRING2025V2-728460-247-HaverhillBradfordVan_to_WR-0325-B::SPRING2025V2-728460-247-HaverhillBradfordVanV1
WR-0325-01::SPRING2025V2-728462-255-HaverhillBradfordVan_to_WR-0325-B::SPRING2025V2-728462-255-HaverhillBradfordVanV1
WR-0325-01::SPRING2025V2-728464-259-HaverhillBradfordVan_to_WR-0325-B::SPRING2025V2-728464-259-HaverhillBradfordVanV1
WR-0325-01::SPRING2025V2-728465-265-HaverhillBradfordVan_to_WR-0325-B::SPRING2025V2-728465-265-HaverhillBradfordVanV1
WR-0325-01::SPRING2025V2-728467-271-HaverhillBradfordVan_to_WR-0325-B::SPRING2025V2-728467-271-HaverhillBradfordVanV1
WR-0325-01::SPRING2025V2-728469-277-HaverhillBradfordVan_to_WR-0325-B::SPRING2025V2-728469-277-HaverhillBradfordVanV1
WR-0325-01::SPRING2025V2-728471-285-HaverhillBradfordVan_to_WR-0325-B::SPRING2025V2-728471-285-HaverhillBradfordVanV1
WR-0325-01::SPRING2025V2-728472-293-HaverhillBradfordVan_to_WR-0325-B::SPRING2025V2-728472-293-HaverhillBradfordVanV1
WR-0325-B::NorthJune2WKDY-739830-208-HaverhillBradfordVanV1_to_WR-0325-01::NorthJune2WKDY-739830-208-HaverhillBradfordVan
WR-0325-B::NorthJune2WKDY-739833-212-HaverhillBradfordVanV1_to_WR-0325-01::NorthJune2WKDY-739833-212-HaverhillBradfordVan
WR-0325-B::NorthJune2WKDY-739834-218-HaverhillBradfordVanV1_to_WR-0325-01::NorthJune2WKDY-739834-218-HaverhillBradfordVan
WR-0325-B::NorthJune2WKDY-739836-224-HaverhillBradfordVanV1_to_WR-0325-01::NorthJune2WKDY-739836-224-HaverhillBradfordVan
WR-0325-B::NorthJune2WKDY-739838-232-HaverhillBradfordVanV1_to_WR-0325-01::NorthJune2WKDY-739838-232-HaverhillBradfordVan
WR-0325-B::NorthJune2WKDY-739840-238-HaverhillBradfordVanV1_to_WR-0325-01::NorthJune2WKDY-739840-238-HaverhillBradfordVan
WR-0325-B::NorthJune2WKDY-739843-244-HaverhillBradfordVanV1_to_WR-0325-01::NorthJune2WKDY-739843-244-HaverhillBradfordVan
WR-0325-B::NorthJune2WKDY-739845-250-HaverhillBradfordVanV1_to_WR-0325-01::NorthJune2WKDY-739845-250-HaverhillBradfordVan
WR-0325-B::NorthJune2WKDY-739847-256-HaverhillBradfordVanV1_to_WR-0325-01::NorthJune2WKDY-739847-256-HaverhillBradfordVan
WR-0325-B::NorthJune2WKDY-739850-266-HaverhillBradfordVanV1_to_WR-0325-01::NorthJune2WKDY-739850-266-HaverhillBradfordVan
WR-0325-B::NorthJune2WKDY-739853-274-HaverhillBradfordVanV1_to_WR-0325-01::NorthJune2WKDY-739853-274-HaverhillBradfordVan
WR-0325-B::NorthJune2WKDY-739856-282-HaverhillBradfordVanV1_to_WR-0325-01::NorthJune2WKDY-739856-282-HaverhillBradfordVan
WR-0325-B::NorthJune2WKND-740084-5208-HaverhillBradfordVanV1_to_WR-0325-01::NorthJune2WKND-740084-5208-HaverhillBradfordVan
WR-0325-B::NorthJune2WKND-740086-5224-HaverhillBradfordVanV1_to_WR-0325-01::NorthJune2WKND-740086-5224-HaverhillBradfordVan
WR-0325-B::NorthJune2WKND-740088-5234-HaverhillBradfordVanV1_to_WR-0325-01::NorthJune2WKND-740088-5234-HaverhillBradfordVan
WR-0325-B::NorthJune2WKND-740090-5242-HaverhillBradfordVanV1_to_WR-0325-01::NorthJune2WKND-740090-5242-HaverhillBradfordVan
WR-0325-B::NorthJune2WKND-740093-5252-HaverhillBradfordVanV1_to_WR-0325-01::NorthJune2WKND-740093-5252-HaverhillBradfordVan
WR-0325-B::NorthJune2WKND-740094-5262-HaverhillBradfordVanV1_to_WR-0325-01::NorthJune2WKND-740094-5262-HaverhillBradfordVan
WR-0325-B::NorthJune2WKND-740096-5274-HaverhillBradfordVanV1_to_WR-0325-01::NorthJune2WKND-740096-5274-HaverhillBradfordVan
WR-0325-B::NorthJune2WKND-740098-5284-HaverhillBradfordVanV1_to_WR-0325-01::NorthJune2WKND-740098-5284-HaverhillBradfordVan
WR-0325-B::SPRING2025-728169-5208-HaverhillBradfordVanV1_to_WR-0325-01::SPRING2025-728169-5208-HaverhillBradfordVan
WR-0325-B::SPRING2025-728171-5224-HaverhillBradfordVanV1_to_WR-0325-01::SPRING2025-728171-5224-HaverhillBradfordVan
WR-0325-B::SPRING2025-728173-5234-HaverhillBradfordVanV1_to_WR-0325-01::SPRING2025-728173-5234-HaverhillBradfordVan
WR-0325-B::SPRING2025-728175-5242-HaverhillBradfordVanV1_to_WR-0325-01::SPRING2025-728175-5242-HaverhillBradfordVan
WR-0325-B::SPRING2025-728178-5252-HaverhillBradfordVanV1_to_WR-0325-01::SPRING2025-728178-5252-HaverhillBradfordVan
WR-0325-B::SPRING2025-728179-5262-HaverhillBradfordVanV1_to_WR-0325-01::SPRING2025-728179-5262-HaverhillBradfordVan
WR-0325-B::SPRING2025-728181-5274-HaverhillBradfordVanV1_to_WR-0325-01::SPRING2025-728181-5274-HaverhillBradfordVan
WR-0325-B::SPRING2025-728183-5284-HaverhillBradfordVanV1_to_WR-0325-01::SPRING2025-728183-5284-HaverhillBradfordVan
WR-0325-B::SPRING2025V2-728448-208-HaverhillBradfordVanV1_to_WR-0325-01::SPRING2025V2-728448-208-HaverhillBradfordVan
WR-0325-B::SPRING2025V2-728450-212-HaverhillBradfordVanV1_to_WR-0325-01::SPRING2025V2-728450-212-HaverhillBradfordVan
WR-0325-B::SPRING2025V2-728451-218-HaverhillBradfordVanV1_to_WR-0325-01::SPRING2025V2-728451-218-HaverhillBradfordVan
WR-0325-B::SPRING2025V2-728453-224-HaverhillBradfordVanV1_to_WR-0325-01::SPRING2025V2-728453-224-HaverhillBradfordVan
WR-0325-B::SPRING2025V2-728455-232-HaverhillBradfordVanV1_to_WR-0325-01::SPRING2025V2-728455-232-HaverhillBradfordVan
WR-0325-B::SPRING2025V2-728457-238-HaverhillBradfordVanV1_to_WR-0325-01::SPRING2025V2-728457-238-HaverhillBradfordVan
WR-0325-B::SPRING2025V2-728459-244-HaverhillBradfordVanV1_to_WR-0325-01::SPRING2025V2-728459-244-HaverhillBradfordVan
WR-0325-B::SPRING2025V2-728461-250-HaverhillBradfordVanV1_to_WR-0325-01::SPRING2025V2-728461-250-HaverhillBradfordVan
WR-0325-B::SPRING2025V2-728463-256-HaverhillBradfordVanV1_to_WR-0325-01::SPRING2025V2-728463-256-HaverhillBradfordVan
WR-0325-B::SPRING2025V2-728466-266-HaverhillBradfordVanV1_to_WR-0325-01::SPRING2025V2-728466-266-HaverhillBradfordVan
WR-0325-B::SPRING2025V2-728468-274-HaverhillBradfordVanV1_to_WR-0325-01::SPRING2025V2-728468-274-HaverhillBradfordVan
WR-0325-B::SPRING2025V2-728470-282-HaverhillBradfordVanV1_to_WR-0325-01::SPRING2025V2-728470-282-HaverhillBradfordVan

milas avatar May 31 '25 18:05 milas

FYI I am now hosting an instance @ https://transiter.mbta.wtf !

[It's using the changes I mentioned above to ignore the "trip" transfers.]

(It's behind a CDN w/ hard-coded 10 sec caching. But running on arm64 as well 😉)

milas avatar May 31 '25 20:05 milas

The plan above sounds good! Although, I wonder should the API distinguish between different types of transfers at all? I'm thinking e.g. that the API could just return all transfers including ones with the trips/routes attached. And then it's up to the API consumer to filter those out.

jamespfennell avatar Jul 16 '25 15:07 jamespfennell