aemetxfb.utils

Utility functions and configuration.

Utility functions for the aemetxfb package.

class aemetxfb.utils.AEMetConfig(http_timeout=10.0, download_timeout=60.0, cache_enabled=False, cache_ttl=3600, cache_dir='.aemet_cache')[source]

Bases: object

Centralized configuration for AEMet HTTP requests.

All timeout values are expressed in seconds. The defaults are chosen to be safe for the variety of endpoints the library calls:

  • http_timeout — small probe requests (finding the latest timestamp for radar images, checking HTTP status codes).

  • download_timeout — larger payloads (CSV, tar.gz, images).

Caching parameters control the optional disk-based response cache (see aemetxfb.cache). The cache is disabled by default so that existing code behaviour is unchanged.

  • cache_enabled — when True, decorated functions will read from / write to the SQLite cache store.

  • cache_ttl — time-to-live in seconds for cached entries. Climate data that changes rarely can safely use large values (e.g. 86400 for one day).

  • cache_dir — directory where the SQLite database file is stored.

The class is frozen so that a single shared instance can be safely imported by every module without risk of mutation.

Examples

>>> config = AEMetConfig()
>>> config.http_timeout
10.0
>>> config.download_timeout
60.0
>>> config.cache_enabled
False
Parameters:
  • http_timeout (float)

  • download_timeout (float)

  • cache_enabled (bool)

  • cache_ttl (int)

  • cache_dir (str)

http_timeout: float = 10.0
download_timeout: float = 60.0
cache_enabled: bool = False
cache_ttl: int = 3600
cache_dir: str = '.aemet_cache'
property urlretrieve_timeout: float

Alias kept for documentation purposes.

urlretrieve does not accept a timeout kwarg, so downloads that previously used it should be migrated to urlopen + read. This property simply returns download_timeout as a reminder.

aemetxfb.utils.set_config(config)[source]

Replace the module-level CONFIG singleton with a new configuration.

Because AEMetConfig is frozen (immutable), this function swaps the global reference so that all subsequent calls use the new timeouts. Modules that already imported CONFIG directly will still hold the old reference; the library’s own modules re-evaluate CONFIG at call time, so this works correctly for normal usage.

Parameters:

config (AEMetConfig) – The new configuration to use for all HTTP requests.

Return type:

None

Examples

Replace the global CONFIG with custom timeouts:

>>> from aemetxfb.utils import CONFIG, AEMetConfig, set_config
>>> original = CONFIG
>>> set_config(AEMetConfig(http_timeout=5.0, download_timeout=30.0))
>>> from aemetxfb.utils import CONFIG as NEW_CONFIG
>>> NEW_CONFIG.http_timeout
5.0
>>> set_config(original)  # restore
>>> from aemetxfb.utils import CONFIG as RESTORED
>>> RESTORED.http_timeout
10.0
aemetxfb.utils.decompress_file(file, output_path)[source]

Decompress a .tar.gz file to the specified output directory.

Parameters:
  • file (str | pathlib.Path) – Path to the .tar.gz file to decompress.

  • output_path (str | pathlib.Path) – Path to the directory where the contents will be extracted.

Raises:
Return type:

None

aemetxfb.utils.find_latest_timestamp(url_template, timestep, max_iterations, timestamp_format, check_method='http_status', radar_id=None)[source]

Find the latest available timestamp by checking data availability.

Iterates backwards in time from the current moment, checking for data availability at each timestamp until valid data is found or the iteration limit is exhausted.

Parameters:
  • url_template (str) – URL template with {timestamp} placeholder and optionally {radar}. Example: "https://example.com/{timestamp}.gif"

  • timestep (datetime.timedelta) – Time interval between consecutive timestamps to check.

  • max_iterations (int) – Maximum number of timestamps to check backwards.

  • timestamp_format (str) – strftime format string for timestamp formatting.

  • check_method (str, optional) –

    Method to verify data availability:

    • "http_status": Check if HTTP response status is 200

    • "json": Check if JSON response is non-empty (not "[]")

  • radar_id (str | None, optional) – Optional radar identifier to substitute in url_template.

Returns:

The latest timestamp with available data.

Return type:

datetime.datetime

Raises:

RuntimeError – If no available data is found within the iteration limit.

aemetxfb.utils.get_spanish_day_name(day_name)[source]

Convert an English day name to its Spanish equivalent.

Accepts day names in any case variation (Title, lower, UPPER) and returns the corresponding name in spanish.

Parameters:

day_name (str) – English day name (e.g., "Monday", "Tuesday").

Returns:

Spanish day name (e.g., "lunes", "martes").

Return type:

str

Raises:

ValueError – If the day name is not recognized.

Examples

>>> get_spanish_day_name("Monday")
'lunes'
>>> get_spanish_day_name("MONday")
'lunes'
>>> get_spanish_day_name("Friday")
'viernes'
>>> get_spanish_day_name("Sunday")
'domingo'
>>> get_spanish_day_name("Invalid")
Traceback (most recent call last):
    ...
ValueError: Unknown day name: Invalid
aemetxfb.utils.get_spanish_month_name(month_name)[source]

Convert a month name between English and Spanish.

Accepts month names in any case variation (Title, lower, UPPER) and returns the corresponding name in the opposite language.

Parameters:

month_name (str) – Month name in English (e.g., "January") or Spanish (e.g., "Enero", "enero", "ENERO").

Returns:

Month name in Spanish if input is English, or in English if input is Spanish. Spanish names have Title case (e.g., "Enero"), English names have Title case (e.g., "January").

Return type:

str

Raises:

ValueError – If the month name is not recognized.

Examples

English to Spanish:

>>> get_spanish_month_name("January")
'Enero'
>>> get_spanish_month_name("December")
'Diciembre'

Spanish to English (case-insensitive):

>>> get_spanish_month_name("Enero")
'January'
>>> get_spanish_month_name("enero")
'January'
>>> get_spanish_month_name("ENERO")
'January'

Invalid input raises ValueError:

>>> get_spanish_month_name("Jan")
Traceback (most recent call last):
    ...
ValueError: Unknown month name: Jan