Skip to main content

A Python package for fetching UTC time from multiple time servers with fallback logic. Features free servers.

Project description

Timely Timed

A robust Python package for fetching UTC time from multiple time servers with automatic fallback logic and extensive customization options.

Installation

pip install timely-timed

Features

  • Zero External Dependencies - Uses only built-in Python modules (urllib, json, datetime)
  • Multiple Time Server Support - Automatic fallback across multiple servers
  • Extensible Architecture - Add custom servers and strategies easily
  • Smart Server Management - Exclude, add, or remove servers at will
  • Strategy Pattern - Different server types handled by dedicated strategies
  • Comprehensive Error Handling - Detailed error messages when servers fail
  • Type Hints - Full type annotations for better IDE support
  • Logging Integration - Built-in logging for debugging

Quick Start

Basic Usage

from timely_timed import get_utc_time

# Get current UTC time from time servers
utc_time = get_utc_time()
print(utc_time)  # datetime object representing current UTC time

Exclude Default Servers

from timely_timed import get_utc_time

# Exclude specific default servers (supports partial matching)
utc_time = get_utc_time(excluded_servers=["worldclockapi"])

# Exclude multiple servers
utc_time = get_utc_time(excluded_servers=["worldclockapi", "aisenseapi"])

Using Custom Time Servers

from timely_timed import get_utc_time, TimeServerClient

# Method 1: Using the convenience function
custom_servers = ["https://your-custom-server.com/time"]
utc_time = get_utc_time(custom_servers=custom_servers)

# Method 2: Using the client class
client = TimeServerClient(custom_servers=["https://your-custom-server.com/time"])
utc_time = client.get_utc_time()

# Method 3: Only use custom servers (no defaults)
client = TimeServerClient(
    custom_servers=["https://your-server.com/time"],
    use_default_servers=False
)
utc_time = client.get_utc_time()

Advanced Usage

Dynamic Server Management

from timely_timed import TimeServerClient

client = TimeServerClient()

# Add a server with highest priority
client.add_server("https://priority-server.com/time", priority=True)

# Add a server with lowest priority
client.add_server("https://backup-server.com/time", priority=False)

# Remove servers by pattern (supports partial matching)
removed_count = client.remove_server("worldclockapi")
print(f"Removed {removed_count} server(s)")

# Remove by exact URL
client.remove_server("http://worldclockapi.com/api/json/utc/now")

utc_time = client.get_utc_time()

Initialization Options

from timely_timed import TimeServerClient

# Initialize with custom servers and exclusions
client = TimeServerClient(
    custom_servers=["https://my-server.com/time"],
    excluded_servers=["worldclockapi", "aisenseapi"],
    use_default_servers=True  # Still use remaining defaults
)

# Initialize with only custom servers
client = TimeServerClient(
    custom_servers=["https://my-server.com/time"],
    use_default_servers=False  # Disable all defaults
)

Sending POST Body Data

from timely_timed import get_utc_time

# If required by server, include additional data in the POST request
data = {"user": "example", "request_id": "12345"}
utc_time = get_utc_time(body=data)
print(utc_time)

Error Handling

from timely_timed import get_utc_time, AllServersFailedError

try:
    utc_time = get_utc_time()
    print(f"Current UTC time: {utc_time}")
except AllServersFailedError as e:
    print(f"Failed to fetch time: {e}")
    # Error message includes details about which servers failed and why

Logging Integration

import logging
from timely_timed import TimeServerClient

# Enable logging to see which servers are being tried
logging.basicConfig(level=logging.DEBUG)

client = TimeServerClient()
utc_time = client.get_utc_time()
# Logs will show: "Successfully fetched time from https://..."

Default Time Servers

The package includes three default servers, AiSenseAPI, my self-hosted server (powered by Cloudflare Workers), and WorldClockAPI.

All default servers are free, public APIs requiring no authentication.

Custom Time Server Integration

Supported Server Formats

The package automatically handles different server types:

POST-Based Servers (JSON)

Expected request: POST with optional JSON body

{
  "success": true,
  "result": {
    "utcTime": "2025-12-08T17:05:02.279Z"
  }
}

AiSenseAPI Format (GET)

Expected request: GET

{
  "datetime": "2025-12-08T17:05:02+00:00"
}

WorldClockAPI Format (GET)

Expected request: GET

{
  "currentDateTime": "2025-12-08T17:05:02Z"
}

Adding Custom Server Strategies

For servers with custom formats, extend the TimeServerStrategy class:

from timely_timed import TimeServerClient, TimeServerStrategy
from datetime import datetime
from urllib.request import Request, urlopen
import json

class MyCustomStrategy(TimeServerStrategy):
    def matches(self, url: str) -> bool:
        return "my-custom-server.com" in url
    
    def fetch_time(self, url: str, body=None) -> datetime:
        req = Request(url, method="GET")
        with urlopen(req, timeout=5) as response:
            data = json.loads(response.read().decode("utf-8"))
            time_str = data["timestamp"]  # Your custom field
            return datetime.fromisoformat(time_str)

# Use the custom strategy
client = TimeServerClient(
    custom_servers=["https://my-custom-server.com/api/time"],
    custom_strategies=[MyCustomStrategy()]
)
utc_time = client.get_utc_time()

API Reference

get_utc_time(body=None, custom_servers=None, excluded_servers=None)

Convenience function to fetch UTC time.

Parameters:

  • body (dict, optional): JSON data to send in POST requests
  • custom_servers (list, optional): Custom server URLs (highest priority)
  • excluded_servers (list, optional): Server patterns to exclude from defaults

Returns: datetime object

Raises: AllServersFailedError if all servers fail

TimeServerClient

Main client class for advanced usage.

Constructor Parameters:

  • custom_servers (list, optional): Custom server URLs
  • custom_strategies (list, optional): Custom strategy instances
  • use_default_servers (bool): Whether to include default servers (default: True)
  • excluded_servers (list, optional): Server patterns to exclude

Methods:

  • get_utc_time(body=None) - Fetch UTC time with fallback logic
  • add_server(server_url, priority=True) - Add a server dynamically
  • remove_server(server_pattern) - Remove servers matching pattern
  • add_strategy(strategy, priority=True) - Add a custom strategy

TimeServerStrategy (Abstract Base Class)

Base class for implementing custom server handlers.

Methods to Implement:

  • matches(url) - Return True if this strategy handles the URL
  • fetch_time(url, body=None) - Fetch and return datetime from the server

Exception Classes

  • TimeServerError - Base exception for time server errors
  • AllServersFailedError - Raised when all configured servers fail

Contributing

Contributions are welcome! Please follow these steps:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes with proper documentation
  4. Add tests if applicable
  5. Ensure code follows the existing style
  6. Submit a pull request

Development Setup

git clone https://github.com/yourusername/timely-timed.git
cd timely-timed
pip install -e .

License

MIT License - See LICENSE file for details

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

timely_timed-0.3.0.tar.gz (8.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

timely_timed-0.3.0-py3-none-any.whl (7.7 kB view details)

Uploaded Python 3

File details

Details for the file timely_timed-0.3.0.tar.gz.

File metadata

  • Download URL: timely_timed-0.3.0.tar.gz
  • Upload date:
  • Size: 8.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.1

File hashes

Hashes for timely_timed-0.3.0.tar.gz
Algorithm Hash digest
SHA256 7052b5e2b201af15a07f9011ab29ac3a7a697c9e5020d9c075545adf6b1c11e3
MD5 886b9ead6e24f83524d97e3c988830c7
BLAKE2b-256 a6a5956673ad53c3c2fa54c3858e2442064630ee43dcc8496002292857703e12

See more details on using hashes here.

File details

Details for the file timely_timed-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: timely_timed-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 7.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.1

File hashes

Hashes for timely_timed-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0afd0ac4bb8a33ee37c203c4d26b93c6e3b42bfa5be235abe85451221b6f5e47
MD5 4064b759eae8631a5c07deec4ad2fdbb
BLAKE2b-256 197f971fc4d6df5da839321609c4e205911adb429ba09e3f4dc110c275d86e75

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page