PyTransportNSWv2 0.9.0__tar.gz → 0.9.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyTransportNSWv2
3
- Version: 0.9.0
3
+ Version: 0.9.2
4
4
  Summary: Get detailed per-trip transport information from TransportNSW
5
5
  Home-page: https://github.com/andystewart999/TransportNSW
6
6
  Author: andystewart999
@@ -23,8 +23,51 @@ Description: # TransportNSWv2
23
23
  ### API Documentation
24
24
  The source API details can be found here: https://opendata.transport.nsw.gov.au/sites/default/files/2023-08/Trip%20Planner%20API%20manual-opendataproduction%20v3.2.pdf
25
25
 
26
- ### Parameters
27
- Only the first three paramters are mandatory, the rest are optional. All parameters and their defaults are as follows:
26
+ ### Exposed functions
27
+ Two functions are available:
28
+ ```get_trip()``` returns trip information between two stop IDs
29
+ ```check_stops()``` lets you confirm that the two stop IDs are valid, plus it returns all the stop ID metadata. Note that ```get_trip()``` calls this function internally and fails relatively gracefully if either of the stop IDs are invalid, so there's no specific need to call ```check_stops()``` unless you want the stop ID metadata.
30
+
31
+ ### check_stops() parameters
32
+ All parameters are mandatory. Note that ```stop_list``` can be a single string or a list of strings:
33
+ ```.check_stops(api_key, stop_list)```
34
+
35
+ The return is a JSON-compatible Python object as per the example here:
36
+ ```
37
+ {
38
+ "all_stops_valid": true,
39
+ "stop_list": [
40
+ {
41
+ "stop_id": "200060",
42
+ "valid": true,
43
+ "error_code": 0,
44
+ "stop_detail": {
45
+ "id": "200060",
46
+ "name": "Central Station, Sydney",
47
+ "disassembledName": "Central Station",
48
+ <etc, as per the Transport NSW API>
49
+ }
50
+ }
51
+ },
52
+ {
53
+ "stop_id": "229310",
54
+ "valid": true,
55
+ "error_code": 0,
56
+ "stop_detail": {
57
+ "id": "229310",
58
+ "name": "Newcastle Interchange, Wickham",
59
+ "disassembledName": "Newcastle Interchange",
60
+ <etc, as per the Transport NSW API>
61
+ }
62
+ }
63
+ ]
64
+ }
65
+ ```
66
+ Most of the top-level properties are pretty self-explanatory. If all you want to do is get a general yes/no then ```all_stops_valid``` is the quickest check. If any of the stops are invalid or there was an error calling the stop-finder API then ```error_code``` will point you to the issue. If the API call was successful then ```stop_detail``` will contain everything that the API sent back for the closest match it found.
67
+
68
+
69
+ ### get_trip() parameters
70
+ Only the first three parameters are mandatory, the rest are optional. All parameters and their defaults are as follows:
28
71
  ```python
29
72
  .get_trip(origin_stop_id, destination_stop_id, api_key, trip_wait_time = 0, transport_type = 0, strict_transport_type = False, raw_output = False, journeys_to_return = 1, route_filter = '', include_realtime_location = True, include_alerts = 'none', alert_type = 'all', check_stop_ids = True, forced_gtfs_uri = [])
30
73
  ```
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyTransportNSWv2
3
- Version: 0.9.0
3
+ Version: 0.9.2
4
4
  Summary: Get detailed per-trip transport information from TransportNSW
5
5
  Home-page: https://github.com/andystewart999/TransportNSW
6
6
  Author: andystewart999
@@ -23,8 +23,51 @@ Description: # TransportNSWv2
23
23
  ### API Documentation
24
24
  The source API details can be found here: https://opendata.transport.nsw.gov.au/sites/default/files/2023-08/Trip%20Planner%20API%20manual-opendataproduction%20v3.2.pdf
25
25
 
26
- ### Parameters
27
- Only the first three paramters are mandatory, the rest are optional. All parameters and their defaults are as follows:
26
+ ### Exposed functions
27
+ Two functions are available:
28
+ ```get_trip()``` returns trip information between two stop IDs
29
+ ```check_stops()``` lets you confirm that the two stop IDs are valid, plus it returns all the stop ID metadata. Note that ```get_trip()``` calls this function internally and fails relatively gracefully if either of the stop IDs are invalid, so there's no specific need to call ```check_stops()``` unless you want the stop ID metadata.
30
+
31
+ ### check_stops() parameters
32
+ All parameters are mandatory. Note that ```stop_list``` can be a single string or a list of strings:
33
+ ```.check_stops(api_key, stop_list)```
34
+
35
+ The return is a JSON-compatible Python object as per the example here:
36
+ ```
37
+ {
38
+ "all_stops_valid": true,
39
+ "stop_list": [
40
+ {
41
+ "stop_id": "200060",
42
+ "valid": true,
43
+ "error_code": 0,
44
+ "stop_detail": {
45
+ "id": "200060",
46
+ "name": "Central Station, Sydney",
47
+ "disassembledName": "Central Station",
48
+ <etc, as per the Transport NSW API>
49
+ }
50
+ }
51
+ },
52
+ {
53
+ "stop_id": "229310",
54
+ "valid": true,
55
+ "error_code": 0,
56
+ "stop_detail": {
57
+ "id": "229310",
58
+ "name": "Newcastle Interchange, Wickham",
59
+ "disassembledName": "Newcastle Interchange",
60
+ <etc, as per the Transport NSW API>
61
+ }
62
+ }
63
+ ]
64
+ }
65
+ ```
66
+ Most of the top-level properties are pretty self-explanatory. If all you want to do is get a general yes/no then ```all_stops_valid``` is the quickest check. If any of the stops are invalid or there was an error calling the stop-finder API then ```error_code``` will point you to the issue. If the API call was successful then ```stop_detail``` will contain everything that the API sent back for the closest match it found.
67
+
68
+
69
+ ### get_trip() parameters
70
+ Only the first three parameters are mandatory, the rest are optional. All parameters and their defaults are as follows:
28
71
  ```python
29
72
  .get_trip(origin_stop_id, destination_stop_id, api_key, trip_wait_time = 0, transport_type = 0, strict_transport_type = False, raw_output = False, journeys_to_return = 1, route_filter = '', include_realtime_location = True, include_alerts = 'none', alert_type = 'all', check_stop_ids = True, forced_gtfs_uri = [])
30
73
  ```
@@ -15,8 +15,51 @@ If it's available, the general occupancy level and the latitude and longitude of
15
15
  ### API Documentation
16
16
  The source API details can be found here: https://opendata.transport.nsw.gov.au/sites/default/files/2023-08/Trip%20Planner%20API%20manual-opendataproduction%20v3.2.pdf
17
17
 
18
- ### Parameters
19
- Only the first three paramters are mandatory, the rest are optional. All parameters and their defaults are as follows:
18
+ ### Exposed functions
19
+ Two functions are available:
20
+ ```get_trip()``` returns trip information between two stop IDs
21
+ ```check_stops()``` lets you confirm that the two stop IDs are valid, plus it returns all the stop ID metadata. Note that ```get_trip()``` calls this function internally and fails relatively gracefully if either of the stop IDs are invalid, so there's no specific need to call ```check_stops()``` unless you want the stop ID metadata.
22
+
23
+ ### check_stops() parameters
24
+ All parameters are mandatory. Note that ```stop_list``` can be a single string or a list of strings:
25
+ ```.check_stops(api_key, stop_list)```
26
+
27
+ The return is a JSON-compatible Python object as per the example here:
28
+ ```
29
+ {
30
+ "all_stops_valid": true,
31
+ "stop_list": [
32
+ {
33
+ "stop_id": "200060",
34
+ "valid": true,
35
+ "error_code": 0,
36
+ "stop_detail": {
37
+ "id": "200060",
38
+ "name": "Central Station, Sydney",
39
+ "disassembledName": "Central Station",
40
+ <etc, as per the Transport NSW API>
41
+ }
42
+ }
43
+ },
44
+ {
45
+ "stop_id": "229310",
46
+ "valid": true,
47
+ "error_code": 0,
48
+ "stop_detail": {
49
+ "id": "229310",
50
+ "name": "Newcastle Interchange, Wickham",
51
+ "disassembledName": "Newcastle Interchange",
52
+ <etc, as per the Transport NSW API>
53
+ }
54
+ }
55
+ ]
56
+ }
57
+ ```
58
+ Most of the top-level properties are pretty self-explanatory. If all you want to do is get a general yes/no then ```all_stops_valid``` is the quickest check. If any of the stops are invalid or there was an error calling the stop-finder API then ```error_code``` will point you to the issue. If the API call was successful then ```stop_detail``` will contain everything that the API sent back for the closest match it found.
59
+
60
+
61
+ ### get_trip() parameters
62
+ Only the first three parameters are mandatory, the rest are optional. All parameters and their defaults are as follows:
20
63
  ```python
21
64
  .get_trip(origin_stop_id, destination_stop_id, api_key, trip_wait_time = 0, transport_type = 0, strict_transport_type = False, raw_output = False, journeys_to_return = 1, route_filter = '', include_realtime_location = True, include_alerts = 'none', alert_type = 'all', check_stop_ids = True, forced_gtfs_uri = [])
22
65
  ```
@@ -4,8 +4,9 @@
4
4
 
5
5
  from datetime import datetime, timedelta
6
6
  from google.transit import gtfs_realtime_pb2
7
- import requests.exceptions
7
+
8
8
  import requests
9
+
9
10
  import logging
10
11
  import re
11
12
  import json #For the output
@@ -76,6 +77,110 @@ class TransportNSWv2(object):
76
77
  ATTR_ALERTS: '[]'
77
78
  }
78
79
 
80
+
81
+ def check_stops(self, api_key, stops):
82
+ # Check the list of stops and return a JSON array of the stop details, plus if all the checked stops existed
83
+ # Return a JSON array of the results
84
+
85
+ # Sanity checking
86
+ if isinstance(stops, str):
87
+ # If it's a single string, convert it to a list
88
+ stops = [stops]
89
+
90
+ auth = 'apikey ' + api_key
91
+ header = {'Accept': 'application/json', 'Authorization': auth}
92
+
93
+ #Prepare the output string
94
+ all_stops_valid = True
95
+ stop_list = []
96
+ skip_api_calls = False
97
+
98
+ for stop in stops:
99
+ url = \
100
+ 'https://api.transport.nsw.gov.au/v1/tp/stop_finder?' \
101
+ 'outputFormat=rapidJSON&coordOutputFormat=EPSG%3A4326' \
102
+ '&type_sf=stop&name_sf=' + stop + \
103
+ '&TfNSWSF=true'
104
+
105
+ # Send the query
106
+ try:
107
+ url = 'https://api.transport.nsw.gov.au/v1/tp/stop_finder?outputFormat=rapidJSON&coordOutputFormat=EPSG%3A4326&type_sf=stop&name_sf=' + stop + '&TfNSWSF=true'
108
+ error_code = 0
109
+
110
+ if not skip_api_calls:
111
+ response = requests.get(url, headers=header, timeout=5)
112
+ else:
113
+ # An earlier call resulted in an API key error so no point trying again
114
+ response.status_code = 401
115
+
116
+ # If we get bad status code, handle it depending on the error type
117
+ if response.status_code != 200:
118
+ # We can't be sure that all the stops are valid
119
+ error_code = response.status_code
120
+ stop_detail = []
121
+
122
+ if response.status_code == 401:
123
+ # API key issue - log that, and don't bother with the other calls as they will all fail
124
+ skip_api_calls = True
125
+ all_stops_valid = False
126
+ logger.error(f"Error {str(response.status_code)} calling /v1/tp/stop_finder API; invalid API key")
127
+
128
+ elif response.status_code == 403 or response.status_code == 429:
129
+ # We've exceeded the rate limit but that doesn't mean the stop isn't valid
130
+ # So let's assume that the stop ID is probably ok but we'll still raise a warning
131
+ logger.warn(f"Error {str(response.status_code)} calling /v1/tp/stop_finder API; rate limit exceeded - assuming stop is valid")
132
+
133
+ else:
134
+ # A misc error - log it
135
+ all_stops_valid = False
136
+ logger.error(f"Error {str(response.status_code)} calling /v1/tp/stop_finder API")
137
+ else:
138
+ # Parse the result as a JSON object
139
+ stop_detail = response.json()
140
+
141
+ # Just a quick check - the presence of systemMessages signifies an error, otherwise we assume it's ok
142
+ if 'systemMessages' in stop_detail:
143
+ all_stops_valid = False
144
+ error_code = stop_detail['systemMessages'][0]['code']
145
+ error_text = stop_detail['systemMessages'][0]['text']
146
+ stop_detail = []
147
+
148
+ logger.error(f"Error {error_code} calling /v1/tp/stop_finder API; {error_text} for Stop ID {stop}")
149
+
150
+ # Put in a pause here to try and make sure we stay under the 5 API calls/second limit
151
+ # Not usually an issue but if multiple processes are running multiple calls we might hit it
152
+ time.sleep(1.0)
153
+
154
+ except Exception as ex:
155
+ # Some other kind of error, we should assume that the stop is invalid
156
+ error_code = 999
157
+ stop_detail = []
158
+
159
+ logger.error(f"Error {str(ex)} calling /v1/tp/stop_finder API; assuming stop is invalid")
160
+
161
+ finally:
162
+ # Append the results to the JSON output - only return the 'isBest' location entry if there's more than one
163
+ if stop_detail != []:
164
+ stop_valid = True
165
+ for location in stop_detail['locations']:
166
+ if location['isBest']:
167
+ stop_detail = location
168
+
169
+ break
170
+
171
+ else:
172
+ stop_valid = False
173
+
174
+ #Add it to the list
175
+ data = {"stop_id": stop, "valid": stop_valid, "error_code": error_code, "stop_detail": stop_detail}
176
+ stop_list.append (data)
177
+
178
+ # Complete the JSON output and return it
179
+ data = {"all_stops_valid": all_stops_valid, "stop_list": stop_list}
180
+ #return json.dumps(data)
181
+ return data
182
+
183
+
79
184
  def get_trip(self, name_origin, name_destination , api_key, journey_wait_time = 0, transport_type = 0, \
80
185
  strict_transport_type = False, raw_output = False, journeys_to_return = 1, route_filter = '', \
81
186
  include_realtime_location = True, include_alerts = 'none', alert_type = 'all', check_stop_ids = True, forced_gtfs_uri = []):
@@ -108,44 +213,18 @@ class TransportNSWv2(object):
108
213
  # First, check if the source and dest stops are valid unless we've been told not to
109
214
  if check_stop_ids:
110
215
  stop_list = [name_origin, name_destination]
216
+ data = self.check_stops(api_key, stop_list)
111
217
 
112
- for stop in stop_list:
113
- url = \
114
- 'https://api.transport.nsw.gov.au/v1/tp/stop_finder?' \
115
- 'outputFormat=rapidJSON&coordOutputFormat=EPSG%3A4326' \
116
- '&type_sf=stop&name_sf=' + stop + \
117
- '&TfNSWSF=true'
218
+ if not data['all_stops_valid']:
219
+ # One or both of those stops was invalid - log an error and exit
220
+ stop_error = ""
221
+ for stop in data['stop_list']:
222
+ if not stop['valid']:
223
+ stop_error += stop['stop_id']+ ", "
118
224
 
119
- # Send the query and return an error if something goes wrong
120
- try:
121
- response = requests.get(url, headers=header, timeout=5)
122
-
123
- # If we get bad status code, log error and return with None
124
- if response.status_code != 200:
125
- if response.status_code == 429:
126
- # We've exceeded the rate limit but that doesn't mean future calls won't work
127
- # So let's assume that the stop ID is ok but we'll still raise a warning
128
- logger.warn(f"Error {str(response.status_code)} calling /v1/tp/stop_finder API; rate limit exceeded - assuming stop is valid")
129
- else:
130
- # If it's an API key issue there's no point in continuing, hence returning None
131
- logger.error(f"Error {str(response.status_code)} calling /v1/tp/stop_finder API; check API key")
132
- return None
133
- else:
134
- # Parse the result as a JSON object
135
- result = response.json()
136
-
137
- # Just a quick check - the presence of systemMessages signifies an error, otherwise we assume it's ok
138
- if 'systemMessages' in result:
139
- logger.error(f"Error - Stop ID {stop} doesn't exist")
140
- return None
141
-
142
- # Put in a pause here to try and make sure we stay under the 5 API calls/second limit
143
- # Not usually an issue but if multiple processes are running multiple calls we might hit it
144
- time.sleep(1.0)
225
+ logger.error(f"Stop ID(s) {stop_error[:-2]} do not exist - exiting")
226
+ return None
145
227
 
146
- except Exception as ex:
147
- logger.error(f"Error {str(ex)} calling /v1/tp/stop_finder API; assuming stop is valid")
148
- return None
149
228
 
150
229
  # We don't control how many journeys are returned any more, so need to be careful of running out of valid journeys if there is a filter in place, particularly a strict filter
151
230
  # It would be more efficient to return one journey, check if the filter is met and then retrieve the next one via a new query if not, but for now we'll only be making use of the journeys we've been given
@@ -164,6 +243,8 @@ class TransportNSWv2(object):
164
243
  # Otherwise store the response for the next steps
165
244
  try:
166
245
  response = requests.get(url, headers=header, timeout=10)
246
+
247
+
167
248
  except Exception as ex:
168
249
  logger.error(f"Error {str(ex)} calling /v1/tp/trip API")
169
250
  return None
@@ -207,17 +288,17 @@ class TransportNSWv2(object):
207
288
 
208
289
  for current_journey_index in range (0, retrieved_journeys, 1):
209
290
  # Look for a trip with a matching transport type filter in at least one of its legs. Either ANY, or the first leg, depending on how strict we're being
210
- journey, next_journey_index = self.find_next_journey(result['journeys'], current_journey_index, transport_type, strict_transport_type, route_filter)
291
+ journey, next_journey_index = self._find_next_journey(result['journeys'], current_journey_index, transport_type, strict_transport_type, route_filter)
211
292
 
212
293
  if ((journey is None) or (journey['legs']) is None):
213
294
  pass
214
295
  else:
215
296
  legs = journey['legs']
216
- first_leg = self.find_first_leg(legs, transport_type, strict_transport_type, route_filter)
297
+ first_leg = self._find_first_leg(legs, transport_type, strict_transport_type, route_filter)
217
298
 
218
299
  #Executive decision - don't be strict on the last leg, there's often some walking (transport type 100) involved.
219
- last_leg = self.find_last_leg(legs, transport_type, False)
220
- changes = self.find_changes(legs, transport_type)
300
+ last_leg = self._find_last_leg(legs, transport_type, False)
301
+ changes = self._find_changes(legs, transport_type)
221
302
 
222
303
  origin = first_leg['origin']
223
304
  first_stop = first_leg['destination']
@@ -235,7 +316,7 @@ class TransportNSWv2(object):
235
316
  delay = int((t1-t2) / 60)
236
317
 
237
318
  # How long until it leaves?
238
- due = self.get_due(datetime.strptime(origin_departure_time, fmt))
319
+ due = self._get_due(datetime.strptime(origin_departure_time, fmt))
239
320
 
240
321
  # Destination info
241
322
  destination_stop_id = destination['id']
@@ -243,7 +324,7 @@ class TransportNSWv2(object):
243
324
  destination_arrival_time = destination['arrivalTimeEstimated']
244
325
 
245
326
  # Origin type info - train, bus, etc
246
- origin_mode = self.get_mode(transportation['product']['class'])
327
+ origin_mode = self._get_mode(transportation['product']['class'])
247
328
  origin_mode_name = transportation['product']['name']
248
329
 
249
330
  # RealTimeTripID info so we can try and get the current location later
@@ -272,7 +353,7 @@ class TransportNSWv2(object):
272
353
  if self.include_alerts != 'none':
273
354
  # We'll be adding these to the returned JSON string as an array
274
355
  # Only include alerts of the specified priority or greater, and of the specified type
275
- alerts = self.find_alerts(legs, self.include_alerts, self.alert_type)
356
+ alerts = self._find_alerts(legs, self.include_alerts, self.alert_type)
276
357
 
277
358
  latitude = 'n/a'
278
359
  longitude = 'n/a'
@@ -284,11 +365,11 @@ class TransportNSWv2(object):
284
365
  # ie it's been determined elsewhere then it can be forced
285
366
 
286
367
  bFoundTripID = False
287
- url_base_path = self.get_base_url(origin_mode)
368
+ url_base_path = self._get_base_url(origin_mode)
288
369
 
289
370
  # Check for a forced URI
290
371
  if not forced_gtfs_uri:
291
- url_mode_list = self.get_mode_list(origin_mode, agencyid)
372
+ url_mode_list = self._get_mode_list(origin_mode, agencyid)
292
373
  else:
293
374
  # We've been forced to use a specific URI!
294
375
  url_mode_list = forced_gtfs_uri
@@ -370,8 +451,8 @@ class TransportNSWv2(object):
370
451
  return json_output
371
452
 
372
453
 
373
- def find_next_journey(self, journeys, start_journey_index, journeytype, strict, route_filter):
374
- # Fnd the next journey that has a leg of the requested type, and/or that satisfies the route filter
454
+ def _find_next_journey(self, journeys, start_journey_index, journeytype, strict, route_filter):
455
+ # Find the next journey that has a leg of the requested type, and/or that satisfies the route filter
375
456
  journey_count = len(journeys)
376
457
 
377
458
  # Some basic error checking
@@ -379,7 +460,7 @@ class TransportNSWv2(object):
379
460
  return None, None
380
461
 
381
462
  for journey_index in range (start_journey_index, journey_count, 1):
382
- leg = self.find_first_leg(journeys[journey_index]['legs'], journeytype, strict, route_filter)
463
+ leg = self._find_first_leg(journeys[journey_index]['legs'], journeytype, strict, route_filter)
383
464
  if leg is not None:
384
465
  return journeys[journey_index], journey_index + 1
385
466
  else:
@@ -389,7 +470,7 @@ class TransportNSWv2(object):
389
470
  return None, None
390
471
 
391
472
 
392
- def find_first_leg(self, legs, legtype, strict, route_filter):
473
+ def _find_first_leg(self, legs, legtype, strict, route_filter):
393
474
  # Find the first leg of the requested type
394
475
  leg_count = len(legs)
395
476
  for leg_index in range (0, leg_count, 1):
@@ -419,7 +500,7 @@ class TransportNSWv2(object):
419
500
  return None
420
501
 
421
502
 
422
- def find_last_leg(self, legs, legtype, strict):
503
+ def _find_last_leg(self, legs, legtype, strict):
423
504
  # Find the last leg of the requested type
424
505
  leg_count = len(legs)
425
506
  for leg_index in range (leg_count - 1, -1, -1):
@@ -441,7 +522,7 @@ class TransportNSWv2(object):
441
522
  return None
442
523
 
443
524
 
444
- def find_changes(self, legs, legtype):
525
+ def _find_changes(self, legs, legtype):
445
526
  # Find out how often we have to change
446
527
  changes = 0
447
528
  leg_count = len(legs)
@@ -454,11 +535,11 @@ class TransportNSWv2(object):
454
535
  return changes - 1
455
536
 
456
537
 
457
- def find_alerts(self, legs, priority_filter, alert_type):
538
+ def _find_alerts(self, legs, priority_filter, alert_type):
458
539
  # Return an array of all the alerts on this trip that meet the priority level and alert type
459
540
  leg_count = len(legs)
460
541
  found_alerts = []
461
- priority_minimum = self.get_alert_priority(priority_filter)
542
+ priority_minimum = self._get_alert_priority(priority_filter)
462
543
  alert_list = alert_type.split("|")
463
544
 
464
545
  for leg_index in range (0, leg_count, 1):
@@ -466,14 +547,14 @@ class TransportNSWv2(object):
466
547
  if 'infos' in current_leg:
467
548
  alerts = current_leg['infos']
468
549
  for alert in alerts:
469
- if (self.get_alert_priority(alert['priority'])) >= priority_minimum:
550
+ if (self._get_alert_priority(alert['priority'])) >= priority_minimum:
470
551
  if (alert_type == 'all') or (alert['type'].lower() in alert_list):
471
552
  found_alerts.append (alert)
472
553
 
473
554
  return json.dumps(found_alerts)
474
555
 
475
556
 
476
- def find_hints(self, legs, legtype, priority):
557
+ def _find_hints(self, legs, legtype, priority):
477
558
  # Return an array of all the hints on this trip that meet the priority type
478
559
  leg_count = len(legs)
479
560
 
@@ -484,7 +565,7 @@ class TransportNSWv2(object):
484
565
  hints = current_leg['hints']
485
566
 
486
567
 
487
- def get_mode(self, iconId):
568
+ def _get_mode(self, iconId):
488
569
  """Map the iconId to a full text string"""
489
570
  modes = {
490
571
  1 : "Train",
@@ -501,7 +582,7 @@ class TransportNSWv2(object):
501
582
 
502
583
  return modes.get(iconId, None)
503
584
 
504
- def get_base_url(self, mode):
585
+ def _get_base_url(self, mode):
505
586
  # Map the journey mode to the proper base real time location URL
506
587
  v1_url = "https://api.transport.nsw.gov.au/v1/gtfs/vehiclepos"
507
588
  v2_url = "https://api.transport.nsw.gov.au/v2/gtfs/vehiclepos"
@@ -519,7 +600,7 @@ class TransportNSWv2(object):
519
600
  return url_options.get(mode, None)
520
601
 
521
602
 
522
- def get_alert_priority(self, alert_priority):
603
+ def _get_alert_priority(self, alert_priority):
523
604
  # Map the alert priority to a number so we can filter later
524
605
 
525
606
  alert_priorities = {
@@ -533,7 +614,7 @@ class TransportNSWv2(object):
533
614
  return alert_priorities.get(alert_priority.lower(), 4)
534
615
 
535
616
 
536
- def get_mode_list(self, mode, agencyid):
617
+ def _get_mode_list(self, mode, agencyid):
537
618
  """
538
619
  Map the journey mode to the proper modifier URL. If the mode is Bus, Coach or School bus then use the agency ID to invoke the GTFS datastore search API
539
620
  which will give us the appropriate URL to call later - we still have to do light rail the old-fashioned, brute-force way though
@@ -581,7 +662,7 @@ class TransportNSWv2(object):
581
662
  return url_options.get(mode, None)
582
663
 
583
664
 
584
- def get_due(self, estimated):
665
+ def _get_due(self, estimated):
585
666
  # Minutes until departure
586
667
  due = 0
587
668
  if estimated > datetime.utcnow():
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
5
5
 
6
6
  setuptools.setup(
7
7
  name="PyTransportNSWv2",
8
- version="0.9.0",
8
+ version="0.9.2",
9
9
  author="andystewart999",
10
10
  author_email="andy.stewart@live.com",
11
11
  description="Get detailed per-trip transport information from TransportNSW",
@@ -14,8 +14,7 @@ setuptools.setup(
14
14
  url="https://github.com/andystewart999/TransportNSW",
15
15
  packages=setuptools.find_packages(),
16
16
  install_requires=[
17
- 'gtfs-realtime-bindings',
18
- 'httpx',
17
+ 'gtfs-realtime-bindings'
19
18
  ],
20
19
  classifiers=[
21
20
  "Programming Language :: Python :: 3",