def mortgage_offers(self): """ Retrieve finansportalen.no's boliglån grunndata xml and returns dict for content Returns ------- out : dict content from boliglån grunndata Xxml feed """ LOGGER.info("trying to retrieve '{}'".format( self.mortgage_offers.__name__)) response = self.portalen_response() if response: tree = Et.fromstring(response.content.decode( "windows-1252")).findall(PORTALEN_ENTRY) offers = {} count = 0 for entries in tree: count += 1 offers.update({ count: { re.sub("{[^>]+}", "", entry.tag): entry.text.strip() for entry in entries if entry.text } }) LOGGER.success("'{}' successfully retrieved".format( self.mortgage_offers.__name__)) return offers raise NotFoundError("No 'mortgage_offers' received")
def __init__(self, family_members: list = None, income: Union[int, float, str] = 0, cars: Union[int, str] = 0): """ Constructor / Instantiate the class Parameters ---------- family_members : list list of Person (Male or Female) instances income : int, float, str gross yearly income cars : int, str number of cars in the family """ super().__init__() try: self._assert_family_members(family_members) Assertor.assert_data_types([income, cars], [(int, float, str), (int, str)]) Assertor.assert_non_negative([income, cars]) self._family_members = family_members self._inntekt = str(income) self._antall_biler = str(cars) LOGGER.success( "created '{}', with id: [{}]".format(self.__class__.__name__, self.id_str)) except Exception as family_exception: LOGGER.exception(family_exception) raise family_exception
def __init__(self, age: Union[str, int], income: Union[str, int, float]): """ Constructor / Instantiate the class Parameters ---------- age : str, int age of individual income : str, int, float income of individual """ try: super().__init__() Assertor.assert_data_types([age, income], [(str, int), (str, int, float)]) self.age = str(age + 1) self.income = str(income) self.year = str(2022) self.url = SKATTEETATEN_URL + self.year LOGGER.success("created '{}', with id: [{}]".format( self.__class__.__name__, self.id_)) except Exception as skatteetaten_exception: LOGGER.exception(skatteetaten_exception) raise skatteetaten_exception
def ssb_interest_rates(self): """ gets the interest information from SSB table nr. 10748 Returns ------- out : dict interest rate information from SSB """ try: LOGGER.info("trying to retrieve '{}'".format( self.ssb_interest_rates.__name__)) response = self.response().json() keys = response["dimension"]["Rentebinding"]["category"][ "label"].values() values = response["value"] LOGGER.success("'{}' successfully retrieved".format( self.ssb_interest_rates.__name__)) return { key.lower(): str(val) for key, val in dict(zip(keys, values)).items() } except Exception as ssb_interest_rates_exception: LOGGER.exception(ssb_interest_rates_exception) raise ssb_interest_rates_exception
def __init__(self, utlanstype: list = None, sektor: list = None, rentebinding: list = None, tid: list = None): """ Constructor / Instantiate the class Parameters ---------- utlanstype : list type of loan, default ["70"] sektor : list sektor, default is ["04b"] rentebinding : list type of interest rate, default is ["08", "12", "10", "11", "06"] tid : list time frame """ try: LOGGER.info("trying to create '{}'".format( self.__class__.__name__)) Assertor.assert_data_types([utlanstype, sektor, rentebinding, tid], [(type(None), list) for _ in range(3)]) self.utlanstype = ["70"] if not utlanstype else utlanstype self.sektor = ["04b"] if not sektor else sektor self.rentebinding = ["08", "12", "10", "11", "06" ] if not rentebinding else rentebinding self.tid = self._updated_table_date() if not tid else tid LOGGER.success("created {}".format(self.__class__.__name__)) except Exception as ssb_payload_exception: LOGGER.exception(ssb_payload_exception) raise ssb_payload_exception
def update(self, db_name: str, col_name: str, query: dict, new_value: dict): """ method for updating document(s) in a collection Parameters ---------- db_name : str db name to look for collection col_name : str collection name to apply update query : dict document to query new_value : dict new values to apply in document """ try: LOGGER.info("trying to '{}' document '{}' with value '{}'".format( self.update.__name__, query, new_value)) Assertor.assert_data_types([db_name, col_name], [str, str]) collection = getattr(self._client, db_name.lower())[col_name.lower()] collection.update_many(query, new_value) LOGGER.success("'{}' successfully completed".format( self.update.__name__)) except Exception as exp: LOGGER.exception(exp) raise exp
def sifo_expenses(self): """ get SIFO expenses given the family information Returns ------- out : dict dictionary with SIFO expenses """ try: LOGGER.info("trying to retrieve '{}'".format( self.sifo_expenses.__name__)) soup = BeautifulSoup(self.response(), "xml") root = Et.fromstring(soup.prettify()) expenses = {'_id': self.family.id_str} for child in root: expenses.update( {child.tag: child.text.strip().replace(".", "")}) LOGGER.success("'{}' successfully retrieved".format( self.sifo_expenses.__name__)) return expenses except Exception as sifo_expenses_exception: LOGGER.exception(sifo_expenses_exception) raise sifo_expenses_exception
def read(self, db_name: str, col_name: str): """ method for reading all documents in a collection Parameters ---------- db_name : str db name to lookup col_name : str collection name to lookup Returns ------- out : list all documents in collection """ try: LOGGER.info( "trying to '{}' all documents in collection: '{}' from db: '{}'" .format(self.read.__name__, col_name, db_name)) Assertor.assert_data_types([db_name, col_name], [str, str]) documents = [] for document in getattr(self._client[db_name.lower()], col_name.lower()).find(): documents.append(document) LOGGER.success( "'{}' successfully completed - '{}' document(s) found".format( self.read.__name__, len(documents))) return documents except Exception as exp: LOGGER.exception(exp) raise exp
def delete(self, db_name: str, col_name: str): """ Delete all documents in collection. Will also delete the db that the collection is in. Parameters ---------- db_name : str name of db col_name : str name of collection to be deleted """ try: LOGGER.info( "trying to '{}' all documents from collection: '{}' in db: '{}'" .format(self.delete.__name__, col_name, db_name)) Assertor.assert_data_types([db_name, col_name], [str, str]) collection = getattr(self._client, db_name)[col_name] count = collection.count() collection.drop() LOGGER.success( "'{}' successfully completed - '{}' document(s) deleted". format(self.delete.__name__, count)) except Exception as exp: LOGGER.exception(exp) raise exp
def sifo_base_expenses(self, include_id: bool = False): """ get SIFO base expenses given the family information Returns ------- out : dict dictionary with SIFO expenses """ LOGGER.info("trying to retrieve '{}'".format( self.sifo_base_expenses.__name__)) response_json = self.response().json()["utgifter"] sifo_expenses = {} sifo_expenses.update(response_json['individspesifikke']) sifo_expenses.update({'sumindivid': response_json['sumindivid']}) sifo_expenses.update(response_json['husholdsspesifikke']) sifo_expenses.update( {'sumhusholdning': response_json['sumhusholdning']}) sifo_expenses.update({'totalt': response_json['totalt']}) sifo_expenses = {key: str(val) for key, val in sifo_expenses.items()} if include_id: sifo_expenses.update({'_id': self.family.id_}) # import json # with open('sifo_data.json', 'w', encoding='utf-8') as file: # json.dump(sifo_expenses, file, ensure_ascii=False, indent=4) LOGGER.success("'{}' successfully retrieved".format( self.sifo_base_expenses.__name__)) return sifo_expenses
def __init__(self, age: Union[int, float, str] = 0, kinder_garden: str = '0', sfo: str = '0', pregnant: str = '0'): """ Constructor / Instantiate the class Parameters ---------- age : int, float, str age of person kinder_garden : str kids in kinder garden, '1' true or '0' false sfo : str After school programme, '1' true or '0' false pregnant : str Pregnant female, '1' true or '0' false """ try: super().__init__('k', age, kinder_garden, sfo) Assertor.assert_data_types([age, kinder_garden, sfo], [(float, int, str), str, str]) Assertor.assert_arguments({pregnant: ['pregnant', ('0', '1')]}) if Person.sifo_age(age) not in ('19', '50') and pregnant == '1': raise ValueError("pregnancy at this age is not possible") self._gravid = pregnant LOGGER.success("created '{}', with id: [{}]".format( self.__class__.__name__, self.id_str)) except Exception as female_exception: LOGGER.exception(female_exception) raise female_exception
def postal_code_info(self): """ gets postal code information Returns ------- out : dict dictionary with postal code information """ LOGGER.info("trying to retrieve 'postal_code_info' for -> '{}'".format( self.postal_code)) soup = BeautifulSoup(self.response().content, "lxml") rows = soup.find_all("tr") # with open('content.html', 'w', encoding='utf-8') as file: # file.write(soup.prettify()) if len(rows) == 2: header = [ head.text.strip().lower() for head in soup.find_all('th') ] values = [ value.text.strip().upper() if i != 4 else value.text.strip().upper().rsplit(' ', 1)[0] for i, value in enumerate(rows[1].find_all('td')) ] LOGGER.success("'postal_code_info' successfully retrieved") return { hdr: val for hdr, val in dict(zip(header, values)).items() if val } raise NotFoundError("'{}' is an invalid postal code".format( self.postal_code))
def mortgage_offers(self): """ Retrieve finansportalen.no's boliglån grunndata xml and returns dict for content Returns ------- out : dict content from boliglån grunndata Xxml feed """ try: LOGGER.info("trying to retrieve '{}'".format( self.mortgage_offers.__name__)) offers = {} soup = BeautifulSoup( self.response().content.decode("windows-1252"), "xml") root = Et.fromstring(soup.prettify()) remove_url_re = '{[^>]+}' for i, children in enumerate(root.findall(PORTALEN_ENTRY)): offers.update({ i + 1: { re.sub(remove_url_re, '', child.tag): child.text.strip() for child in children if child.text } }) LOGGER.success("'{}' successfully retrieved".format( self.mortgage_offers.__name__)) return offers except Exception as mortgage_offers_exception: LOGGER.exception(mortgage_offers_exception) raise mortgage_offers_exception
def __init__(self): """ Constructor / Instantiate the class """ super().__init__() self._browser = None LOGGER.success("created '{}', with id: [{}]".format( self.__class__.__name__, self.id_))
def to_json(self, file_dir: str = "report/json/mortgage_offers"): """ save mortgage offers information to JSON file """ self.save_json(self.housing_information(), file_dir, file_prefix="HousingInfo_") LOGGER.success("'{}' successfully parsed to JSON at '{}'".format( self.housing_information().__name__, file_dir))
def to_json(self, file_dir: str = "report/json/finn_information"): """ save statistics information to JSON file """ Assertor.assert_data_types([file_dir], [str]) self.save_json(self.community_stat_information(), file_dir, file_prefix="CommunityStatInfo_") LOGGER.success( "'community_stat_information' successfully parsed to JSON at '{}'".format(file_dir))
def to_json(self, file_dir: str = "report/json/finn_information"): """ save ownership information to JSON file """ self.save_json(self.housing_ownership_information(), file_dir, file_prefix="HousingOwnershipInfo_") LOGGER.success( "'housing_ownership_information' successfully parsed to JSON at '{}'".format(file_dir))
def to_json(self, file_dir: str = "report/json/mortgage_offers"): """ save mortgage offers information to JSON file """ self.save_json(self.mortgage_offers(), file_dir, file_prefix="MortgageOffers_") LOGGER.success( "'mortgage_offers' successfully parsed to JSON at '{}'".format( file_dir))
def __init__(self): """ Constructor / Instantiate the class """ try: super().__init__() self._browser = requests.post(PORTALEN_URL, auth=PORTALEN_CRED) LOGGER.success("created '{}', with id: [{}]".format( self.__class__.__name__, self.id_str)) except Exception as portalen_exception: LOGGER.exception(portalen_exception) raise portalen_exception
def to_json(self, file_dir: str = "report/json/finn_information"): """ save advert information to JSON file """ Assertor.assert_data_types([file_dir], [str]) self.save_json(self.housing_ad_information(), file_dir, file_prefix="HousingAdInfo_") LOGGER.success( "'housing_ad_information' successfully parsed to JSON at '{}'".format(file_dir))
def to_json(self, file_dir: str = "report/json/interest_rates"): """ save ssb interest rate information to JSON Parameters ---------- file_dir : str file directory to save JSON files """ self.save_json(self.ssb_interest_rates(), file_dir=file_dir, file_prefix="SsbInterestRates_") LOGGER.success("'{}' successfully parsed to JSON at '{}'".format( self.ssb_interest_rates.__name__, file_dir))
def to_json(self, file_dir: str = "report/json/expenses"): """ save sifo expenses to JSON Parameters ---------- file_dir : str file directory to save JSON files """ self.save_json(self.sifo_expenses(), file_dir=file_dir, file_prefix="SifoExpenses_") LOGGER.success("'{}' successfully parsed to JSON at '{}'".format( self.sifo_expenses.__name__, file_dir))
def to_json(self, file_dir: str = "report/json/postal_code"): """ save postal code information to JSON Parameters ---------- file_dir : str file directory to save JSON files """ self.save_json(self.postal_code_info(), file_dir=file_dir, file_prefix="PostalCode_") LOGGER.success( "'postal_code_info' successfully parsed to JSON at '{}'".format( file_dir))
def to_json(self, file_dir: str): """ save sifo expenses to JSON Parameters ---------- file_dir : str file directory to save JSON files """ self.save_json(self.sifo_base_expenses(), file_dir=file_dir, file_prefix="SifoExpenses_") LOGGER.success( "'sifo_expenses' successfully parsed to JSON at '{}'".format( file_dir))
def housing_ownership_information(self): """ Retrieve and parse housing ownership history information from Finn.no search to dict Returns ------- out : dict """ LOGGER.info( "trying to retrieve 'housing_ownership_information' for -> '{}'".format(self.finn_code)) history_headers = None history_results = [] keys = [] values = [] try: owner_soup = BeautifulSoup(self.ownership_response().content, "lxml") for geo_val in owner_soup.find_all("dl", attrs={"class": "definition-list u-mb32"}): for i, val in enumerate(geo_val.text.split("\n")): if i % 2 != 0 and val: keys.append(val.strip().lower().replace("å", "a")) elif val: values.append(val.strip()) for table_row in owner_soup.find( "table", attrs={"class": "data-table u-mb32"}).find_all("tr"): if not history_headers: history_headers = [head.text for head in table_row.find_all("th")] row = [tab_row.text.strip().replace(",-", " kr") for tab_row in table_row.find_all("td") if tab_row.text.strip()] if row: history_results.append(row) info = dict(zip(keys, values)) historic_df = DataFrame(history_results, columns=history_headers) info.update( {"historikk": historic_df.assign(Pris=historic_df.iloc[:, -1].str.replace( ",", " kr").str.replace("\u2212", "")).to_dict()}) LOGGER.success("'housing_ownership_information' successfully retrieved") return info except AttributeError as no_ownership_history_exception: LOGGER.debug("[{}] No ownership history found!, exited with '{}'".format( self.__class__.__name__, no_ownership_history_exception))
def __init__(self, number: str): """ Constructor / Instantiate the class Parameters ---------- number : str phone number to be validated """ try: super().__init__() Assertor.assert_data_types([number], [str]) self.number = number LOGGER.success("created '{}', with id: [{}]".format( self.__class__.__name__, self.id_str)) except Exception as phone_exception: LOGGER.exception(phone_exception) raise phone_exception
def __init__(self): """ Constructor / Instantiate the class. Should only create one connection to the MongoDB cloud database cluster. """ try: LOGGER.info("trying to create '{}'".format( self.__class__.__name__)) self._id_str = str(uuid4()) self._client = MongoClient(DB_STRING) self._db = None self._collection = None LOGGER.success("created '{}', with id: [{}]".format( self.__class__.__name__, self.id_str)) except Exception as dao_exception: LOGGER.exception(dao_exception) raise dao_exception
def __init__(self, family: Family): """ Constructor / Instantiate the class Parameters ---------- family : Family object with family information """ try: super().__init__() Assertor.assert_data_types([family], [Family]) self._family = family LOGGER.success("created '{}', with id: [{}]".format( self.__class__.__name__, self.id_)) except Exception as sifo_exception: LOGGER.exception(sifo_exception) raise sifo_exception
def end_process(cls): """ method for ending logging and profiling of process """ digits = 7 elapsed = round((time() - cls.start) * 1000, digits) speedup = round(cls.elapsed - elapsed, digits) cls.profiling.add_row(["-----------", "", "", ""]) cls.profiling.add_row(["total", "", "", str(elapsed) + "ms"]) cls.profiling.add_row(["", "", "", ""]) cls.profiling.add_row(["speedup", "", "", str(speedup) + "ms"]) cls.profiling.add_row([ "(total without speedup)", "", "", str(round(cls.elapsed, digits)) + "ms" ]) LOGGER.success("ending '{}'".format(cls.__name__)) LOGGER.info("reporting profiling results -> \n\n profiling: '{}' \n\n". format(cls.__name__) + str(cls.profiling) + "\n")
def create(self, db_name: str, col_name: str, document: (dict, list)): """ method for creating posts / documents (dict or list) into collection in database Parameters ---------- db_name : str db to insert record col_name : str collection to insert record document : dict, list record(s) to insert """ try: LOGGER.info( "trying to '{}' document(s) in collection: '{}' in db: '{}'". format(self.create.__name__, col_name, db_name)) Assertor.assert_data_types([db_name, col_name, document], [str, str, (dict, list)]) if not isinstance(document, (dict, list)): raise TypeError("expected type '{}', got '{}' " "instead".format( (dict.__name__, list.__name__), type(document).__name__)) count = len(document) if isinstance(document, list) else len( [document]) if not self._db: self._db = self._client[db_name.lower()] self._collection = self._db[col_name.lower()] else: self._collection = self._db[col_name.lower()] self._collection.insert(document) LOGGER.success( "'{}' successfully completed - '{}' document(s)".format( self.create.__name__, count)) except Exception as exp: LOGGER.exception(exp) raise exp