From cde4b879c19fd5020f3d223608b14c713efbfa68 Mon Sep 17 00:00:00 2001 From: Thomas Oettli Date: Fri, 23 Jan 2026 23:07:25 +0100 Subject: [PATCH] Add missing docstrings and examples --- src/ddns_service/dns.py | 40 ++++++++++++++++++++++++++++++- src/ddns_service/models.py | 49 ++++++++++++++++++++++++-------------- 2 files changed, 70 insertions(+), 19 deletions(-) diff --git a/src/ddns_service/dns.py b/src/ddns_service/dns.py index 46d6cb9..b842826 100644 --- a/src/ddns_service/dns.py +++ b/src/ddns_service/dns.py @@ -37,6 +37,12 @@ def encode_dnsname(hostname): Raises: EncodingError: If hostname is invalid. + + Example: + >>> encode_dnsname("münchen") + 'xn--mnchen-3ya' + >>> encode_dnsname("example.com.") + 'example.com' """ hostname = hostname.lower().strip() @@ -84,6 +90,24 @@ def encode_dnsname(hostname): def detect_ip_type(ip): + """ + Detect IP address type and normalize. + + Args: + ip: IP address string. + + Returns: + Tuple of (record_type, normalized_ip). + + Raises: + ValueError: If IP address is invalid. + + Example: + >>> detect_ip_type("192.168.1.1") + ('A', '192.168.1.1') + >>> detect_ip_type("2001:db8::1") + ('AAAA', '2001:db8::1') + """ try: addr = ipaddress.ip_address(ip) if isinstance(addr, ipaddress.IPv4Address): @@ -127,6 +151,16 @@ def parse_bind_key_file(path): Raises: DNSError: If parsing fails. + + Example: + Key file contents:: + + key "ddns-key." { + algorithm hmac-sha256; + secret "base64secret=="; + }; + + >>> keyring, algo = parse_bind_key_file("/etc/bind/ddns.key") """ if not path: return None, None @@ -324,13 +358,17 @@ class DNSService: Update a DNS record for the given hostname. Args: - hostname: Fully qualified hostname. + hostname: Hostname (without zone suffix). zone: DNS zone name. ip: IP address to set. ttl: DNS record TTL. Raises: DNSError: If update fails. + + Example: + >>> dns_service.update_record("myhost", "example.com", "192.168.1.1", 60) + >>> dns_service.update_record("myhost", "example.com", "2001:db8::1", 60) """ try: record_type, normalized_ip = detect_ip_type(ip) diff --git a/src/ddns_service/models.py b/src/ddns_service/models.py index 724acf5..0aea2c8 100644 --- a/src/ddns_service/models.py +++ b/src/ddns_service/models.py @@ -19,6 +19,22 @@ from peewee import ( ) from playhouse.pool import PooledMySQLDatabase +# Re-export DoesNotExist and EncodingError for convenience +__all__ = [ + 'db', + 'DATABASE_VERSION', + 'User', + 'Hostname', + 'Version', + 'init_database', + 'create_tables', + 'get_user', + 'get_hostname', + 'get_hostname_for_user', + 'DoesNotExist', + 'EncodingError', +] + # Database proxy (initialized later with actual backend) db = DatabaseProxy() @@ -269,6 +285,11 @@ def get_user(username: str): Raises: DoesNotExist: If user not found. + + Example: + >>> user = get_user("alice") + >>> print(user.email) + 'alice@example.com' """ return User.get(User.username == username) @@ -286,6 +307,11 @@ def get_hostname(hostname, zone): Raises: DoesNotExist: If hostname not found. + + Example: + >>> host = get_hostname("myhost", "example.com") + >>> print(host.last_ipv4) + '192.168.1.1' """ return Hostname.get( (Hostname.hostname == hostname) & (Hostname.zone == zone) @@ -297,7 +323,7 @@ def get_hostname_for_user(hostname: str, user: User): Get hostname owned by specific user. Args: - hostname: Hostname to look up. + hostname: Hostname to look up (FQDN). user: User who should own the hostname. Returns: @@ -305,23 +331,10 @@ def get_hostname_for_user(hostname: str, user: User): Raises: DoesNotExist: If hostname not found or not owned by user. + + Example: + >>> user = get_user("alice") + >>> host = get_hostname_for_user("myhost.example.com", user) """ fqdn = fn.Concat(Hostname.hostname, '.', Hostname.zone) return Hostname.get((fqdn == hostname) & (Hostname.user == user)) - - -# Re-export DoesNotExist and EncodingError for convenience -__all__ = [ - 'db', - 'DATABASE_VERSION', - 'User', - 'Hostname', - 'Version', - 'init_database', - 'create_tables', - 'get_user', - 'get_hostname', - 'get_hostname_for_user', - 'DoesNotExist', - 'EncodingError', -]