Py3DNS - Python 3 DNS library
Py3DNS is a Python 3 library for making DNS queries and parsing responses. It provides a flexible API for various record types (A, AAAA, MX, NS, SOA, etc.) and is a port of the older `pydns` library, specifically adapted for Python 3. The current version is 4.0.2, with updates primarily focusing on Python compatibility, bug fixes, and feature enhancements like `asyncio` support.
Common errors
-
ModuleNotFoundError: No module named 'DNS'
cause This error typically occurs if `py3dns` is not installed, or if an attempt was made to install the Python 2-only `pydns` package instead.fixVerify that `py3dns` is installed in your active environment by running `pip install py3dns`. Ensure your Python interpreter matches the environment where `py3dns` is installed. -
DNSError: No name servers specified
cause The library could not find or was not explicitly provided with any DNS name server addresses to send queries to, often because `DNS.DiscoverNameServers()` was not called or failed.fixBefore making any `DNS.Request`, ensure name servers are set up by calling `DNS.DiscoverNameServers()`, `DNS.ParseResolvConf()`, or by manually setting `DNS.defaults['server'] = ['IP_ADDRESS_1', 'IP_ADDRESS_2']`. -
socket.timeout: timed out
cause A DNS query took longer than the default or configured timeout period, often due to network issues, an unresponsive DNS server, or a very slow connection.fixIncrease the timeout value by setting `DNS.defaults['timeout'] = X` (where `X` is the timeout in seconds) before making the request. Also, check your network connectivity and the availability of your configured DNS servers.
Warnings
- breaking Direct migration from Python 2's 'pydns' to 'py3dns' is not straightforward, as 'py3dns' is a separate project with Python 3 specific adjustments. While the API is largely compatible, code will require Python 3 syntax and 'py3dns' installation.
- gotcha DNS queries will fail with a 'No name servers specified' error if name servers are not explicitly configured or automatically discovered before making requests.
- gotcha Synchronous DNS requests (e.g., `DNS.Request.req()`) are blocking and can lead to performance bottlenecks or frozen applications in concurrent or I/O-bound environments.
Install
-
pip install py3dns
Imports
- DNS
from py3dns import DNS
import DNS
Quickstart
import DNS
import os
# Configure name servers, typically from system settings
# For testing, you can explicitly set them or rely on system discovery
# Example using Google's DNS for demonstration if system discovery fails or for specific testing
# DNS.defaults['server'] = ['8.8.8.8', '8.8.4.4']
# Discover name servers from /etc/resolv.conf or common system locations
DNS.DiscoverNameServers()
# Ensure name servers were found or set
if not DNS.defaults.get('server'):
print("Warning: No DNS name servers discovered. Queries might fail.")
print("Attempting to use public DNS servers as fallback.")
DNS.defaults['server'] = ['8.8.8.8', '8.8.4.4'] # Fallback to Google DNS
# Make an A record query for google.com
try:
req = DNS.Request(name='google.com', qtype='A')
response = req.req()
print(f"DNS Query for google.com (A records):\n")
if response.answers:
for answer in response.answers:
print(f" Name: {answer.name}, Type: {answer.qtype}, Data: {answer.data}, TTL: {answer.ttl}")
else:
print(" No A records found for google.com.")
# Example: MX record query
req_mx = DNS.Request(name='example.com', qtype='MX')
response_mx = req_mx.req()
print(f"\nDNS Query for example.com (MX records):\n")
if response_mx.answers:
for answer in response_mx.answers:
print(f" Name: {answer.name}, Type: {answer.qtype}, Priority: {answer.data[0]}, Exchange: {answer.data[1]}")
else:
print(" No MX records found for example.com.")
except DNS.DNSError as e:
print(f"DNS Error: {e}")
except Exception as e:
print(f"An unexpected error occurred: {e}")