rdnsresolver - Retrying DNS Resolver Package.
Project description
rdnsresolver Package Documentation
Overview
The rdnsresolver package provides synchronous and asynchronous DNS resolution wrappers based on dnspython. It implements automatic exponential backoff retry mechanisms utilizing tenacity for transient network failures, timeouts, and nameserver unreachability.
Class: RetryingResolver
__init__
__init__(resolver: Optional[dns.resolver.Resolver] = None, **kwargs: Any) -> None
This method initializes a synchronous DNS resolver instance with integrated retry logic.
It accepts an optional custom resolver instance, max_attempts (integer, default 5), backoff_factor (float, default 1.5), and initial_delay (float, default 1.0).
It instantiates and returns the configured RetryingResolver object.
It raises a TypeError if unsupported keyword arguments are supplied during initialization.
If no custom resolver is provided, it falls back to the global dns.resolver module functions, which share the system's underlying default DNS configuration.
resolve
resolve(qname: Union[str, dns.name.Name], rdtype: Union[int, str] = dns.rdatatype.A, **kwargs: Any) -> dns.resolver.Answer
This method executes a synchronous DNS query applying an exponential backoff strategy for transient network failures.
It requires the target qname (string or dns.name.Name), an optional rdtype (integer or string, default A), and accepts optional kwargs representing standard dnspython query parameters or temporary retry configuration overrides.
It returns a dns.resolver.Answer object containing the query results upon successful resolution.
It propagates permanent dnspython errors such as NXDOMAIN or NoAnswer immediately, and raises dns.exception.Timeout or dns.resolver.NoNameservers only after all retry attempts are exhausted.
Providing override retry parameters via kwargs modifies the behavior strictly for that specific query execution, leaving the instance's base configuration unmodified for subsequent calls.
resolve_ptr
resolve_ptr(ip_address: str, **kwargs: Any) -> dns.resolver.Answer
This method constructs a reverse DNS name from an IP address and executes a synchronous PTR record query with retry logic.
It requires the target ip_address (string) and accepts optional kwargs for standard query parameters or temporary retry overrides.
It returns a dns.resolver.Answer object containing the reverse resolution records.
It propagates permanent errors like NXDOMAIN immediately, while raising timeout or nameserver unavailability exceptions only after the retry limit is reached.
Invalid IP address strings passed to this method will immediately trigger a dns.exception.SyntaxError from the underlying reverse name constructor before any network requests are initiated.
Class: AsyncRetryingResolver
__init__
__init__(resolver: Optional[dns.asyncresolver.Resolver] = None, **kwargs: Any) -> None
This method initializes an asynchronous DNS resolver instance with integrated retry logic for non-blocking operations.
It accepts an optional custom dns.asyncresolver.Resolver instance, max_attempts (integer, default 5), backoff_factor (float, default 1.5), and initial_delay (float, default 1.0).
It instantiates and returns the configured AsyncRetryingResolver object.
It raises a TypeError if unsupported keyword arguments are supplied to the underlying constructor.
Instantiating this class outside of an active asynchronous event loop is permitted, provided that the underlying custom resolver, if supplied, does not tightly bind to an active loop during its own initialization.
resolve
async resolve(qname: Union[str, dns.name.Name], rdtype: Union[int, str] = dns.rdatatype.A, **kwargs: Any) -> dns.resolver.Answer
This method executes an asynchronous DNS query using the specified name and record type, applying the configured exponential backoff strategy for transient network exceptions.
It requires the target qname (string or dns.name.Name), an optional rdtype (integer or string, default A), and accepts optional kwargs representing standard asynchronous query parameters or temporary retry overrides.
It asynchronously yields a dns.resolver.Answer object representing the final server reply upon successful execution.
It propagates permanent dnspython errors like NXDOMAIN or NoAnswer instantly without retrying, and raises transient errors like dns.exception.Timeout or dns.resolver.NoNameservers only if the maximum retry limit is breached.
Executing this method requires an active event loop; attempting to run it synchronously or across mismatched event loops will result in an asyncio RuntimeError.
resolve_ptr
async resolve_ptr(ip_address: str, **kwargs: Any) -> dns.resolver.Answer
This method constructs a reverse DNS name from the provided IP address and executes an asynchronous PTR record query with retry logic.
It requires the target ip_address (string) and accepts optional kwargs for standard query parameters or temporary retry configuration overrides.
It asynchronously yields a dns.resolver.Answer object containing the requested reverse pointer records.
It propagates permanent errors instantly without retrying, raising timeout or nameserver unavailability exceptions solely after the maximum retry attempts are depleted.
Processing large batches of IP addresses concurrently with this method should be rate-limited by the calling application to prevent localized socket exhaustion or upstream DNS rate-limiting responses.
Global Functions
resolve
resolve(qname: Union[str, dns.name.Name], rdtype: Union[int, str] = dns.rdatatype.A, **kwargs: Any) -> dns.resolver.Answer
This function executes a synchronous DNS request utilizing a globally maintained RetryingResolver singleton instance.
It requires the target qname (string or dns.name.Name), an optional rdtype (integer or string, default A), and accepts optional kwargs for request parameters or retry configuration overrides.
It returns the dns.resolver.Answer object generated by the global singleton session.
It propagates permanent dnspython errors instantly and raises transient errors like dns.exception.Timeout or dns.resolver.NoNameservers only after all retry attempts are exhausted.
The global singleton defaults to the system's DNS configuration; if the environment dictates custom nameservers, developers must either modify the global dns.resolver.default_resolver or instantiate a dedicated RetryingResolver instead of using this function.
aresolve
async aresolve(qname: Union[str, dns.name.Name], rdtype: Union[int, str] = dns.rdatatype.A, **kwargs: Any) -> dns.resolver.Answer
This function executes an asynchronous DNS request utilizing a globally maintained AsyncRetryingResolver singleton instance.
It requires the target qname (string or dns.name.Name), an optional rdtype (integer or string, default A), and accepts optional kwargs for request parameters or retry configuration overrides.
It asynchronously yields the dns.resolver.Answer object generated by the global asynchronous singleton session.
It propagates permanent errors immediately and raises transient errors only after exhausting the configured retry limit.
The global asynchronous instance delegates to the dns.asyncresolver module; invoking this function from a distinctly different thread or a newly created event loop will trigger cross-loop execution exceptions if the underlying UDP sockets were bound elsewhere.
resolve_ptr
resolve_ptr(ip_address: str, **kwargs: Any) -> dns.resolver.Answer
This function performs a synchronous reverse DNS lookup utilizing the global RetryingResolver singleton instance.
It requires the target ip_address (string) and accepts optional kwargs for request parameters or retry configuration overrides.
It returns the dns.resolver.Answer object generated by the global singleton session.
It propagates permanent errors immediately and raises transient errors only after exhausting the configured retry limit.
Supplying non-standard IP representations may trigger parsing errors in the dns.reversename module before the global resolver instance is invoked.
aresolve_ptr
async aresolve_ptr(ip_address: str, **kwargs: Any) -> dns.resolver.Answer
This function performs an asynchronous reverse DNS lookup utilizing the global AsyncRetryingResolver singleton instance.
It requires the target ip_address (string) and accepts optional kwargs for request parameters or retry configuration overrides.
It asynchronously yields the dns.resolver.Answer object generated by the global asynchronous singleton session.
It propagates permanent errors immediately and raises transient errors only after exhausting the configured retry limit.
Similar to the synchronous variant, invalid input strings will bypass the retry mechanism entirely by failing during the local address parsing phase.
Migration Guide
Import Replacement
Projects utilizing direct dnspython implementations typically import dns.resolver and dns.asyncresolver. Migrating to this package requires importing the equivalent global functions from rdnsresolver.
The application must replace operational calls to dns.resolver and dns.asyncresolver by adding from rdnsresolver import resolve, aresolve, resolve_ptr, aresolve_ptr.
Imports for supporting modules such as dns.name, dns.rdatatype, and dns.exception remain necessary within the codebase for constructing strict query types and handling specific error structures.
Synchronous Query Migration
Existing synchronous codebase patterns execute queries using direct invocations like dns.resolver.resolve(qname, rdatatype).
The migration involves substituting dns.resolver.resolve with the resolve function.
For example, the invocation dns.resolver.resolve(current, dns.rdatatype.DS) becomes resolve(current, dns.rdatatype.DS).
The return signatures remain identical; the application will continue to receive a dns.resolver.Answer object, ensuring that downstream data processing logic requires zero modifications.
Asynchronous Query Migration
Asynchronous implementations currently rely on statements like await dns.asyncresolver.resolve(qname, rdatatype).
The migration requires replacing dns.asyncresolver.resolve with the aresolve function.
For example, the statement await dns.asyncresolver.resolve(current, dns.rdatatype.SOA) translates directly to await aresolve(current, dns.rdatatype.SOA).
The internal event loop interactions remain unchanged, but the overall execution time of the awaited function will increase dynamically if transient failures trigger the exponential backoff mechanism.
Reverse DNS (PTR) Simplification
Standard dnspython reverse lookups require a two-step process: converting the IP address string using dns.reversename.from_address(ip) and subsequently querying the resulting dns.name.Name object for a PTR record.
The rdnsresolver package provides dedicated helper functions to abstract this conversion phase and integrate the retry logic simultaneously.
A legacy code block containing rev_name = dns.reversename.from_address(ip) followed by answers = dns.resolver.resolve(rev_name, 'PTR') is replaced entirely by the single call answers = resolve_ptr(ip).
Similarly, the asynchronous equivalent answers = await dns.asyncresolver.resolve(rev_name, 'PTR') is consolidated into answers = await aresolve_ptr(ip).
Exception Handling Adjustments
Applications migrating to this package must account for changes in exception timing resulting from the introduced retry behavior.
Existing try...except blocks configured to catch dns.exception.Timeout or dns.resolver.NoNameservers will continue to function correctly.
However, these exceptions will no longer be raised immediately upon the first network failure; they will surface only after the maximum configured retry limit is exceeded.
Developers must evaluate overarching application timeouts to ensure that the cumulative delay introduced by the backoff multiplier does not violate strict internal performance boundaries or trigger secondary timeouts in higher-level services.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rdnsresolver-0.1.0.tar.gz.
File metadata
- Download URL: rdnsresolver-0.1.0.tar.gz
- Upload date:
- Size: 8.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
67ab8167d368496e2faea8f21340c486d0026a0a8044b56757dc347f82938644
|
|
| MD5 |
240e65524cd95eee4aa4fd8e47b51760
|
|
| BLAKE2b-256 |
8039ad32dcb665b033f3be1988a165d1e30890ebe9b7e22257f7e3663410b528
|
File details
Details for the file rdnsresolver-0.1.0-py3-none-any.whl.
File metadata
- Download URL: rdnsresolver-0.1.0-py3-none-any.whl
- Upload date:
- Size: 8.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0e2916b94271e4602269ab62d077c080458e1d006e1e475c9b26d821427a3212
|
|
| MD5 |
0ba272ce089f0fddeb3f273c1d9e5863
|
|
| BLAKE2b-256 |
85c9d3bdbe350c77d76609e554d424be818e5f3347d5e2bc43dd1d0ec735804f
|