access different endpoints of API to get certain data (we usually don't want all the data)
Request Handler
When building an application that queries from an API a lot, we need to expect errors in handling requests to the API. We can build a handler class to handle all the exceptions without filling our code with try-excepts.
General rule of thumb: When we find we have many repetitive try-excepts, build a handler class.
"""Class with methods that handle requests to API"""import jsonimport timefrom typing import Unionimport requestsfrom handlers.handler import Handlerfrom logger import loggerbase_url ="http://some-api.com"# Handler class is a parent class that handles parsing the credentialsclassRequestHandler(Handler):"""Class that handles requests"""def__init__(self,*args,**kwargs) ->None:super(RequestHandler, self).__init__(*args, **kwargs) api_credentials = self.get_credentials()# this method comes from the parent Handler class self.default_params ={"some_param":"some_value"}defget_request(self,url_path:str,params=None) -> Union[None, requests.Response]:"""Sends GET request to API"""if params: self.default_params.update(params) request_url = base_url + url_pathtry: response = requests.get( request_url, headers={"Content-Type": "application/json"}, params=self.default_params, auth=(credentials["user"], credentials["password"]), )except requests.exceptions.RequestException as err: logger.error("Unable to fetch %s\n%s", err, request_url)returnNoneifhasattr(response, "status_code"): status_code = response.status_codeelse: logger.error("Response has no status_code attribute")returnNoneif status_code ==429: time.sleep(60) response = self.get_request(url_path, params=params, api=api)if status_code !=200: logger.error("Unable to fetch - return code %s\n%s", status_code, request_url )returnNonereturn responsedefget_response_json(self,response: requests.Response,requested_info:str ) -> Union[None,dict]:"""Gets JSON from response"""ifnot response:returnNonetry: response_json = response.json()except json.decoder.JSONDecodeError: logger.error("Could not decode JSON for %s", requested_info) response_json =Nonereturn response_json