def function_wrapper(*args, **kwargs): response = function(*args, **kwargs) try: # if the authorization is invalid, refresh the API access token if response.status_code == 401: from plantpredict.oauth2 import OAuth2 OAuth2.refresh() # if there is a sever side error, return the error message elif not 200 <= response.status_code < 300: raise APIError(response.status_code, response.content) # if the HTTP request receives a successful response else: # if the response contains content, return it if response.content: if "Queue" in response.url: return json.loads(response.content) else: # if it is a list, use convert_json method in list comprehension if isinstance(json.loads(response.content), list): return [convert_json(i, camel_to_snake) for i in json.loads(response.content)] else: return convert_json(json.loads(response.content), camel_to_snake) # if the response does not contain content, return a generic success message else: return {'is_successful': True} except AttributeError: return response
def search(self, latitude, longitude, search_radius=1): """ GET /Weather/Search Searches for all existing Weather entities within a search radius of a specified latitude/longitude. :param latitude: North-South coordinate of the Weather location, in decimal degrees. :type latitude: float :param longitude: East-West coordinate of the Project location, in decimal degrees. :type longitude: float :param search_radius: search radius in miles :type search_radius: float :return: #TODO :rtype: list of dicts """ response = requests.get( url=self.api.base_url + "/Weather/Search", headers={"Authorization": "Bearer " + self.api.access_token}, params=convert_json( { 'latitude': latitude, 'longitude': longitude, 'search_radius': search_radius }, snake_to_camel)) weather_list = json.loads(response.content) return [convert_json(w, camel_to_snake) for w in weather_list]
def update(self): """Generic PUT request.""" return requests.put( url=self.api.base_url + self.update_url_suffix, headers={"Authorization": "Bearer " + self.api.access_token}, json=convert_json(self.__dict__, snake_to_camel))
def search(self, latitude, longitude, search_radius=1.0): """HTTP Request: GET /Project/Search Searches for all existing Project entities within a search radius of a specified latitude/longitude. :param latitude: North-South coordinate of the Project location, in decimal degrees. :type latitude: float :param longitude: East-West coordinate of the Project location, in decimal degrees. :type longitude: float :param search_radius: search radius in miles :type search_radius: float :return: TODO """ response = requests.get( url=self.api.base_url + "/Project/Search", headers={"Authorization": "Bearer " + self.api.access_token}, params={ 'latitude': latitude, 'longitude': longitude, 'searchRadius': search_radius }) project_list = json.loads(response.content) return [convert_json(p, camel_to_snake) for p in project_list]
def test_convert_json_camel_to_snake(self): with open('test_data/test_convert_json_camel.json', 'rb') as json_file: snake_dict = utilities.convert_json(json.load(json_file), utilities.camel_to_snake) with open('test_data/test_convert_json_snake.json', 'rb') as json_file: self.assertEqual(snake_dict, json.load(json_file))
def get_nodal_data(self, params=None): """GET /Project/{ProjectId}/Prediction/{Id}/NodalJson""" return requests.get( url=self.api.base_url + "/Project/{}/Prediction/{}/NodalJson".format( self.project_id, self.id), headers={"Authorization": "Bearer " + self.api.access_token}, params=convert_json(params, snake_to_camel) if params else {})
def get(self): """Generic GET request.""" response = requests.get( url=self.api.base_url + self.get_url_suffix, headers={"Authorization": "Bearer " + self.api.access_token}) attr = convert_json(json.loads(response.content), camel_to_snake) for key in attr: setattr(self, key, attr[key]) return response
def create(self, *args): """Generic POST request.""" response = requests.post( url=self.api.base_url + self.create_url_suffix, headers={"Authorization": "Bearer " + self.api.access_token}, json=convert_json(self.__dict__, snake_to_camel) ) # power plant is the exception that doesn't have its own id. has a project and prediction id try: self.id = json.loads(response.content)['id'] if 200 <= response.status_code < 300 else None except ValueError: pass return response
def get_time_zone(self): """GET /Geo/{Latitude}/{Longitude}/TimeZone :return: Example response - { u'timeZone': -8.0 } """ response = requests.get( url=self.api.base_url + "/Geo/{}/{}/TimeZone".format(self.latitude, self.longitude), headers={"Authorization": "Bearer " + self.api.access_token}) attr = convert_json(json.loads(response.content), camel_to_snake) for key in attr: setattr(self, key, attr[key]) return response
def get_closest_station(self): """ Returns the ASHRAE station with the shortest distance from the specified latitude and longitude. Sets the returned information as attributes on the instance of this class. :return: # TODO once new http response is implemented """ response = requests.get( url=self.api.base_url + "/ASHRAE", headers={"Authorization": "Bearer " + self.api.access_token}, params={ "latitude": self.latitude, "longitude": self.longitude }) attr = convert_json(json.loads(response.content), camel_to_snake) for key in attr: setattr(self, key, attr[key]) return response
def run(self, export_options=None): """ POST /Project/{ProjectId}/Prediction/{PredictionId}/Run Runs the Prediction and waits for simulation to complete. The input variable "export_options" should take the :param export_options: Contains options for exporting :return: """ response = requests.post( url=self.api.base_url + "/Project/{}/Prediction/{}/Run".format(self.project_id, self.id), headers={"Authorization": "Bearer " + self.api.access_token}, json=convert_json(export_options, snake_to_camel) if export_options else None) # TODO why didn't this return an error? it only returned when I stopped the script # observes task queue to wait for prediction run to complete self._wait_for_prediction() return response
def get_station(self, station_name=None): """ Returns the ASHRAE station matching the specified name and shortest distance from the specified latitude and longitude. Sets the returned information as attributes on the instance of this class. :param str station_name: Valid name of ASHRAE weather station :return: # TODO once new http response is implemented """ self.station_name = station_name if station_name else self.station_name response = requests.get( url=self.api.base_url + "/ASHRAE/GetStation", headers={"Authorization": "Bearer " + self.api.access_token}, params={ "latitude": self.latitude, "longitude": self.longitude, "stationName": self.station_name }) attr = convert_json(json.loads(response.content), camel_to_snake) for key in attr: setattr(self, key, attr[key]) return response
def get_location_info(self): """GET /Geo/{Latitude}/{Longitude}/Location :return: Example response - { u'country': u'United States', u'country_code': u'US', u'locality': u'San Francisco', u'region': u'North America', u'state_province': u'California', u'state_province_code': u'CA' } """ response = requests.get( url=self.api.base_url + "/Geo/{}/{}/Location".format(self.latitude, self.longitude), headers={"Authorization": "Bearer " + self.api.access_token}) attr = convert_json(json.loads(response.content), camel_to_snake) for key in attr: setattr(self, key, attr[key]) return response
def get_elevation(self): """ **GET** */Geo/* :py:attr:`latitude` */* :py:attr:`longitude` */Elevation* Retrieves the elevation in meters for a given latitude and longitude. In addition to returning a dictionary with this information, the method also automatically assigns the contents of the dictionary to the instance of :py:mod:`Geo` as attributes. .. container:: toggle .. container:: header **Required Attributes** .. container:: required_attributes .. csv-table:: Minimum required attributes on object to call this method successfully. :delim: ; :header: Field, Type, Description :stub-columns: 1 latitude; float; North-South GPS coordinate. Must be between :py:data:`-90` and :py:data:`90` - units :py:data:`[decimal degrees]`. longitude; float; East-West GPS coordinate Must be between :py:data:`-180` and :py:data:`180` units :py:data:`[decimal degrees]`. .. container:: toggle .. container:: header **Example Code** .. container:: example_code Instantiate a local object instance of :py:mod:`Geo` with latitude and longitude as inputs (which automatically assigns them as attributes to the object). Then call the method on the object. .. code-block:: python geo = api.geo(latitude=35.1, longitude=-106.7) geo.get_elevation() .. container:: toggle .. container:: header **Example Response** .. container:: example_response The method returns a dictionary as shown in the example below, and assigns its contents as attributes to the local object instance of :py:mod:`Geo`. .. code-block:: python { "elevation": 1553.614 } :return: A dictionary with location information as shown in "Example Response". :rtype: dict """ response = requests.get( url=self.api.base_url + "/Geo/{}/{}/Elevation".format(self.latitude, self.longitude), headers={"Authorization": "Bearer " + self.api.access_token}) attr = convert_json(json.loads(response.content), camel_to_snake) for key in attr: setattr(self, key, attr[key]) return response