or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

channel-management.mddns-queries.mderror-handling.mdhost-resolution.mdindex.mdutilities.md
tile.json

tessl/pypi-pycares

Python interface for c-ares asynchronous DNS library

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/pycares@4.10.x

To install, run

npx @tessl/cli install tessl/pypi-pycares@4.10.0

index.mddocs/

pycares

A Python interface for c-ares, a C library that performs DNS requests and name resolutions asynchronously. pycares enables Python applications to perform non-blocking DNS queries including A, AAAA, MX, and other record types, making it ideal for high-performance networking applications that need to handle multiple concurrent DNS lookups without blocking execution.

Package Information

  • Package Name: pycares
  • Language: Python
  • Installation: pip install pycares

Core Imports

import pycares

For error handling:

import pycares.errno

For utilities:

from pycares import ascii_bytes, maybe_str, parse_name

Basic Usage

import pycares
import select

def wait_channel(channel):
    """Helper function to process channel events until completion."""
    while True:
        read_fds, write_fds = channel.getsock()
        if not read_fds and not write_fds:
            break
        timeout = channel.timeout()
        if not timeout:
            channel.process_fd(pycares.ARES_SOCKET_BAD, pycares.ARES_SOCKET_BAD)
            continue
        rlist, wlist, xlist = select.select(read_fds, write_fds, [], timeout)
        for fd in rlist:
            channel.process_fd(fd, pycares.ARES_SOCKET_BAD)
        for fd in wlist:
            channel.process_fd(pycares.ARES_SOCKET_BAD, fd)

def query_callback(result, error):
    """Callback function for DNS queries."""
    if error is not None:
        print(f'Error: ({error}) {pycares.errno.strerror(error)}')
    else:
        print(f'Result: {result}')

# Create a DNS resolution channel
channel = pycares.Channel()

# Perform a simple A record query
channel.query('google.com', pycares.QUERY_TYPE_A, query_callback)

# Process the query until completion
wait_channel(channel)

# Clean up
channel.close()

Architecture

pycares is built around the Channel class, which represents a DNS resolution context. The architecture supports both synchronous-style blocking operations (using helper functions like the wait_channel example above) and full asynchronous integration with event loops.

Key components:

  • Channel: The main DNS resolution engine that manages queries, servers, and I/O
  • Result classes: Structured objects containing parsed DNS response data for each record type
  • Callback system: Asynchronous completion notification via user-provided callback functions
  • Event loop integration: Socket-based I/O monitoring for integration with select, asyncio, and other event systems

Capabilities

Utility Functions

String encoding and domain name processing utilities for handling international domain names and proper ASCII encoding.

def ascii_bytes(data): ...
def maybe_str(data): ...
def parse_name(name): ...

Utilities

DNS Channel Management

Core functionality for creating and configuring DNS resolution channels, including server configuration, timeout settings, and I/O event processing.

class Channel:
    def __init__(
        self,
        flags=None,
        timeout=None,
        tries=None,
        ndots=None,
        tcp_port=None,
        udp_port=None,
        servers=None,
        domains=None,
        lookups=None,
        sock_state_cb=None,
        socket_send_buffer_size=None,
        socket_receive_buffer_size=None,
        rotate=False,
        local_ip=None,
        local_dev=None,
        resolvconf_path=None,
        event_thread=False
    ): ...
    
    def getsock(self): ...
    def timeout(self, t=None): ...
    def process_fd(self, read_fd, write_fd): ...
    def close(self): ...

Channel Management

DNS Queries

DNS query operations for all major record types including A, AAAA, MX, TXT, SOA, SRV, and others. Supports both direct queries and search-based queries using configured search domains.

def query(self, name, query_type, callback, query_class=None): ...
def search(self, name, query_type, callback, query_class=None): ...

DNS Queries

Host Resolution

Traditional host resolution functions similar to standard library socket functions but with asynchronous callback-based operation.

def gethostbyname(self, name, family, callback): ...
def gethostbyaddr(self, addr, callback): ...
def getaddrinfo(self, host, port, callback, family=0, type=0, proto=0, flags=0): ...
def getnameinfo(self, address, flags, callback): ...

Host Resolution

Error Handling and Constants

Comprehensive error code definitions and utility functions for handling DNS resolution errors and failures.

# Error constants available in pycares.errno
ARES_SUCCESS: int
ARES_ENOTFOUND: int
ARES_ETIMEOUT: int
# ... additional error codes

def strerror(code: int) -> str: ...

Error Handling

Command Line Interface

pycares includes a command-line interface for performing DNS queries similar to the dig command:

# Usage: python -m pycares [query_type] hostname

# Perform A record lookup (default)
python -m pycares google.com

# Perform specific record type lookup
python -m pycares mx google.com
python -m pycares txt google.com
python -m pycares aaaa google.com
python -m pycares ns google.com

The CLI outputs results in dig-like format with question and answer sections, including TTL values and properly formatted record data.

Thread Safety

pycares supports thread-safe operation when the underlying c-ares library is compiled with thread safety. Check thread safety support:

def ares_threadsafety() -> bool: ...

Version Information

__version__: str  # Package version string

Constants and Types

# Type aliases
IP4 = tuple[str, int]
IP6 = tuple[str, int, int, int]

# Query types
QUERY_TYPE_A: int
QUERY_TYPE_AAAA: int
QUERY_TYPE_MX: int
QUERY_TYPE_TXT: int
QUERY_TYPE_SOA: int
QUERY_TYPE_SRV: int
QUERY_TYPE_NS: int
QUERY_TYPE_PTR: int
QUERY_TYPE_CNAME: int
QUERY_TYPE_CAA: int
QUERY_TYPE_NAPTR: int
QUERY_TYPE_ANY: int

# Channel flags
ARES_FLAG_USEVC: int
ARES_FLAG_PRIMARY: int
ARES_FLAG_IGNTC: int
ARES_FLAG_NORECURSE: int
ARES_FLAG_STAYOPEN: int
ARES_FLAG_NOSEARCH: int
ARES_FLAG_NOALIASES: int
ARES_FLAG_NOCHECKRESP: int
ARES_FLAG_EDNS: int
ARES_FLAG_NO_DFLT_SVR: int

# Name info flags
ARES_NI_NOFQDN: int
ARES_NI_NUMERICHOST: int
ARES_NI_NAMEREQD: int
ARES_NI_NUMERICSERV: int
ARES_NI_DGRAM: int
ARES_NI_TCP: int
ARES_NI_UDP: int
ARES_NI_SCTP: int
ARES_NI_DCCP: int
ARES_NI_NUMERICSCOPE: int
ARES_NI_LOOKUPHOST: int
ARES_NI_LOOKUPSERVICE: int
ARES_NI_IDN: int
ARES_NI_IDN_ALLOW_UNASSIGNED: int
ARES_NI_IDN_USE_STD3_ASCII_RULES: int

# Query classes
QUERY_CLASS_IN: int
QUERY_CLASS_CHAOS: int
QUERY_CLASS_HS: int
QUERY_CLASS_NONE: int
QUERY_CLASS_ANY: int

# Other constants
ARES_SOCKET_BAD: int
ARES_VERSION: str