Skip to main content

py-doh-core

Python bindings for doh-core, via PyO3/maturin. Not yet published to PyPI.

DohTransport (DoH, GET or POST), DotTransport (DoT), and DoqTransport (DoQ) are all bound, each with a blocking resolve() and an async def-compatible aresolve(), plus resolve_many()/ aresolve_many() for querying several record types against one name in a single call (mirroring doh-cli's variadic [record_types...] argument -- see Multiple record types below). Responses come back as typed ParsedResponse/Answer objects (see py_doh_core.pyi for the full shape) mirroring every field of doh_core::ParsedResponse, not plain dicts. op_code/response_code are OpCode/ResponseCode enums (e.g. response.response_code == doh.ResponseCode.NXDOMAIN), not magic strings.

This crate is intentionally excluded from the main Cargo workspace (see the root Cargo.toml): it's a PyO3 cdylib extension module, which needs maturin's linker setup to resolve Python symbols at import time — plain cargo build/cargo test --workspace can't link it.

Build / try it locally

cd py-doh-core
python3 -m venv .venv
source .venv/bin/activate
pip install maturin
maturin develop

The convention used here and throughout tests/test_resolve.py is to import the module as doh:

import asyncio
import py_doh_core as doh

transport = doh.DohTransport("https://dns.google/dns-query")
response = transport.resolve("example.com", "A")
assert response.response_code == doh.ResponseCode.NOERROR
print(response.response_code, response.answers[0].rdata)


async def main():
    dot = doh.DotTransport("dns.google")
    return await dot.aresolve("example.com", "AAAA")


print(asyncio.run(main()))

Errors (bad server URL, DNS failures, SERVFAIL/REFUSED, etc.) raise doh.DohError with the same message doh-core itself produces — no fallback to classic plaintext DNS, same as the Rust library.

Multiple record types

resolve_many()/aresolve_many() query several record types for one name against a single transport instance, matching doh-cli's own multi-type behavior: queries run in turn (reusing the connection -- this matters most for DoqTransport's pooled connection), and one type's failure doesn't abort the rest. Each entry in the returned list is a QueryResult with record_type, and exactly one of response/error set:

transport = doh.DohTransport("https://dns.google/dns-query")
for result in transport.resolve_many("example.com", ["A", "AAAA", "MX"]):
    if result.error is not None:
        print(result.record_type, "failed:", result.error)
    else:
        print(result.record_type, [a.rdata for a in result.response.answers])

An unparseable record type string (unlike a per-query network/DNS failure) raises DohError immediately, before any query is sent — also matching doh-cli's CLI-arg validation.

Logging

Verbose/debug output uses Python's standard logging module -- no separate init call needed:

import logging

logging.basicConfig(level=logging.DEBUG)

Logger names follow the Rust module path, e.g. doh_core.transport.doh, doh_core.transport.doq, py_doh_core.transport. DEBUG shows one line per query (server, method, connection reuse, response codes); a small amount of extra detail (e.g. response sizes) logs at level 5, below logging.DEBUG (10) -- pass level=5 to see it. Scope to just this library with logging.getLogger("doh_core").setLevel(logging.DEBUG).

Only doh_core/py_doh_core targets are bridged to Python -- dependency crates (reqwest, h2, rustls, quinn) are deliberately not, since their logging runs on long-lived background threads that can outlive a single resolve() call and, in rare cases, still be active as the Python interpreter shuts down.

Tests

pip install pytest pytest-asyncio
pytest

tests/test_resolve.py runs live against real public resolvers (no mocking layer, same approach the Rust side uses). DoT/DoQ cases skip automatically if port 853 is unreachable on the current network.

Releasing

Wheels (Linux/macOS/Windows, one per platform via PyO3's abi3-py39 stable ABI -- no per-Python-version rebuilds needed) and an sdist are built and published to PyPI by .github/workflows/py-doh-core-release.yml, triggered by pushing a tag matching py-v* (e.g. py-v0.1.0 -- distinct from the Rust crates' plain v* tags, since this package versions independently). Publishing uses PyPI Trusted Publishing (OIDC), so no API token is stored as a secret; the PyPI project must have this repo/workflow/pypi environment registered as a pending publisher before the first release.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

py_doh_core-0.1.0.tar.gz (82.4 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

py_doh_core-0.1.0-cp39-abi3-win_amd64.whl (3.1 MB view details)

Uploaded CPython 3.9+Windows x86-64

py_doh_core-0.1.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.8 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ x86-64

py_doh_core-0.1.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.9 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ ARM64

py_doh_core-0.1.0-cp39-abi3-macosx_11_0_arm64.whl (3.5 MB view details)

Uploaded CPython 3.9+macOS 11.0+ ARM64

py_doh_core-0.1.0-cp39-abi3-macosx_10_12_x86_64.whl (3.6 MB view details)

Uploaded CPython 3.9+macOS 10.12+ x86-64

File details

Details for the file py_doh_core-0.1.0.tar.gz.

File metadata

  • Download URL: py_doh_core-0.1.0.tar.gz
  • Upload date:
  • Size: 82.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for py_doh_core-0.1.0.tar.gz
Algorithm Hash digest
SHA256 1a936f6f8a3c99b139aed04a41a807bcd2d771c998ee5dd605586e186a811b93
MD5 c2b8f408da0ee9df772ce77e54e73b9b
BLAKE2b-256 c77d3683bd77a254b3fdcf58757a8d039ee0fcb63aa8fe936f33d26339409710

See more details on using hashes here.

Provenance

The following attestation bundles were made for py_doh_core-0.1.0.tar.gz:

Publisher: py-doh-core-release.yml on ubahmapk/doh

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file py_doh_core-0.1.0-cp39-abi3-win_amd64.whl.

File metadata

  • Download URL: py_doh_core-0.1.0-cp39-abi3-win_amd64.whl
  • Upload date:
  • Size: 3.1 MB
  • Tags: CPython 3.9+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for py_doh_core-0.1.0-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 7bbe0e4f80b450e3cb713c10dc27315cf07acdd2d7975f11009fea0c1c62c903
MD5 9ca3b9cce2e69ddb0af0402e62a94b6e
BLAKE2b-256 5d19d838d5e4ca3788c70a0f3ffa9225cd9319079213e3bc19dd301e2a7b4b9f

See more details on using hashes here.

Provenance

The following attestation bundles were made for py_doh_core-0.1.0-cp39-abi3-win_amd64.whl:

Publisher: py-doh-core-release.yml on ubahmapk/doh

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file py_doh_core-0.1.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for py_doh_core-0.1.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 d0948fe6df5a4833fc1d855cb0973c6fc6ea03d9cabae47e80eff648e9aa7567
MD5 4100eb47df343948a173a98e4f6733fe
BLAKE2b-256 25d7314109ba5a1555237801e90cf6973d52b52efc298e5b5eab171a99135332

See more details on using hashes here.

Provenance

The following attestation bundles were made for py_doh_core-0.1.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: py-doh-core-release.yml on ubahmapk/doh

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file py_doh_core-0.1.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for py_doh_core-0.1.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 aed17052867b411a89ebbcf42af21cd352d3d42a5502af1322e4c17390752280
MD5 d15e78c6ef6857994314390d2fe128db
BLAKE2b-256 21542188e95976b3e478b117c2dee4ad440012c45715f51e5d27513adaa8babc

See more details on using hashes here.

Provenance

The following attestation bundles were made for py_doh_core-0.1.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: py-doh-core-release.yml on ubahmapk/doh

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file py_doh_core-0.1.0-cp39-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for py_doh_core-0.1.0-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c7c1fd9491c23b7870802572f1a25cc2d63f788992087562fa2acf10ea27847e
MD5 34652bddae62e64dc4de3ad63fbde512
BLAKE2b-256 a222117a2f21932147027a29bc0ea272d48700785db7ac327358dc091b8cbbe5

See more details on using hashes here.

Provenance

The following attestation bundles were made for py_doh_core-0.1.0-cp39-abi3-macosx_11_0_arm64.whl:

Publisher: py-doh-core-release.yml on ubahmapk/doh

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file py_doh_core-0.1.0-cp39-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for py_doh_core-0.1.0-cp39-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 8fc980094082916b84f6eca5886cea500f5481d6f5930bca79c213f551b49dfd
MD5 264d410560dfae203ba1b155aca2c6c4
BLAKE2b-256 d107a202fe52a7ab9d3d48206506af4668069a09015b25f5dd7054a687bc6100

See more details on using hashes here.

Provenance

The following attestation bundles were made for py_doh_core-0.1.0-cp39-abi3-macosx_10_12_x86_64.whl:

Publisher: py-doh-core-release.yml on ubahmapk/doh

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.1.1

6 files

This release

0.1.0 This release

6 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page