def _get_informations(self, poi): logging.debug('building stands') try: all_stands = self.breaker.call(self._get_all_stands) ref = poi.get('properties', {}).get('ref') if not ref: return Stands(0, 0, StandsStatus.unavailable) stands = all_stands.get(ref.lstrip('0')) if stands: if stands.status != 'open': stands.available_bikes = 0 stands.available_places = 0 stands.total_stands = 0 return stands except pybreaker.CircuitBreakerError as e: logging.getLogger(__name__).error('atos service dead (error: {})'.format(e)) raise BssProxyError('circuit breaker open') except requests.Timeout as t: logging.getLogger(__name__).error('atos service timeout (error: {})'.format(t)) raise BssProxyError('timeout') except Exception as e: logging.getLogger(__name__).exception('cykleo error : {}'.format(str(e))) raise BssProxyError(str(e)) return Stands(0, 0, StandsStatus.unavailable)
def parking_space_availability_cykleo_get_informations_with_status_Closed_test( ): webservice_response = { '2': { "station": { "assetStation": { "coordinate": {}, "organization": 1, "commercialNumber": 1, "id": 1, "commercialName": "station 1" }, "status": "DISCONNECTED", "id": 1 }, "availableClassicBikeCount": 3, "id": 1, "availableElectricBikeCount": 1, "availableDockCount": 2 } } provider = CykleoProvider('http://bob', network, 'big', 'big', {'CYKLEO'}) provider._call_webservice = MagicMock(return_value=webservice_response) assert provider.get_informations(poi) == Stands(0, 0, 'UNAVAILABLE') assert provider.get_informations(poi_with_0) == Stands(0, 0, 'UNAVAILABLE')
def _get_informations(self, poi): # Possible status values of the station: OPEN and CLOSED ref = poi.get('properties', {}).get('ref') service_key = self.WS_URL_TEMPLATE.format(self.contract, self.api_key) + self.network data = self._data.get(service_key) if data is None: self._data[service_key] = self._call_webservice() self._last_update = datetime.datetime.utcnow() if self._last_update + datetime.timedelta( seconds=self._update_interval) < datetime.datetime.utcnow(): service_url = self.WS_URL_TEMPLATE.format(self.contract, self.api_key) self._data[service_url] = self._call_webservice() self._last_update = datetime.datetime.utcnow() data = self._data.get(service_key) if data and 'status' in data.get(ref, {}): if data[ref]['status'] == 'OPEN': return Stands( data[ref].get('available_bike_stands', 0), data[ref].get('available_bikes', 0), StandsStatus.open, ) elif data[ref]['status'] == 'CLOSED': return Stands(0, 0, StandsStatus.closed) return Stands(0, 0, StandsStatus.unavailable)
def parking_space_availability_cykleo_get_informations_test(): webservice_response = { '2': { "station": { "assetStation": { "coordinate": {}, "organization": 1, "commercialNumber": 1, "id": 1, "commercialName": "station 1" }, "status": "IN_SERVICE", "id": 1 }, "availableClassicBikeCount": 3, "id": 1, "availableElectricBikeCount": 1, "availableDockCount": 2 } } provider = CykleoProvider('http://bob', network, 'big', 'big', {'CYKLEO'}) provider._call_webservice = MagicMock(return_value=webservice_response) assert provider.get_informations(poi) == Stands(2, 4, StandsStatus.open) assert provider.get_informations(poi_with_0) == Stands( 2, 4, StandsStatus.open) provider._call_webservice = MagicMock(return_value=None) assert provider.get_informations(poi) == Stands(0, 0, StandsStatus.unavailable) assert provider.get_informations(poi_with_0) == Stands( 0, 0, StandsStatus.unavailable) invalid_poi = {} assert provider.get_informations(invalid_poi) == Stands( 0, 0, StandsStatus.unavailable)
def _get_informations(self, poi): ref = poi.get('properties', {}).get('ref') if ref is not None: ref = ref.lstrip('0') data = self._call_webservice() # Possible status values of the station: IN_SERVICE, IN_MAINTENANCE, OUT_OF_SERVICE, DISCONNECTED # and DECOMMISSIONED if not data: return Stands(0, 0, StandsStatus.unavailable) obj_station = data.get(ref) if not obj_station: return Stands(0, 0, StandsStatus.unavailable) if obj_station.get( 'station', {}).get('status' ) == 'IN_SERVICE' and 'availableDockCount' in obj_station: return Stands( obj_station.get('availableDockCount', 0), obj_station.get('availableClassicBikeCount', 0) + obj_station.get('availableElectricBikeCount', 0), StandsStatus.open, ) elif obj_station.get('station', {}).get('status') in ('OUT_OF_SERVICE', 'DECOMMISSIONED'): return Stands(0, 0, StandsStatus.closed) else: return Stands(0, 0, StandsStatus.unavailable)
def parking_space_availability_jcdecaux_get_informations_with_status_Closed_test(): webservice_response = {'2': {'available_bike_stands': 4, 'available_bikes': 8, 'status': 'CLOSED'}} provider = JcdecauxProvider(u"vélib'", 'Paris', 'api_key', {'jcdecaux'}) provider._call_webservice = MagicMock(return_value=webservice_response) assert provider.get_informations(poi) == Stands(0, 0, StandsStatus.closed) provider._call_webservice = MagicMock(return_value=None) assert provider.get_informations(poi) == Stands(0, 0, StandsStatus.unavailable) invalid_poi = {} assert provider.get_informations(invalid_poi) == Stands(0, 0, StandsStatus.unavailable)
def get_informations(self, poi): # Possible status values of the station: OPEN and CLOSED ref = poi.get('properties', {}).get('ref') data = self._call_webservice() if data and 'status' in data.get(ref, {}): if data[ref]['status'] == 'OPEN': return Stands(data[ref].get('available_bike_stands', 0), data[ref].get('available_bikes', 0), 'OPEN') elif data[ref]['status'] == 'CLOSED': return Stands(0, 0, 'CLOSED') return Stands(0, 0, 'UNAVAILABLE')
def parking_space_availability_atos_get_informations_with_closed_status_test(): """ The service returns realtime stand information or stand with status='unavailable' if an error occured """ stand_2 = Stands(5, 9, StandsStatus.closed) all_stands = {'1': Stands(4, 8, StandsStatus.open), '2': stand_2} provider = AtosProvider(u'10', u'vélitul', u'https://webservice.atos.com?wsdl', {'keolis'}) provider._get_all_stands = MagicMock(return_value=all_stands) assert provider.get_informations(poi) == Stands(0, 0, StandsStatus.closed) invalid_poi = {} assert provider.get_informations(invalid_poi) == Stands(0, 0, StandsStatus.unavailable)
def parking_space_availability_jcdecaux_get_informations_test(): """ The service returns realtime stand information or stand with status='Unavailable' if an error occured """ webservice_response = {'2': {'available_bike_stands': 4, 'available_bikes': 8, 'status': 'OPEN'}} provider = JcdecauxProvider(u"vélib'", 'Paris', 'api_key', {'jcdecaux'}) provider._call_webservice = MagicMock(return_value=webservice_response) assert provider.get_informations(poi) == Stands(4, 8, StandsStatus.open) provider._call_webservice = MagicMock(return_value=None) assert provider.get_informations(poi) == Stands(0, 0, StandsStatus.unavailable) invalid_poi = {} assert provider.get_informations(invalid_poi) == Stands(0, 0, StandsStatus.unavailable)
def parking_space_availability_atos_get_informations_test(): """ Atos validate return good stands informations or None if an error occured """ stands = Stands(5, 9) all_stands = {'1': Stands(4, 8), '2': stands} provider = AtosProvider(u'10', u'vélitul', u'https://webservice.atos.com?wsdl', {'keolis'}) provider.get_all_stands = MagicMock(return_value=all_stands) assert provider.get_informations(poi) == stands provider.get_all_stands = MagicMock( side_effect=WebFault('fake fault', 'mock')) assert provider.get_informations(poi) is None
def test_call_mocked_request(): webservice_response = [{'number': 2, 'available_bike_stands': 4, 'available_bikes': 8, 'status': 'OPEN'}] provider = JcdecauxProvider(u"vélib'", 'Paris', 'api_key', {'jcdecaux'}) with requests_mock.Mocker() as m: m.get('https://api.jcdecaux.com/vls/v1/stations/', json=webservice_response) assert provider.get_informations(poi) == Stands(4, 8, StandsStatus.open) assert m.called
def get_all_stands(self): client = self.get_client() all_stands = client.service.getSummaryInformationTerminals(self.id_ao) return { stands.libelle: Stands(stands.nbPlacesDispo, stands.nbVelosDispo) for stands in all_stands }
def parking_space_availability_jcdecaux_get_informations_unauthorized_test(): """ The service returns realtime stand information or stand with status='Unavailable' if not authorized """ webservice_unauthorized_response = {'error': 'Unauthorized'} provider = JcdecauxProvider(u"vélib'", 'Paris', 'unauthorized_api_key', {'jcdecaux'}) provider._call_webservice = MagicMock(return_value=webservice_unauthorized_response) assert provider.get_informations(poi) == Stands(0, 0, StandsStatus.unavailable)
def _get_informations(self, poi): ref = poi.get('properties', {}).get('ref') if not ref: return # calculate dummy available stands number s = int(bytearray(str(ref))[0]) return Stands(int(s / 2), s, StandsStatus.closed if s % 2 else StandsStatus.open)
def parking_space_availability_atos_get_informations_test(): """ The service returns realtime stand information or stand with status='unavailable' if an error occured """ stand_2 = Stands(5, 9, StandsStatus.open) all_stands = {'1': Stands(4, 8, StandsStatus.open), '2': stand_2} provider = AtosProvider(u'10', u'vélitul', u'https://webservice.atos.com?wsdl', {'keolis'}) provider._get_all_stands = MagicMock(return_value=all_stands) assert provider.get_informations(poi) == stand_2 invalid_poi = {} assert provider.get_informations(invalid_poi) == Stands(0, 0, StandsStatus.unavailable) poi_blur_ref = {'properties': {'ref': '02'}} assert provider.get_informations(poi_blur_ref) == stand_2 provider._get_all_stands = MagicMock(side_effect=Exception('cannot access service')) assert provider.get_informations(poi) == Stands(0, 0, StandsStatus.unavailable)
def get_informations(self, poi): ref = poi.get('properties', {}).get('ref') data = self._call_webservice() if not data or ref not in data: return None if 'available_bike_stands' in data[ref] and 'available_bikes' in data[ ref]: return Stands(data[ref]['available_bike_stands'], data[ref]['available_bikes'])
def get_informations(self, poi): try: stand = self._get_informations(poi) self.record_call('ok') return stand except BssProxyError as e: self.record_call('failure', reason=str(e)) return Stands(0, 0, StandsStatus.unavailable)
def get_informations(self, poi): logging.debug('building stands') try: all_stands = self.breaker.call(self._get_all_stands) ref = poi.get('properties', {}).get('ref') if not ref: return Stands(0, 0, 'UNAVAILABLE') stands = all_stands.get(ref.lstrip('0')) if stands: if stands.status != 'open': stands.available_bikes = 0 stands.available_places = 0 stands.total_stands = 0 return stands except: logging.getLogger(__name__).exception('transport error during call to %s bss provider', self.id_ao) return Stands(0, 0, 'UNAVAILABLE')
def parking_space_availability_jcdecaux_get_informations_test(): """ Jcdecaux validate return good stands informations or None if an error occured """ webservice_response = {'available_bike_stands': 4, 'available_bikes': 8} provider = JcdecauxProvider(u"Vélib'", 'Paris', 'api_key') provider._call_webservice = MagicMock(return_value=webservice_response) assert provider.get_informations(poi) == Stands(4, 8) provider._call_webservice = MagicMock(return_value=None) assert provider.get_informations(poi) is None
def parking_space_availability_atos_get_informations_test(): """ Atos validate return good stands informations or None if an error occured """ stands = Stands(5, 9) all_stands = {'1': Stands(4, 8), '2': stands} provider = AtosProvider(u'10', u'vélitul', u'https://webservice.atos.com?wsdl', {'keolis'}) provider._get_all_stands = MagicMock(return_value=all_stands) assert provider.get_informations(poi) == stands invalid_poi = {} assert provider.get_informations(invalid_poi) is None poi_blur_ref = {'properties': {'ref': '02'}} assert provider.get_informations(poi_blur_ref) == stands provider._get_all_stands = MagicMock( side_effect=Exception('cannot access service')) assert provider.get_informations(poi) is None
def _get_all_stands(self): with self._get_client() as client: all_stands = client.service.getSummaryInformationTerminals( self.id_ao) return { stands.libelle: Stands( stands.nbPlacesDispo, stands.nbVelosDispo, StandsStatus.open if stands.etatConnexion == 'CONNECTEE' else StandsStatus.unavailable) for stands in all_stands }
def _get_informations(self, poi): ref = poi.get('properties', {}).get('ref') if not ref: return # generate dummy available stands number using a hash algo import hashlib m = hashlib.md5() for k, v in poi.get('properties', {}).items(): m.update(v.encode('utf-8', errors='ignore')) s = int(bytearray(str(m.hexdigest()))[0]) return Stands( int(s / 2), s, StandsStatus.closed if int(ref) % 2 else StandsStatus.open)
def available_electric_bike_count_only_test(): webservice_response = { '2': { "station": { "assetStation": { "coordinate": {}, "organization": 1, "commercialNumber": 1, "id": 1, "commercialName": "station 1" }, "status": "IN_SERVICE", "id": 1 }, "id": 1, "availableElectricBikeCount": 1, "availableDockCount": 2 } } provider = CykleoProvider('http://bob', network, 'big', 'big', {'CYKLEO'}) provider._call_webservice = MagicMock(return_value=webservice_response) assert provider.get_informations(poi) == Stands(2, 1, 'OPEN') assert provider.get_informations(poi_with_0) == Stands(2, 1, 'OPEN')
def witout_available_dock_count_test(): webservice_response = { '2': { "station": { "assetStation": { "coordinate": {}, "organization": 1, "commercialNumber": 1, "id": 1, "commercialName": "station 1" }, "status": "IN_SERVICE", "id": 1 }, "id": 1, "availableElectricBikeCount": 1, } } provider = CykleoProvider('http://bob', network, 'big', 'big', {'CYKLEO'}) provider._call_webservice = MagicMock(return_value=webservice_response) res_stands = provider.get_informations(poi) assert res_stands == Stands(0, 0, StandsStatus.unavailable) res_stands = provider.get_informations(poi_with_0) assert res_stands == Stands(0, 0, StandsStatus.unavailable)
def get_informations(self, poi): ref = poi.get('properties', {}).get('ref') if ref is not None: ref = ref.lstrip('0') data = self._call_webservice() if not data: return None station = data.get(ref) if not station: return None if 'availableDockCount' in station \ and ('availableClassicBikeCount' in station or 'availableElectricBikeCount' in station): return Stands(station.get('availableDockCount'), station.get('availableClassicBikeCount', 0) + station.get('availableElectricBikeCount', 0)) return None
def parking_space_availability_atos_get_all_stands_test(): """ Atos validate transformation of webservice result """ stands = lambda: None all_stands_list = [] stands.libelle = '1' stands.nbPlacesDispo = 4 stands.nbVelosDispo = 8 stands.etatConnexion = 'CONNECTEE' all_stands_list.append(stands) stands2 = lambda: None stands2.libelle = '2' stands2.nbPlacesDispo = 5 stands2.nbVelosDispo = 9 stands2.etatConnexion = 'CONNECTEE' all_stands_list.append(stands2) stands3 = lambda: None stands3.libelle = '3' stands3.nbPlacesDispo = 10 stands3.nbVelosDispo = 20 stands3.etatConnexion = 'DECONNECTEE' all_stands_list.append(stands3) provider = AtosProvider(u'10', u'vélitul', u'https://webservice.atos.com?wsdl', {'keolis'}) client = lambda: None client.service = lambda: None client.service.getSummaryInformationTerminals = MagicMock( return_value=all_stands_list) @contextmanager def mock_get_client(): yield client provider._get_client = mock_get_client all_stands = provider._get_all_stands() assert len(all_stands) == 3 assert isinstance(all_stands.get('2'), Stands) # The status of stand=3 is converted to status navitia='unavailable' from 'DECONNECTEE' # and other attributs are initialized to 0. stand = provider.get_informations('3') assert stand == Stands(0, 0, StandsStatus.unavailable)
def get_informations(self, poi): ref = poi.get('properties', {}).get('ref') data = self._call_webservice(ref) if data and 'available_bike_stands' in data and 'available_bikes' in data: return Stands(data['available_bike_stands'], data['available_bikes'])
def get_informations(self, poi): return Stands(5, 9, StandsStatus.open)
def get_informations(self, poi): available_places = 13 if poi['id'] == 'station_1' else 99 available_bikes = 3 if poi['id'] == 'station_1' else 98 return Stands(available_places=available_places, available_bikes=available_bikes)
def _get_all_stands(self): with self._get_client() as client: all_stands = client.service.getSummaryInformationTerminals(self.id_ao) return {stands.libelle: Stands(stands.nbPlacesDispo, stands.nbVelosDispo, 'OPEN' if stands.etatConnexion == 'CONNECTEE' else 'UNAVAILABLE') for stands in all_stands}