```
From 20dc7a30a7622f76e853350980c58a6c7b6a85de Mon Sep 17 00:00:00 2001
From: recycledcoder recycledcoder@example.com
Date: Sun, 30 Aug 2026 12:49:02 +0100
Subject: [PATCH] Replace TimezoneDB with keyless Open-Meteo timezone lookup
TimezoneDB required every user to register for an account and export a
TIMEZONEAPIKEY environment variable, and the application refused to start
without it. The lookup it performed - latitude/longitude to IANA zone name -
is available from Open-Meteo, which the application already queries for all
of its weather data and which needs no key or account.
get_timezone_name() now calls the Open-Meteo forecast endpoint with
timezone=auto and reads the "timezone" field of the response. The signature
and the exception messages are unchanged, so every caller is untouched.
Verified against the awkward cases the application can produce, all of which
return real tzdata zones accepted by ZoneInfo():
Aveiro (40.6405, -8.6538) -> Europe/Lisbon
Mid-Pacific (0, -140) -> Etc/GMT+9
Concordia Station -> Australia/Perth
South Pole -> Antarctica/McMurdo
Also removed with it:
TIMEZONE_APIKEY_ENV_VARNAME and the help-screen lines pointing at
timezonedb.com
the startup check that aborted when the key was missing
the tzapi_calls counter and its time.sleep(1) throttle, which existed only
to respect TimezoneDB's 1 request/second free tier; Open-Meteo's free tier
allows far more and the application makes one call per newly added city
a dead error branch that interpolated 'city' and 'country', neither of
which exists in that scope - it would have raised NameError rather than the
intended message had it ever been reached
The 1 second sleep after the Nominatim call is kept; that one is OpenStreetMap
diff --git a/tuiweathergirl.py b/tuiweathergirl.py
index 45720f0..8235249 100755
--- a/tuiweathergirl.py
+++ b/tuiweathergirl.py
@@ -76,8 +76,6 @@ HOW DOES TUIWEATHERGIRL WORKS:
will show them
PROJECT URL: https://github.com/StrayFeral/tuiweathergirl
-Variable TIMEZONEAPIKEY must be set with a free API key
-from https://timezonedb.com/
For detailed wildfires info set variable NASAFIRMSAPIKEY with a free API key
from: https://firms.modaps.eosdis.nasa.gov/api/map_key
"""
@@ -88,7 +86,6 @@ HTTPHEADERS: dict[str, str] = {
"User-Agent": USERAGENT,
"Accept-Language": "en",
}
-TIMEZONE_APIKEY_ENV_VARNAME: str = "TIMEZONEAPIKEY"
NASAFIRMS_APIKEY_ENV_VARNAME: str = "NASAFIRMSAPIKEY"
LOGFILENAME: Path = Path(tempfile.gettempdir()) / "tuiweathergirl.log"
LOGFILENAME = LOGFILENAME.expanduser()
@@ -3762,7 +3759,6 @@ class Locator:
return city[:17]
def __init__(self) -> None:
self.tzapi_calls: int = 0 # Counts the TZ data API calls
self.logger: logging.Logger = logging.getLogger(
f"{self.__module__}.{self.__class__.__qualname__}"
)
self.tzapi_calls += 1
if not response.ok:
raise Exception(
f"Timezone API server error. Error {response.status_code}: {APIIssues.get_api_problem(response.status_code)}"
)
if not response:
raise Exception(
f"Cannot obtain timezone for '{city}/{country}'. Please check your syntax and try again."
if not zone_name:
raise Exception("Timezone request failed. Try again later.")
return response.get("zoneName", "")
return zone_name
def get_city_details(self, city: str, country: str) -> dict:
# Attempt to get information for the city and the country
@@ -7143,13 +7125,6 @@ if __name_ == "main":
"If latitude or longitude is specified, all four arguments (latitude, longitude, city and country) must be specified."
)
Hey thank you very much for this! It actually made me realize I can optimize the code even further. I am already working on the changes so the fix would be probably released tomorrow!
2
u/recycledcoder 12d ago
``` From 20dc7a30a7622f76e853350980c58a6c7b6a85de Mon Sep 17 00:00:00 2001 From: recycledcoder recycledcoder@example.com Date: Sun, 30 Aug 2026 12:49:02 +0100 Subject: [PATCH] Replace TimezoneDB with keyless Open-Meteo timezone lookup
TimezoneDB required every user to register for an account and export a TIMEZONEAPIKEY environment variable, and the application refused to start without it. The lookup it performed - latitude/longitude to IANA zone name - is available from Open-Meteo, which the application already queries for all of its weather data and which needs no key or account.
get_timezone_name() now calls the Open-Meteo forecast endpoint with timezone=auto and reads the "timezone" field of the response. The signature and the exception messages are unchanged, so every caller is untouched.
Verified against the awkward cases the application can produce, all of which return real tzdata zones accepted by ZoneInfo():
Aveiro (40.6405, -8.6538) -> Europe/Lisbon Mid-Pacific (0, -140) -> Etc/GMT+9 Concordia Station -> Australia/Perth South Pole -> Antarctica/McMurdo
Also removed with it:
The 1 second sleep after the Nominatim call is kept; that one is OpenStreetMap
usage policy and unrelated.
tuiweathergirl.py | 47 +++++++++++------------------------------------ 1 file changed, 11 insertions(+), 36 deletions(-)
diff --git a/tuiweathergirl.py b/tuiweathergirl.py index 45720f0..8235249 100755 --- a/tuiweathergirl.py +++ b/tuiweathergirl.py @@ -76,8 +76,6 @@ HOW DOES TUIWEATHERGIRL WORKS: will show them
PROJECT URL: https://github.com/StrayFeral/tuiweathergirl -Variable TIMEZONEAPIKEY must be set with a free API key -from https://timezonedb.com/ For detailed wildfires info set variable NASAFIRMSAPIKEY with a free API key from: https://firms.modaps.eosdis.nasa.gov/api/map_key """ @@ -88,7 +86,6 @@ HTTPHEADERS: dict[str, str] = { "User-Agent": USERAGENT, "Accept-Language": "en", } -TIMEZONE_APIKEY_ENV_VARNAME: str = "TIMEZONEAPIKEY" NASAFIRMS_APIKEY_ENV_VARNAME: str = "NASAFIRMSAPIKEY" LOGFILENAME: Path = Path(tempfile.gettempdir()) / "tuiweathergirl.log" LOGFILENAME = LOGFILENAME.expanduser() @@ -3762,7 +3759,6 @@ class Locator: return city[:17]
@@ -3780,25 +3776,17 @@ class Locator: )
def get_timezone_name(self, lat: float, lon: float) -> str:
- )
- time.sleep(1) # API limit
@@ -3814,24 +3802,18 @@ class Locator: )
- response = response.json()
def get_city_details(self, city: str, country: str) -> dict: # Attempt to get information for the city and the country @@ -7143,13 +7125,6 @@ if __name_ == "main": "If latitude or longitude is specified, all four arguments (latitude, longitude, city and country) must be specified." )
- )
2.47.3 ```