kerykeion.fetch_geonames
This is part of Kerykeion (C) 2024 Giacomo Battaglia
1# -*- coding: utf-8 -*- 2""" 3 This is part of Kerykeion (C) 2024 Giacomo Battaglia 4""" 5 6 7import logging 8from requests import Request 9from requests_cache import CachedSession 10from typing import Union 11 12 13class FetchGeonames: 14 """ 15 Class to handle requests to the GeoNames API 16 17 Args: 18 city_name (str): Name of the city 19 country_code (str): Two letters country code 20 username (str, optional): GeoNames username, defaults to "century.boy". 21 """ 22 23 def __init__( 24 self, 25 city_name: str, 26 country_code: str, 27 username: str = "century.boy", 28 ): 29 self.session = CachedSession( 30 cache_name="cache/kerykeion_geonames_cache", 31 backend="sqlite", 32 expire_after=86400, 33 ) 34 35 self.username = username 36 self.city_name = city_name 37 self.country_code = country_code 38 self.base_url = "http://api.geonames.org/searchJSON" 39 self.timezone_url = "http://api.geonames.org/timezoneJSON" 40 41 def __get_timezone(self, lat: Union[str, float, int], lon: Union[str, float, int]) -> dict[str, str]: 42 """ 43 Get the timezone for a given latitude and longitude 44 """ 45 # Dictionary that will be returned: 46 timezone_data = {} 47 48 params = {"lat": lat, "lng": lon, "username": self.username} 49 50 prepared_request = Request("GET", self.timezone_url, params=params).prepare() 51 logging.debug(f"Requesting data from GeoName timezones: {prepared_request.url}") 52 53 try: 54 response = self.session.send(prepared_request) 55 response_json = response.json() 56 57 except Exception as e: 58 logging.error(f"Error fetching {self.timezone_url}: {e}") 59 return {} 60 61 try: 62 timezone_data["timezonestr"] = response_json["timezoneId"] 63 64 except Exception as e: 65 logging.error(f"Error serializing data maybe wrong username? Details: {e}") 66 return {} 67 68 if hasattr(response, "from_cache"): 69 timezone_data["from_tz_cache"] = response.from_cache # type: ignore 70 71 return timezone_data 72 73 def __get_contry_data(self, city_name: str, country_code: str) -> dict[str, str]: 74 """ 75 Get the city data *whitout timezone* for a given city and country name 76 """ 77 # Dictionary that will be returned: 78 city_data_whitout_tz = {} 79 80 params = { 81 "q": city_name, 82 "contry": country_code, 83 "username": self.username, 84 "maxRows": 1, 85 "style": "SHORT", 86 "featureClass": "A", 87 "featureClass": "P", 88 } 89 90 prepared_request = Request("GET", self.base_url, params=params).prepare() 91 logging.debug(f"Requesting data from geonames basic: {prepared_request.url}") 92 93 try: 94 response = self.session.send(prepared_request) 95 response_json = response.json() 96 logging.debug(f"Response from GeoNames: {response_json}") 97 98 except Exception as e: 99 logging.error(f"Error in fetching {self.base_url}: {e}") 100 return {} 101 102 try: 103 city_data_whitout_tz["name"] = response_json["geonames"][0]["name"] 104 city_data_whitout_tz["lat"] = response_json["geonames"][0]["lat"] 105 city_data_whitout_tz["lng"] = response_json["geonames"][0]["lng"] 106 city_data_whitout_tz["countryCode"] = response_json["geonames"][0]["countryCode"] 107 108 except Exception as e: 109 logging.error(f"Error serializing data maybe wrong username? Details: {e}") 110 return {} 111 112 if hasattr(response, "from_cache"): 113 city_data_whitout_tz["from_country_cache"] = response.from_cache # type: ignore 114 115 return city_data_whitout_tz 116 117 def get_serialized_data(self) -> dict[str, str]: 118 """ 119 Returns all the data necessary for the Kerykeion calculation. 120 121 Returns: 122 dict[str, str]: _description_ 123 """ 124 city_data_response = self.__get_contry_data(self.city_name, self.country_code) 125 try: 126 timezone_response = self.__get_timezone(city_data_response["lat"], city_data_response["lng"]) 127 128 except Exception as e: 129 logging.error(f"Error in fetching timezone: {e}") 130 return {} 131 132 return {**timezone_response, **city_data_response} 133 134 135if __name__ == "__main__": 136 from kerykeion.utilities import setup_logging 137 setup_logging(level="debug") 138 139 geonames = FetchGeonames("Montichiari", "IT") 140 print(geonames.get_serialized_data())
class
FetchGeonames:
14class FetchGeonames: 15 """ 16 Class to handle requests to the GeoNames API 17 18 Args: 19 city_name (str): Name of the city 20 country_code (str): Two letters country code 21 username (str, optional): GeoNames username, defaults to "century.boy". 22 """ 23 24 def __init__( 25 self, 26 city_name: str, 27 country_code: str, 28 username: str = "century.boy", 29 ): 30 self.session = CachedSession( 31 cache_name="cache/kerykeion_geonames_cache", 32 backend="sqlite", 33 expire_after=86400, 34 ) 35 36 self.username = username 37 self.city_name = city_name 38 self.country_code = country_code 39 self.base_url = "http://api.geonames.org/searchJSON" 40 self.timezone_url = "http://api.geonames.org/timezoneJSON" 41 42 def __get_timezone(self, lat: Union[str, float, int], lon: Union[str, float, int]) -> dict[str, str]: 43 """ 44 Get the timezone for a given latitude and longitude 45 """ 46 # Dictionary that will be returned: 47 timezone_data = {} 48 49 params = {"lat": lat, "lng": lon, "username": self.username} 50 51 prepared_request = Request("GET", self.timezone_url, params=params).prepare() 52 logging.debug(f"Requesting data from GeoName timezones: {prepared_request.url}") 53 54 try: 55 response = self.session.send(prepared_request) 56 response_json = response.json() 57 58 except Exception as e: 59 logging.error(f"Error fetching {self.timezone_url}: {e}") 60 return {} 61 62 try: 63 timezone_data["timezonestr"] = response_json["timezoneId"] 64 65 except Exception as e: 66 logging.error(f"Error serializing data maybe wrong username? Details: {e}") 67 return {} 68 69 if hasattr(response, "from_cache"): 70 timezone_data["from_tz_cache"] = response.from_cache # type: ignore 71 72 return timezone_data 73 74 def __get_contry_data(self, city_name: str, country_code: str) -> dict[str, str]: 75 """ 76 Get the city data *whitout timezone* for a given city and country name 77 """ 78 # Dictionary that will be returned: 79 city_data_whitout_tz = {} 80 81 params = { 82 "q": city_name, 83 "contry": country_code, 84 "username": self.username, 85 "maxRows": 1, 86 "style": "SHORT", 87 "featureClass": "A", 88 "featureClass": "P", 89 } 90 91 prepared_request = Request("GET", self.base_url, params=params).prepare() 92 logging.debug(f"Requesting data from geonames basic: {prepared_request.url}") 93 94 try: 95 response = self.session.send(prepared_request) 96 response_json = response.json() 97 logging.debug(f"Response from GeoNames: {response_json}") 98 99 except Exception as e: 100 logging.error(f"Error in fetching {self.base_url}: {e}") 101 return {} 102 103 try: 104 city_data_whitout_tz["name"] = response_json["geonames"][0]["name"] 105 city_data_whitout_tz["lat"] = response_json["geonames"][0]["lat"] 106 city_data_whitout_tz["lng"] = response_json["geonames"][0]["lng"] 107 city_data_whitout_tz["countryCode"] = response_json["geonames"][0]["countryCode"] 108 109 except Exception as e: 110 logging.error(f"Error serializing data maybe wrong username? Details: {e}") 111 return {} 112 113 if hasattr(response, "from_cache"): 114 city_data_whitout_tz["from_country_cache"] = response.from_cache # type: ignore 115 116 return city_data_whitout_tz 117 118 def get_serialized_data(self) -> dict[str, str]: 119 """ 120 Returns all the data necessary for the Kerykeion calculation. 121 122 Returns: 123 dict[str, str]: _description_ 124 """ 125 city_data_response = self.__get_contry_data(self.city_name, self.country_code) 126 try: 127 timezone_response = self.__get_timezone(city_data_response["lat"], city_data_response["lng"]) 128 129 except Exception as e: 130 logging.error(f"Error in fetching timezone: {e}") 131 return {} 132 133 return {**timezone_response, **city_data_response}
Class to handle requests to the GeoNames API
Args: city_name (str): Name of the city country_code (str): Two letters country code username (str, optional): GeoNames username, defaults to "century.boy".
FetchGeonames(city_name: str, country_code: str, username: str = 'century.boy')
24 def __init__( 25 self, 26 city_name: str, 27 country_code: str, 28 username: str = "century.boy", 29 ): 30 self.session = CachedSession( 31 cache_name="cache/kerykeion_geonames_cache", 32 backend="sqlite", 33 expire_after=86400, 34 ) 35 36 self.username = username 37 self.city_name = city_name 38 self.country_code = country_code 39 self.base_url = "http://api.geonames.org/searchJSON" 40 self.timezone_url = "http://api.geonames.org/timezoneJSON"
def
get_serialized_data(self) -> dict[str, str]:
118 def get_serialized_data(self) -> dict[str, str]: 119 """ 120 Returns all the data necessary for the Kerykeion calculation. 121 122 Returns: 123 dict[str, str]: _description_ 124 """ 125 city_data_response = self.__get_contry_data(self.city_name, self.country_code) 126 try: 127 timezone_response = self.__get_timezone(city_data_response["lat"], city_data_response["lng"]) 128 129 except Exception as e: 130 logging.error(f"Error in fetching timezone: {e}") 131 return {} 132 133 return {**timezone_response, **city_data_response}
Returns all the data necessary for the Kerykeion calculation.
Returns: dict[str, str]: _description_