Source code for bingmaps.urls.traffic_build_urls

from marshmallow import Schema, fields, post_dump, validate, pre_dump


[docs]class TrafficIncidentsUrl(object): """This class helps in building a url for elevations API service. :ivar data: Data required for building up the URL :ivar protocol: http protocol for the url :ivar schema: Elevations schema to which the data will be dumped All the URL values are retrieved from the schema. Example: :: >>> data = {'mapArea': [37, -105, 45, -94], ... 'includeLocationCodes': 'true', ... 'type': [5], ... 'o': 'xml', ... 'key': 'abs'} >>> url = TrafficIncidentsUrl(data, TrafficIncidentsSchema(), ... 'http') >>> url.main_url 'dev.virtualearth.net' >>> url.protocol 'http:/' >>> url.resourcePath 'Incidents' >>> url.restApi 'Traffic' >>> url.rest 'REST' >>> url.version 'v1' >>> url.query '37.0,-105.0,45.0,-94.0/true?type=5&o=xml&key=abs' """ def __init__(self, data, schema, protocol='http'): self.data = data self.http_protocol = protocol self.schema_dict = self.schema_values(schema) def schema_values(self, schema): is_valid_schema = schema.validate(self.data) if bool(is_valid_schema): raise KeyError(is_valid_schema) else: return schema.dump(self.data).data @property def protocol(self): """This property helps in returning the http protocol to be used as part of the URL. :ivar http_protocol: The http protocol passed in (http/https) :getter: Returns a string relevant to the http protocol - http: ``http:/`` - https: ``https:/`` :type: string """ if self.http_protocol == 'http': return 'http:/' else: return 'https:/' @property def main_url(self): """This property helps in returning the main URL used in bingmaps rest services :getter: Returns a URL - ``dev.virtualearth.net`` :type: string """ return 'dev.virtualearth.net' @property def rest(self): """This property make the URL accessible for REST services. :getter: Returns a string saying that the URL is a REST service URL - ``REST`` :type: string """ return 'REST' @property def version(self): """This property gives the version of the Bing Maps REST services :getter: Returns a string of Bing Maps REST services version - ``v1`` for Elevations services :type: string """ if 'version' in self.schema_dict: return self.schema_dict['version'] else: return None @property def restApi(self): """This property gives a part of the URL that identifies the REST API :getter: Returns a part of the URL that identifies the REST API - ``Elevations`` for Elevations services :type: string """ if 'restApi' in self.schema_dict: return self.schema_dict['restApi'] else: return None @property def resourcePath(self): """This property gives a part of the URL that specifies a resource such as an address or landmark. :getter: Returns a string that identifies the resource path such as address or landmark - ``None`` for Elevations services :type: string """ if 'resourcePath' in self.schema_dict: return self.schema_dict['resourcePath'] else: return None @property def query(self): """This property helps in retrieving the query part of the URL :getter: Returns a part of the URL which consist of all the query parameters. :type: string """ return self.schema_dict['query']
class MainParams(Schema): version = fields.Constant( 'v1', required=True ) restApi = fields.Constant( 'Traffic', required=True ) resourcePath = fields.Constant( 'Incidents', required=True )
[docs]class TrafficIncidentsSchema(MainParams, Schema): """Schema for query parameters in which all the fields will be in a ordered way. All the fields will be dumped in the same order as mentioned in the schema. Data Fields for the schema (taken from https://msdn.microsoft.com/en-us/library/hh441726.aspx): :ivar mapArea[Required]: A rectangular area specified as a bounding box. The size of the area can be a maximum of 500 km x 500 km. A bounding box defines an area by specifying SouthLatitude, WestLongitude, NorthLatitude, and EastLongitude values. :ivar includeLocationCodes[Optional]: One of the following values: - 'true' - 'false' [default] If you want to use the default value, you can omit this parameter from the URL request. :ivar severity[Optional]: One or more of the following integer values: - 1: LowImpact - 2: Minor - 3: Moderate - 4: Serious The default is to return traffic incidents for all severity levels. :ivar type[Optional]: One or more of the following integer values: - 1: Accident - 2: Congestion - 3: DisabledVehicle - 4: MassTransit - 5: Miscellaneous - 6: OtherNews - 7: PlannedEvent - 8: RoadHazard - 9: Construction - 10: Alert - 11: Weather :ivar o[Optional]: A string specifying the output as JSON or xml. :ivar key[Required]: Bing maps key - REQUIRED field This schema helps in serializing the data. Post-Dump: After dumping the data, build_query_string builds up the queryParameters string. The final value after dumping the data would be a string. Example: :: >>> data = {'mapArea': [37, -105, 45, -94], ... 'includeLocationCodes': 'true', ... 'type': [5], ... 'o': 'xml', ... 'key': 'abs'} >>> query = TrafficIncidentsSchema() >>> query.dump(data).data OrderedDict([('version', 'v1'), ('restApi', 'Traffic'), \ ('resourcePath', 'Incidents'), ('query', \ '37.0,-105.0,45.0,-94.0/true?type=5&o=xml&key=abs')]) """ mapArea = fields.List( fields.Float, required=True, error_messages={'required': 'All the four coordinates required'}, validate=validate.Length( min=4, max=4, error='All the four coordinates should be entered: south latitude,' 'west longitude, north latitude and east longitude in the ' 'same order' ) ) includeLocationCodes = fields.Str( default='false' ) severity = fields.List( fields.Int ) type = fields.List( fields.Int ) o = fields.Str() key = fields.Str( required=True, error_messages={'required': 'Bing Maps API key required'} ) class Meta: fields = ('version', 'restApi', 'resourcePath', 'mapArea', 'includeLocationCodes', 'severity', 'type', 'o', 'key') ordered = True @post_dump def build_url(self, data): """This method occurs after dumping the data into the class. Args: data (dict): dictionary of all the query values Returns: data (dict): ordered dict of all the values """ query_part_one = [] query_part_two = [] keys_to_be_removed = [] for key, value in data.items(): if key not in ['version', 'restApi', 'resourcePath']: if key == 'mapArea': query_part_one.append(','.join(str(val) for val in value)) keys_to_be_removed.append(key) elif key == 'includeLocationCodes': query_part_one.append(value) keys_to_be_removed.append(key) else: if isinstance(value, list): value = ','.join(str(val) for val in value) query_part_two.append('{0}={1}'.format(key, value)) keys_to_be_removed.append(key) for k in keys_to_be_removed: del data[k] data['query'] = '{0}?{1}'.format('/'.join(query_part_one), '&'.join(query_part_two)) return data