import logging import requests from datetime import datetime, timedelta class OpenERZConnector: """A simple connector to interact with OpenERZ API.""" def __init__(self, zip_code, waste_type): """Initialize the API connector. Args: zip_code (int): post code of the area of interest waste_type (str): type of waste to be picked up (paper/cardboard/waste/cargotram/etram/organic/textile) """ self.zip = zip_code self.waste_type = waste_type self.start_date = datetime.now() self.end_date = None self.last_api_response = None self.logger = logging.getLogger(__name__) def update_start_date(self): """Set the start day to today.""" self.start_date = datetime.now() def find_end_date(self, day_offset=31): """Find the end date for the request, given an offset expressed in days. Args: day_offset (int): difference in days between start and end date of the request """ self.end_date = self.start_date + timedelta(days=day_offset) def make_api_request(self): """Construct a request and send it to the OpenERZ API.""" headers = {"accept": "application/json"} start_date = self.start_date.strftime("%Y-%m-%d") end_date = self.end_date.strftime("%Y-%m-%d") payload = { "zip": self.zip, "types":self.waste_type, "start": start_date, "end": end_date, "offset": 0, "limit": 1, "lang": "en", "sort": "date", } url = f"https://openerz.metaodi.ch/api/calendar.json" try: self.last_api_response = requests.get(url, params=payload, headers=headers) except requests.exceptions.RequestException as connection_error: self.logger.error("RequestException while making request to OpenERZ: %s", connection_error) def parse_api_response(self): """Parse the JSON response received from the OpenERZ API and return a date of the next pickup.""" if not self.last_api_response.ok: self.logger.warning( "Last request to OpenERZ was not successful. Status code: %d", self.last_api_response.status_code, ) return None response_json = self.last_api_response.json() if response_json["_metadata"]["total_count"] == 0: self.logger.warning("Request to OpenERZ returned no results.") return None result_list = response_json.get("result") first_scheduled_pickup = result_list[0] if first_scheduled_pickup["zip"] == self.zip and first_scheduled_pickup["waste_type"] == self.waste_type: return first_scheduled_pickup["date"] self.logger.warning("Either zip or waste type does not match the ones specified in the configuration.") return None def find_next_pickup(self, day_offset=31): """Find the next pickup date within the next X days, given zip_code and waste type Args: day_offset (int): difference in days between start and end date of the request """ self.update_start_date() self.find_end_date(day_offset=day_offset) self.make_api_request() next_pickup_date = self.parse_api_response() return next_pickup_date