def get(self, id, region=None, lon=None, lat=None): self.region = i_manager.get_region(region, lon, lat) args = self.parsers["get"].parse_args() args.update({ "uri": transform_id(id), "_current_datetime": datetime.datetime.utcnow() }) response = i_manager.dispatch(args, "place_uri", instance_name=self.region) return response, 200
def get(self, id, region=None, lon=None, lat=None): args = self.parsers["get"].parse_args() args.update({"uri": transform_id(id), "_current_datetime": datetime.utcnow()}) if any([region, lon, lat]): self.region = i_manager.get_region(region, lon, lat) timezone.set_request_timezone(self.region) response = i_manager.dispatch(args, "place_uri", instance_name=self.region) else: user = authentication.get_user(token=authentication.get_token(), abort_if_no_token=False) available_instances = get_all_available_instances(user) autocomplete = global_autocomplete.get('bragi') if not autocomplete: raise TechnicalError('world wide autocompletion service not available') response = autocomplete.get_by_uri(args["uri"], instances=available_instances) return response, 200
def get(self, id, region=None, lon=None, lat=None): args = self.parsers["get"].parse_args() args.update({ "uri": transform_id(id), "_current_datetime": datetime.utcnow() }) request_id = "places_{}".format(flask.request.id) args["request_id"] = request_id if any([region, lon, lat]): self.region = i_manager.get_region(region, lon, lat) timezone.set_request_timezone(self.region) response = i_manager.dispatch(args, "place_uri", instance_name=self.region) else: user = authentication.get_user(token=authentication.get_token(), abort_if_no_token=False) available_instances = get_all_available_instances( user, exclude_backend='kraken') # If no instance available most probably due to database error if (not user) and (not available_instances): raise TechnicalError( 'world wide autocompletion service not available temporarily' ) # If parameter '_autocomplete' is absent use 'bragi' as default value if args["_autocomplete"] is None: args["_autocomplete"] = app.config.get( 'DEFAULT_AUTOCOMPLETE_BACKEND', 'bragi') autocomplete = global_autocomplete.get(args["_autocomplete"]) if not autocomplete: raise TechnicalError( 'world wide autocompletion service not available') response = autocomplete.get_by_uri(args["uri"], request_id=request_id, instances=available_instances) return response, 200
def get(self, region=None, lon=None, lat=None, uri=None): self.region = i_manager.get_region(region, lon, lat) timezone.set_request_timezone(self.region) args = self.parsers["get"].parse_args() if uri: if uri[-1] == '/': uri = uri[:-1] uris = uri.split("/") if len(uris) >= 2: args["uri"] = transform_id(uris[-1]) # for coherence we check the type of the object obj_type = uris[-2] if obj_type not in places_types: abort(404, message='places_nearby api not available for {}'. format(obj_type)) else: abort(404) elif lon and lat: # check if lon and lat can be converted to float float(lon) float(lat) args["uri"] = "coord:{}:{}".format(lon, lat) else: abort(404) args["filter"] = args["filter"].replace(".id", ".uri") self._register_interpreted_parameters(args) response = i_manager.dispatch(args, "places_nearby", instance_name=self.region) response = marshal(response, places_nearby) if i_manager.instances[ self.region].bss_provider and args["bss_stands"]: response["places_nearby"] = bss_provider_manager.handle_places( response["places_nearby"]) return response, 200
def parse_args(self, region=None, uri=None): args = self.parsers['get'].parse_args() if args.get('max_duration_to_pt') is not None: # retrocompatibility: max_duration_to_pt override all individual value by mode args['max_walking_duration_to_pt'] = args['max_duration_to_pt'] args['max_bike_duration_to_pt'] = args['max_duration_to_pt'] args['max_bss_duration_to_pt'] = args['max_duration_to_pt'] args['max_car_duration_to_pt'] = args['max_duration_to_pt'] args['max_car_no_park_duration_to_pt'] = args['max_duration_to_pt'] if args['data_freshness'] is None: # retrocompatibilty handling args['data_freshness'] = 'adapted_schedule' if args[ 'disruption_active'] is True else 'base_schedule' # TODO : Changer le protobuff pour que ce soit propre if args['destination_mode'] == 'vls': args['destination_mode'] = 'bss' if args['origin_mode'] == 'vls': args['origin_mode'] = 'bss' # for last and first section mode retrocompatibility if 'first_section_mode' in args and args['first_section_mode']: args['origin_mode'] = args['first_section_mode'] if 'last_section_mode' in args and args['last_section_mode']: args['destination_mode'] = args['last_section_mode'] if region: if uri: objects = uri.split('/') if objects and len(objects) % 2 == 0: args['origin'] = objects[-1] else: abort(503, message="Unable to compute journeys " "from this object") # we transform the origin/destination url to add information if args['origin']: args['origin'] = transform_id(args['origin']) if args['destination']: args['destination'] = transform_id(args['destination']) if args['datetime']: args['original_datetime'] = args['datetime'] else: args['original_datetime'] = pytz.UTC.localize( args['_current_datetime']) if args.get('traveler_type'): traveler_profile = TravelerProfile.make_traveler_profile( region, args['traveler_type']) traveler_profile.override_params(args) # We set default modes for fallback modes. # The reason why we cannot put default values in parser_get.add_argument() is that, if we do so, # fallback modes will always have a value, and traveler_type will never override fallback modes. if args.get('origin_mode') is None: args['origin_mode'] = ['walking'] if args.get('destination_mode') is None: args['destination_mode'] = ['walking'] return args
def get(self, region=None, lon=None, lat=None, uri=None): args = self.parsers['get'].parse_args() if args.get('traveler_type') is not None: traveler_profile = TravelerProfile.make_traveler_profile( region, args['traveler_type']) traveler_profile.override_params(args) # We set default modes for fallback modes. # The reason why we cannot put default values in parser_get.add_argument() is that, if we do so, # fallback modes will always have a value, and traveler_type will never override fallback modes. if args.get('origin_mode') is None: args['origin_mode'] = ['walking'] if args.get('destination_mode') is None: args['destination_mode'] = ['walking'] if args['max_duration_to_pt'] is not None: #retrocompatibility: max_duration_to_pt override all individual value by mode args['max_walking_duration_to_pt'] = args['max_duration_to_pt'] args['max_bike_duration_to_pt'] = args['max_duration_to_pt'] args['max_bss_duration_to_pt'] = args['max_duration_to_pt'] args['max_car_duration_to_pt'] = args['max_duration_to_pt'] if args['data_freshness'] is None: # retrocompatibilty handling args['data_freshness'] = \ 'adapted_schedule' if args['disruption_active'] is True else 'base_schedule' # TODO : Changer le protobuff pour que ce soit propre if args['destination_mode'] == 'vls': args['destination_mode'] = 'bss' if args['origin_mode'] == 'vls': args['origin_mode'] = 'bss' #count override min_nb_journey or max_nb_journey if 'count' in args and args['count']: args['min_nb_journeys'] = args['count'] args['max_nb_journeys'] = args['count'] # for last and first section mode retrocompatibility if 'first_section_mode' in args and args['first_section_mode']: args['origin_mode'] = args['first_section_mode'] if 'last_section_mode' in args and args['last_section_mode']: args['destination_mode'] = args['last_section_mode'] if region: self.region = i_manager.get_region(region) if uri: objects = uri.split('/') if objects and len(objects) % 2 == 0: args['origin'] = objects[-1] else: abort(503, message="Unable to compute journeys " "from this object") def _set_specific_params(mod): if args.get('max_duration') is None: args['max_duration'] = mod.max_duration if args.get('_walking_transfer_penalty') is None: args[ '_walking_transfer_penalty'] = mod.walking_transfer_penalty if args.get('_night_bus_filter_base_factor') is None: args[ '_night_bus_filter_base_factor'] = mod.night_bus_filter_base_factor if args.get('_night_bus_filter_max_factor') is None: args[ '_night_bus_filter_max_factor'] = mod.night_bus_filter_max_factor if region: _set_specific_params(i_manager.instances[region]) else: _set_specific_params(default_values) if not (args['destination'] or args['origin']): abort( 400, message= "you should at least provide either a 'from' or a 'to' argument" ) if args['debug']: g.debug = True #we transform the origin/destination url to add information if args['origin']: args['origin'] = transform_id(args['origin']) if args['destination']: args['destination'] = transform_id(args['destination']) if not args['datetime']: args['datetime'] = datetime.now() args['datetime'] = args['datetime'].replace(hour=13, minute=37) if not region: #TODO how to handle lon/lat ? don't we have to override args['origin'] ? possible_regions = compute_regions(args) else: possible_regions = [region] if args['destination'] and args['origin']: api = 'journeys' else: api = 'isochrone' # we save the original datetime for debuging purpose args['original_datetime'] = args['datetime'] #we add the interpreted parameters to the stats self._register_interpreted_parameters(args) logging.getLogger(__name__).debug( "We are about to ask journeys on regions : {}".format( possible_regions)) #we want to store the different errors responses = {} for r in possible_regions: self.region = r #we store the region in the 'g' object, which is local to a request set_request_timezone(self.region) if args['debug']: # In debug we store all queried region if not hasattr(g, 'regions_called'): g.regions_called = [] g.regions_called.append(r) original_datetime = args['original_datetime'] new_datetime = self.convert_to_utc(original_datetime) args['datetime'] = date_to_timestamp(new_datetime) response = i_manager.dispatch(args, api, instance_name=self.region) if response.HasField(b'error') \ and len(possible_regions) != 1: logging.getLogger(__name__).debug( "impossible to find journeys for the region {}," " we'll try the next possible region ".format(r)) if args['debug']: # In debug we store all errors if not hasattr(g, 'errors_by_region'): g.errors_by_region = {} g.errors_by_region[r] = response.error responses[r] = response continue if all( map( lambda j: j.type in ("non_pt_walk", "non_pt_bike", "non_pt_bss", "car"), response.journeys)): responses[r] = response continue return response for response in responses.values(): if not response.HasField(b"error"): return response # if no response have been found for all the possible regions, we have a problem # if all response had the same error we give it, else we give a generic 'no solution' error first_response = responses.values()[0] if all(r.error.id == first_response.error.id for r in responses.values()): return first_response resp = response_pb2.Response() er = resp.error er.id = response_pb2.Error.no_solution er.message = "No journey found" return resp
def post(self, region=None, lon=None, lat=None, uri=None): args = self.parsers['post'].parse_args() if args['traveler_type']: profile = travelers_profile[args['traveler_type']] profile.override_params(args) #check that we have at least one departure and one arrival if len(args['from']) == 0: abort(400, message="from argument must contain at least one item") if len(args['to']) == 0: abort(400, message="to argument must contain at least one item") # TODO : Changer le protobuff pour que ce soit propre if args['destination_mode'] == 'vls': args['destination_mode'] = 'bss' if args['origin_mode'] == 'vls': args['origin_mode'] = 'bss' if args['max_duration_to_pt']: #retrocompatibility: max_duration_to_pt override all individual value by mode args['max_walking_duration_to_pt'] = args['max_duration_to_pt'] args['max_bike_duration_to_pt'] = args['max_duration_to_pt'] args['max_bss_duration_to_pt'] = args['max_duration_to_pt'] args['max_car_duration_to_pt'] = args['max_duration_to_pt'] #count override min_nb_journey or max_nb_journey if 'count' in args and args['count']: args['min_nb_journeys'] = args['count'] args['max_nb_journeys'] = args['count'] if region: self.region = i_manager.get_region(region) set_request_timezone(self.region) if not region: #TODO how to handle lon/lat ? don't we have to override args['origin'] ? self.region = compute_regions(args) #store json data into 4 arrays args['origin'] = [] args['origin_access_duration'] = [] args['destination'] = [] args['destination_access_duration'] = [] for loop in [('from', 'origin', True), ('to', 'destination', False)]: for location in args[loop[0]]: if "access_duration" in location: args[loop[1]+'_access_duration'].append(location["access_duration"]) else: args[loop[1]+'_access_duration'].append(0) stop_uri = location["uri"] stop_uri = transform_id(stop_uri) args[loop[1]].append(stop_uri) #default Date if not "datetime" in args or not args['datetime']: args['datetime'] = datetime.now() args['datetime'] = args['datetime'].replace(hour=13, minute=37) # we save the original datetime for debuging purpose args['original_datetime'] = args['datetime'] original_datetime = args['original_datetime'] #we add the interpreted parameters to the stats self._register_interpreted_parameters(args) new_datetime = self.convert_to_utc(original_datetime) args['datetime'] = date_to_timestamp(new_datetime) api = 'nm_journeys' response = i_manager.dispatch(args, api, instance_name=self.region) return response
def get(self, region=None, lon=None, lat=None, uri=None): args = self.parsers['get'].parse_args() if args['traveler_type']: profile = travelers_profile[args['traveler_type']] profile.override_params(args) if args['max_duration_to_pt']: #retrocompatibility: max_duration_to_pt override all individual value by mode args['max_walking_duration_to_pt'] = args['max_duration_to_pt'] args['max_bike_duration_to_pt'] = args['max_duration_to_pt'] args['max_bss_duration_to_pt'] = args['max_duration_to_pt'] args['max_car_duration_to_pt'] = args['max_duration_to_pt'] # TODO : Changer le protobuff pour que ce soit propre if args['destination_mode'] == 'vls': args['destination_mode'] = 'bss' if args['origin_mode'] == 'vls': args['origin_mode'] = 'bss' #count override min_nb_journey or max_nb_journey if 'count' in args and args['count']: args['min_nb_journeys'] = args['count'] args['max_nb_journeys'] = args['count'] # for last and first section mode retrocompatibility if 'first_section_mode' in args and args['first_section_mode']: args['origin_mode'] = args['first_section_mode'] if 'last_section_mode' in args and args['last_section_mode']: args['destination_mode'] = args['last_section_mode'] # Technically, bss mode enable walking (if it is better than bss) # so if the user ask for walking and bss, we only keep bss if 'walking' in args['origin_mode'] and 'bss' in args['origin_mode']: args['origin_mode'].remove('walking') if 'walking' in args['destination_mode'] and 'bss' in args['destination_mode']: args['destination_mode'].remove('walking') if region: self.region = i_manager.get_region(region) if uri: objects = uri.split('/') if objects and len(objects) % 2 == 0: args['origin'] = objects[-1] else: abort(503, message="Unable to compute journeys " "from this object") if not args["origin"]: #@vlara really ? I though we could do reverse isochrone ? #shoudl be in my opinion if not args["origin"] and not args["destination"]: abort(400, message="from argument is required") #we transform the origin/destination url to add information if args['origin']: args['origin'] = transform_id(args['origin']) if args['destination']: args['destination'] = transform_id(args['destination']) if not args['datetime']: args['datetime'] = datetime.now() args['datetime'] = args['datetime'].replace(hour=13, minute=37) if not region: #TODO how to handle lon/lat ? don't we have to override args['origin'] ? possible_regions = compute_regions(args) else: possible_regions = [region] api = None if args['destination']: api = 'journeys' else: api = 'isochrone' # we save the original datetime for debuging purpose args['original_datetime'] = args['datetime'] #we add the interpreted parameters to the stats self._register_interpreted_parameters(args) logging.getLogger(__name__).debug("We are about to ask journeys on regions : {}" .format(possible_regions)) #we want to store the different errors responses = {} for r in possible_regions: self.region = r #we store the region in the 'g' object, which is local to a request set_request_timezone(self.region) if args['debug']: # In debug we store all queried region if not hasattr(g, 'regions_called'): g.regions_called = [] g.regions_called.append(r) original_datetime = args['original_datetime'] new_datetime = self.convert_to_utc(original_datetime) args['datetime'] = date_to_timestamp(new_datetime) response = i_manager.dispatch(args, api, instance_name=self.region) if response.HasField('error') \ and len(possible_regions) != 1: logging.getLogger(__name__).debug("impossible to find journeys for the region {}," " we'll try the next possible region ".format(r)) if args['debug']: # In debug we store all errors if not hasattr(g, 'errors_by_region'): g.errors_by_region = {} g.errors_by_region[r] = response.error responses[r] = response continue if all(map(lambda j: j.type in ("non_pt_walk", "non_pt_bike", "non_pt_bss", "car"), response.journeys)): responses[r] = response continue return response for response in responses.itervalues(): if not response.HasField("error"): return response # if no response have been found for all the possible regions, we have a problem # if all response had the same error we give it, else we give a generic 'no solution' error first_response = responses.itervalues().next() if all(r.error.id == first_response.error.id for r in responses.values()): return first_response resp = response_pb2.Response() er = resp.error er.id = response_pb2.Error.no_solution er.message = "No journey found" return resp
def test_transform_id_something(self): id = "something" uri = id assert transform_id(id) == uri
def test_transform_id_address(self): id = "address:toto:12345" uri = id assert transform_id(id) == uri
def test_transform_id_admin(self): id = "admin:fr:12345" uri = id assert transform_id(id) == uri
def test_transform_id_almost_coord(self): id = "1.23456789012345;2.23456789012345toto" uri = id assert transform_id(id) == uri
def test_transform_id_coord(self): id = "1.23456789012345;2.23456789012345" uri = "coord:1.23456789012345:2.23456789012345" assert transform_id(id) == uri
def test_transform_id_address(self): id = "address:1:12345" uri = "address:12345" assert transform_id(id) == uri