{"library":"pycares","title":"Pycares: Asynchronous DNS Resolver","description":"Pycares is a Python module that provides an asynchronous interface to c-ares, a C library for performing DNS requests and name resolutions. It enables non-blocking DNS lookups, making it suitable for high-performance network applications. The library is actively maintained, currently at version 5.0.1, with regular releases addressing bug fixes and introducing new features.","status":"active","version":"5.0.1","language":"en","source_language":"en","source_url":"https://github.com/saghul/pycares","tags":["dns","async","networking","c-ares","resolver","low-level"],"install":[{"cmd":"pip install pycares","lang":"bash","label":"Install Pycares"},{"cmd":"pip install pycares[idna]","lang":"bash","label":"Install with IDNA 2008 support"}],"dependencies":[{"reason":"Required for the Python C interface; version 1.5.0 or higher is needed for Python < 3.14, and 2.0.0b1 or higher for Python >= 3.14.","package":"cffi","optional":false},{"reason":"Provides IDNA 2008 encoding support; otherwise, the built-in IDNA 2003 codec is used.","package":"idna","optional":true},{"reason":"The underlying C library for asynchronous DNS resolution. pycares bundles c-ares by default, but a system-wide c-ares can be used by setting PYCARES_USE_SYSTEM_LIB=1 during build.","package":"c-ares","optional":false},{"reason":"Required (version >= 3.5) to build pycares from source, as it's used to compile the bundled c-ares library.","package":"cmake","optional":false}],"imports":[{"symbol":"pycares","correct":"import pycares"}],"quickstart":{"code":"import pycares\nimport socket\n\ndef callback(result, error):\n    if error:\n        print(f\"Error: {error}\")\n        return\n    if result:\n        for record in result.answer:\n            if record.type == pycares.QUERY_TYPE_A:\n                print(f\"A record for {record.name}: {record.data.addr}\")\n            elif record.type == pycares.QUERY_TYPE_AAAA:\n                print(f\"AAAA record for {record.name}: {record.data.addr}\")\n            elif record.type == pycares.QUERY_TYPE_MX:\n                print(f\"MX record for {record.name}: priority={record.data.priority}, exchange={record.data.exchange}\")\n            # Add other record types as needed\n    else:\n        print(\"No records found.\")\n\n\n# Using a simple select-based event loop\nchannel = pycares.Channel(timeout=5.0)\n\n# Query for A records\nchannel.query(\"google.com\", pycares.QUERY_TYPE_A, callback=callback)\n\n# Query for MX records\nchannel.query(\"example.com\", pycares.QUERY_TYPE_MX, callback=callback)\n\n# Basic event loop processing\nwhile True:\n    read_fds, write_fds = channel.getsockname()\n    if not read_fds and not write_fds:\n        break\n    \n    # In a real application, use an actual event loop (e.g., asyncio, Tornado, Gevent)\n    # For this simple example, we block briefly\n    try:\n        rlist, wlist, xlist = socket.select(read_fds, write_fds, [], 1.0)\n    except socket.error as e:\n        print(f\"Socket error in select: {e}\")\n        break\n\n    channel.process_fd(rlist, wlist)\n","lang":"python","description":"This quickstart demonstrates how to perform asynchronous DNS queries for A and MX records using `pycares`. It sets up a `Channel` and makes two queries with a shared callback function. A basic `select`-based loop is used to process file descriptors and handle the asynchronous responses. In a production environment, `pycares` is typically integrated with a more robust event loop like `asyncio` (via `aiodns`), `Tornado`, or `Gevent`."},"warnings":[{"fix":"Update your result parsing logic to expect `DNSResult` objects with `answer`, `authority`, and `additional` sections, and access record data via `record.data.addr`, `record.data.exchange`, etc. Refer to the v5.0.0 migration guide for details.","message":"The DNS query results API was completely rewritten in v5.0.0. Results are now returned as structured dataclasses (`DNSResult`, `DNSRecord`, and specific `RecordData` types like `ARecordData`, `MXRecordData`, etc.) instead of a list of record-specific objects. Existing code accessing results will break.","severity":"breaking","affected_versions":">=5.0.0"},{"fix":"Pass all `Channel` constructor arguments (e.g., `timeout`, `flags`, `lookups`) and the `callback` argument to query methods as keyword arguments. Remove any explicit `event_thread` arguments.","message":"In v5.0.0, the `Channel` constructor arguments and the `callback` parameter for query methods are now strictly keyword-only. The `event_thread` parameter has also been removed, as event thread mode is now implicit.","severity":"breaking","affected_versions":">=5.0.0"},{"fix":"Ensure your application decodes TXT record data (e.g., `record.data.data.decode('utf-8')`) if string representation is required.","message":"As of v5.0.0, TXT record data is returned as bytes instead of strings. This change affects how TXT record content should be handled.","severity":"breaking","affected_versions":">=5.0.0"},{"fix":"Install CMake (version 3.5+) on your system before attempting to build `pycares` from source (e.g., `apt-get install cmake` on Debian/Ubuntu, `brew install cmake` on macOS).","message":"Pycares v5.0.0 switched its build system for the bundled c-ares library to CMake. Building from source now requires CMake version 3.5 or higher to be installed on the system.","severity":"breaking","affected_versions":">=5.0.0"},{"fix":"Ensure `Channel` objects are explicitly kept alive and properly managed for the entire duration of any pending DNS queries. Implement robust lifecycle management, especially in long-running or highly concurrent applications. Avoid creating `Channel` objects per-request that might be prematurely destroyed.","message":"Improper management of `pycares.Channel` objects, particularly allowing them to be garbage collected while DNS queries are still pending, can lead to a use-after-free vulnerability, causing a fatal Python interpreter crash.","severity":"gotcha","affected_versions":"<=5.0.1 (general concern, specific fixes likely in 5.x)"},{"fix":"When developing or testing, ensure a stable network connection and a properly configured DNS resolver. Account for network-related errors in your application's error handling for DNS lookups.","message":"DNS queries made by `pycares` are real network operations. Consequently, tests and examples often require active internet access and can be sensitive to network conditions or DNS server configurations, potentially leading to environment-specific failures.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"last_verified":"2026-04-05T00:00:00.000Z","next_check":"2026-07-04T00:00:00.000Z"}