PyTransportNSWv2 1.0.0__tar.gz → 1.0.1__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: 1.0.0
3
+ Version: 1.0.1
4
4
  Summary: Get detailed per-trip transport information from TransportNSW
5
5
  Home-page: https://github.com/andystewart999/TransportNSW
6
6
  Author: andystewart999
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyTransportNSWv2
3
- Version: 1.0.0
3
+ Version: 1.0.1
4
4
  Summary: Get detailed per-trip transport information from TransportNSW
5
5
  Home-page: https://github.com/andystewart999/TransportNSW
6
6
  Author: andystewart999
@@ -35,7 +35,7 @@ ATTR_AVMS_TRIP_ID = 'avms_trip_id'
35
35
  ATTR_REAL_TIME_TRIP_ID = 'real_time_trip_id'
36
36
  ATTR_LATITUDE = 'latitude'
37
37
  ATTR_LONGITUDE = 'longitude'
38
-
38
+ ATTR_GTFS_URI = 'gtfs_uri'
39
39
  ATTR_ALERTS = 'alerts'
40
40
 
41
41
  logger = logging.getLogger(__name__)
@@ -49,14 +49,6 @@ class TransportNSWv2(object):
49
49
 
50
50
  def __init__(self):
51
51
  """Initialize the data object with default values."""
52
- self.origin_id = None
53
- self.destination_id = None
54
- self.api_key = None
55
- self.journey_wait_time = None
56
- self.transport_type = None
57
- self.strict_transport_type = None
58
- self.raw_output = None
59
- self.journeys_to_return = None
60
52
  self.info = {
61
53
  ATTR_DUE_IN : 'n/a',
62
54
  ATTR_ORIGIN_STOP_ID : 'n/a',
@@ -79,7 +71,7 @@ class TransportNSWv2(object):
79
71
  }
80
72
 
81
73
 
82
- def check_stops(self, api_key, stops):
74
+ def check_stops(self, api_key, stops, home_assistant = False):
83
75
  # Check the list of stops and return a JSON array of the stop details, plus if all the checked stops existed
84
76
  # Return a JSON array of the results
85
77
 
@@ -121,22 +113,12 @@ class TransportNSWv2(object):
121
113
  stop_detail = []
122
114
 
123
115
  if response.status_code == 401:
124
- # API key issue - log that, and don't bother with the other calls as they will all fail
125
- #skip_api_calls = True
126
- #all_stops_valid = False
127
- #logger.error(f"Error {str(response.status_code)} calling /v1/tp/stop_finder API; invalid API key")
128
116
  raise InvalidAPIKey("Invalid API key")
129
117
 
130
118
  elif response.status_code == 403 or response.status_code == 429:
131
- # We've exceeded the rate limit but that doesn't mean the stop isn't valid
132
- # So raise an API rate limit exception and let the user decide how to handle it
133
- #logger.warn(f"Error {str(response.status_code)} calling /v1/tp/stop_finder API; rate limit exceeded - assuming stop is valid")
134
119
  raise APIRateLimitExceeded("API rate limit exceeded")
135
120
 
136
121
  else:
137
- # Raise a generic error exception
138
- #all_stops_valid = False
139
- #logger.error(f"Error {str(response.status_code)} calling /v1/tp/stop_finder API")
140
122
  raise StopError("Unknown")
141
123
 
142
124
  else:
@@ -145,25 +127,15 @@ class TransportNSWv2(object):
145
127
 
146
128
  # Just a quick check - the presence of systemMessages signifies an error, otherwise we assume it's ok
147
129
  if 'systemMessages' in stop_detail:
148
- #all_stops_valid = False
149
- #error_code = stop_detail['systemMessages'][0]['code']
150
130
  error_text = stop_detail['systemMessages'][0]['text']
151
- #stop_detail = []
152
- #logger.error(f"Error {error_code} calling /v1/tp/stop_finder API; {error_text} for Stop ID {stop}")
153
- #raise StopError(f"Error {str(error_code)} ({str(error_text)}) calling stop finder API for stop ID {stop}")
154
- raise StopError(f"{error_text}")
131
+ raise StopError(f"{error_text}", stop)
155
132
 
156
133
  # Put in a pause here to try and make sure we stay under the 5 API calls/second limit
157
134
  # Not usually an issue but if multiple processes are running multiple calls we might hit it
158
135
  time.sleep(1.0)
159
136
 
160
137
  except Exception as ex:
161
- # Some other kind of error, we should assume that the stop is invalid
162
- #error_code = 999
163
- #stop_detail = []
164
-
165
- #logger.error(f"Error {str(ex)} calling /v1/tp/stop_finder API; assuming stop is invalid")
166
- raise StopError(f"Error '{ex}' calling stop finder API for stop ID {stop}")
138
+ raise StopError(f"Error '{ex}' calling stop finder API for stop ID {stop}", stop)
167
139
 
168
140
  finally:
169
141
  # Append the results to the JSON output - only return the 'isBest' location entry if there's more than one
@@ -172,7 +144,6 @@ class TransportNSWv2(object):
172
144
  for location in stop_detail['locations']:
173
145
  if location['isBest']:
174
146
  stop_detail = location
175
-
176
147
  break
177
148
 
178
149
  else:
@@ -197,21 +168,10 @@ class TransportNSWv2(object):
197
168
  """Get the latest data from Transport NSW."""
198
169
  fmt = '%Y-%m-%dT%H:%M:%SZ'
199
170
 
200
- #self.name_origin = name_origin
201
- #self.destination = name_destination
202
- #self.api_key = api_key
203
- #self.journey_wait_time = journey_wait_time
204
- #self.transport_type = transport_type
205
- #self.strict_transport_type = strict_transport_type
206
- #self.raw_output = raw_output
207
- #self.journeys_to_return = journeys_to_return
208
- #self.route_filter = route_filter.lower()
209
- #self.include_realtime_location = include_realtime_location
210
- #self.include_alerts = include_alerts.lower()
211
- #self.alert_type = alert_type.lower()
212
171
  route_filter = route_filter.lower()
213
172
  include_alerts = include_alerts.lower()
214
173
  alert_type = alert_type.lower()
174
+
215
175
  # This query always uses the current date and time - but add in any 'journey_wait_time' minutes
216
176
  now_plus_wait = datetime.now() + timedelta(minutes = journey_wait_time)
217
177
  itdDate = now_plus_wait.strftime('%Y%m%d')
@@ -233,7 +193,7 @@ class TransportNSWv2(object):
233
193
  stop_error += stop['stop_id']+ ", "
234
194
 
235
195
  #logger.error(f"Stop ID(s) {stop_error[:-2]} do not exist - exiting")
236
- raise StopError (f"Stop ID(s) {stop_error[:-2]} do not exist")
196
+ raise StopError (f"Stop ID(s) {stop_error[:-2]} do not exist", stop_error)
237
197
  #return None
238
198
 
239
199
  # 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
@@ -245,9 +205,8 @@ class TransportNSWv2(object):
245
205
  'outputFormat=rapidJSON&coordOutputFormat=EPSG%3A4326' \
246
206
  '&depArrMacro=dep&itdDate=' + itdDate + '&itdTime=' + itdTime + \
247
207
  '&type_origin=any&name_origin=' + name_origin + \
248
- '&type_destination=any&name_destination=' + destination + \
208
+ '&type_destination=any&name_destination=' + name_destination + \
249
209
  '&TfNSWTR=true'
250
- # '&calcNumberOfTrips=' + str(journeys_to_retrieve) + \
251
210
 
252
211
  # Send the query and return an error if something goes wrong
253
212
  # Otherwise store the response for the next steps
@@ -255,23 +214,19 @@ class TransportNSWv2(object):
255
214
  response = requests.get(url, headers=header, timeout=10)
256
215
 
257
216
  except Exception as ex:
258
- #logger.error(f"Error {str(ex)} calling /v1/tp/trip API")
259
- #return None
260
- raise TripError (f"Error '{str(ex)}' calling trip API for journey {self.name_origin} to {self.destination}")
217
+ raise TripError (f"Error '{str(ex)}' calling trip API for journey {name_origin} to {name_destination}")
261
218
 
262
219
  # If we get bad status code, log error and return with n/a or an empty string
263
220
  if response.status_code != 200:
264
221
  if response.status_code == 401:
265
222
  # API key issue
266
- raise InvalidAPIKey("Error 'Invalid API key' calling trip API for journey {self.name_origin} to {self.destination}")
223
+ raise InvalidAPIKey("Error 'Invalid API key' calling trip API for journey {name_origin} to {name_destination}")
267
224
 
268
225
  elif response.status_code == 403 or response.status_code == 429:
269
- raise APIRateLimitExceeded("Error 'API rate limit exceeded' calling trip API for journey {self.name_origin} to {self.destination}")
270
- #logger.error(f"Error {str(response.status_code)} calling /v1/tp/trip API; rate limit exceeded")
226
+ raise APIRateLimitExceeded("Error 'API rate limit exceeded' calling trip API for journey {name_origin} to {name_destination}")
271
227
 
272
228
  else:
273
- raise TripError(f"Error '{str(response.status_cude)}' calling trip API for journey {self.name_origin} to {self.destination}")
274
- #logger.error(f"Error {str(response.status_code)} calling /v1/tp/trip API; check API key")
229
+ raise TripError(f"Error '{str(response.status_cude)}' calling trip API for journey {name_origin} to {name_destination}")
275
230
 
276
231
  return None
277
232
 
@@ -292,10 +247,7 @@ class TransportNSWv2(object):
292
247
  retrieved_journeys = len(result['journeys'])
293
248
 
294
249
  except:
295
- # Looks like an empty response
296
- #logger.error(f"Error {(str(err))} calling /v1/tp/trip API")
297
- raise TripError(f"Error 'no journeys returned' calling trip API for journey {self.name_origin} to {self.destination}")
298
- #return None
250
+ raise TripError(f"Error 'no journeys returned' calling trip API for journey {name_origin} to {name_destination}")
299
251
 
300
252
  # Loop through the results applying filters where required, and generate the appropriate JSON output including an array of in-scope trips
301
253
  json_output=''
@@ -371,15 +323,16 @@ class TransportNSWv2(object):
371
323
  occupancy = first_stop['properties']['occupancy']
372
324
 
373
325
  alerts = "[]"
374
- if self.include_alerts != 'none':
326
+ if include_alerts != 'none':
375
327
  # We'll be adding these to the returned JSON string as an array
376
328
  # Only include alerts of the specified priority or greater, and of the specified type
377
- alerts = self._find_alerts(legs, self.include_alerts, self.alert_type)
329
+ alerts = self._find_alerts(legs, include_alerts, alert_type)
378
330
 
379
331
  latitude = 'n/a'
380
332
  longitude = 'n/a'
333
+ mode_url = 'n/a'
381
334
 
382
- if self.include_realtime_location and realtimetripid != 'n/a':
335
+ if include_realtime_location and realtimetripid != 'n/a':
383
336
  # See if we can get the latitute and longitude via the Realtime Vehicle Positions API
384
337
  # Build the URL(s) - some modes have multiple GTFS sources, unforunately
385
338
  # Some travel modes require brute-forcing the API call a few times, so if we're sure of the URI,
@@ -449,12 +402,13 @@ class TransportNSWv2(object):
449
402
  ATTR_CHANGES: changes,
450
403
  ATTR_OCCUPANCY : occupancy,
451
404
  ATTR_REAL_TIME_TRIP_ID : realtimetripid,
405
+ ATTR_GTFS_URI: mode_url,
452
406
  ATTR_LATITUDE : latitude,
453
407
  ATTR_LONGITUDE : longitude,
454
408
  ATTR_ALERTS: json.loads(alerts)
455
409
  }
456
410
 
457
- if self.home_assistant:
411
+ if home_assistant:
458
412
  self.info.update (
459
413
  {ATTR_AVMS_TRIP_ID: avmstripid}
460
414
  )
@@ -475,7 +429,7 @@ class TransportNSWv2(object):
475
429
 
476
430
  current_journey_index = next_journey_index
477
431
 
478
- json_output='{"journeys_to_return": ' + str(self.journeys_to_return) + ', "journeys_with_data": ' + str(found_journeys) + ', "journeys": [' + json_output + ']}'
432
+ json_output='{"journeys_to_return": ' + str(journeys_to_return) + ', "journeys_with_data": ' + str(found_journeys) + ', "journeys": [' + json_output + ']}'
479
433
  return json_output
480
434
 
481
435
 
@@ -700,18 +654,21 @@ class TransportNSWv2(object):
700
654
  return due
701
655
 
702
656
  # Exceptions
703
- class TFNSWAPIError(Exception):
704
- """ Base error for all exceptions """
705
-
706
- class InvalidAPIKey(TFNSWAPIError):
657
+ class InvalidAPIKey(Exception):
707
658
  """ API key error """
708
659
 
709
- class APIRateLimitExceeded(TFNSWAPIError):
660
+ class APIRateLimitExceeded(Exception):
710
661
  """ API rate limit exceeded """
711
662
 
712
- class StopError(TFNSWAPIError):
663
+ class StopError(Exception):
713
664
  """ Stop-finder related error """
665
+ def __init__(self, message = "", stop_detail = ""):
666
+ super().__init__(message)
667
+ self.stop_detail = stop_detail
668
+
669
+ # def __str__(self):
670
+ # return f"{self.message}"
714
671
 
715
- class TripError(TFNSWAPIError):
672
+ class TripError(Exception):
716
673
  """" Trip-finder related error """
717
674
 
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
5
5
 
6
6
  setuptools.setup(
7
7
  name="PyTransportNSWv2",
8
- version="1.0.0",
8
+ version="1.0.1",
9
9
  author="andystewart999",
10
10
  author_email="andy.stewart@live.com",
11
11
  description="Get detailed per-trip transport information from TransportNSW",