Skip to main content

bindantic

PyPI version Python versions License CI Coverage Docs PyPI Downloads

bindantic - a library for managing BIND9 DNS server configuration via Pydantic models.

Instead of manually editing named.conf , you describe the configuration in Python, and the library generates correct BIND9 syntax and (optionally) places files into the required directories.

Features

  • Full support for all named.conf blocks:
    • acl, controls, dnssec-policy, http, key, key-store, logging, options, remote-servers, server, statistics-channels, tls, trust-anchors, view, zone.
  • All common resource record types:
    • A, AAAA, CAA, CERT, CNAME, DNAME, DNSKEY, DS, HINFO, LOC, MX, NAPTR, NSEC, NS, PTR, RP, RRSIG, SOA, SPF, SRV, SSHFP, TLSA, TXT.
  • Built-in validation - pass strings, numbers, IP addresses, durations – the library will format them correctly for BIND.
  • Syntax generation in one line
    • model.model_bind_syntax() - for any block or the whole named.conf,
    • zone.model_bind_syntax_zone_file() - for a ready-to-use zone file.
  • Generate files without writing / write to disk
    • config.generate_files() - returns a list of generated files
    • config.write_files("./my_config") - creates named.conf, zones, keys, DNSSEC policies and organises them into subdirectories.
  • Python - 3.10+, static typing, 96% test coverage.
  • No extra dependencies - only Pydantic

Installation

pip install bindantic

⚠️ NOTE:

The named-checkconf utility from the bind-utils package may be older than your BIND server and may not recognise new directives.

bindantic generates syntax according to the latest stable BIND 9.20.x version. If you check the configuration with an older utility you may get errors. Always use the same version of named-checkconf as your server, if possible.

Quick Start

Example of a minimal configuration

from bindantic import (
    ARecord,
    NamedConfig,
    NSRecord,
    OptionsBlock,
    SOARecord,
    ZoneBlock,
    ZoneTypeEnum,
)

config = NamedConfig(
    options_block=OptionsBlock(
        directory="/etc/bind",
        recursion=True,
        allow_recursion=["localhost", "localnets"],
        listen_on=["any"],
        listen_on_v6=["any"],
    ),
    zone_blocks=[
        ZoneBlock(
            comment="optional comment",
            name="example.com",
            zone_type=ZoneTypeEnum.PRIMARY,
            file="zones/example.com.zone",
            resource_records=[
                SOARecord(
                    mname="ns1.example.com",
                    rname="admin.example.com",
                    serial=2026010101,
                    refresh=10800,
                    retry=3600,
                    expire=604800,
                    minimum=3600,
                    origin="example.com",
                    ttl=3600,
                ),
                NSRecord(nsdname="ns1.example.com", comment="optional comment"),
                ARecord(name="@", address="192.168.1.1"),
            ],
        )
    ],
)
Output of `config.model_bind_syntax()`
options {
    allow-recursion {
        localhost;
        localnets;
    };
    directory "/etc/bind";
    listen-on {
        any;
    };
    listen-on-v6 {
        any;
    };
    recursion yes;
};

# optional comment
zone example.com. {
    type primary;
    file "zones/example.com.zone";
};
Output of `config.zone_blocks[0].model_bind_syntax_zone_file()`
$TTL 3600
$ORIGIN example.com.
@                    IN   SOA ns1.example.com. admin.example.com. (
                                     2026010101 ; Serial number (YYYYMMDDNN)
                                     10800      ; Refresh time
                                     3600       ; Retry time
                                     604800     ; Expire time
                                     3600       ; Minimum TTL
                     )
@                    IN   NS         ns1.example.com. ; optional comment
@                    IN   A          192.168.1.1
Output of `config.generate_files()`
[
    GeneratedFile(
        path=PosixPath("/etc/bind/zones/example.com.zone"),
        content="<CONTENT>",
        type="zone",
    ),
    GeneratedFile(
        path=PosixPath("/etc/bind/named.conf"),
        content="<CONTENT>",
        type="config",
    ),
]
Output of `config.write_files(base_dir="./examples/example")`
example_bind/
├── named.conf
└── zones/
    └── example.com.zone
# Automatically generated by bindantic - please adjust!

options {
    allow-recursion {
        localhost;
        localnets;
    };
    directory "examples/example";
    listen-on {
        any;
    };
    listen-on-v6 {
        any;
    };
    recursion yes;
};

# optional comment
zone example.com. {
    type primary;
    file "zones/example.com.zone";
};
$TTL 3600
$ORIGIN example.com.
@                    IN   SOA ns1.example.com. admin.example.com. (
                                     2026010101 ; Serial number (YYYYMMDDNN)
                                     10800      ; Refresh time
                                     3600       ; Retry time
                                     604800     ; Expire time
                                     3600       ; Minimum TTL
                     )
@                    IN   NS         ns1.example.com. ; optional comment
@                    IN   A          192.168.1.1


The file ./examples/manual_example.py contains usage examples for all supported models.

More examples

Focused, runnable scripts for common real-world setups:

Versioning

bindantic follows Semantic Versioning.

  • Public API - everything importable from the top-level bindantic package (models, enums, field type aliases) is covered by semver guarantees.
  • Internal - any module prefixed with _ (e.g. bindantic._base_model, bindantic._base_types_validation) is an implementation detail and may change without notice.
  • Major - removing/renaming a public model or field, or a change that makes previously valid input invalid, or a change to the generated BIND syntax output.
  • Minor - new models, new optional fields, support for new BIND directives.
  • Patch - bug fixes that don't change the public API surface.

bindantic targets the latest stable BIND 9.20.x release; tracking a new BIND directive is treated as a minor bump unless it conflicts with existing behavior.

Release files for bindantic 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bindantic 1.0.0
File Size Uploaded
bindantic-1.0.0.tar.gz 56.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for bindantic 1.0.0
File Interpreter ABI Platform
bindantic-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 120.1 kB

Release files / bindantic-1.0.0.tar.gz

Download URL bindantic-1.0.0.tar.gz
Size 56.2 kB
Tags Source
SHA-256 checksum
How to use checksums
050329692c95cada17c4cb578994ff7e762553c1f05232d727002b974d347f33
BLAKE2b-256 checksum
How to use checksums
e890ca43c03e8eb22cb53a633312b4efb19eecb593f3b78fd5991dc1a8c62a5c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 2, 2026.

Transparency log

Release files / bindantic-1.0.0-py3-none-any.whl

Download URL bindantic-1.0.0-py3-none-any.whl
Size 63.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8d269bd6309f5080b5d1b96f49593bf6270a28dc074c22bae7b729d5dc37656c
BLAKE2b-256 checksum
How to use checksums
24d8ba9954c0a616e6feb56054d96f9dc0163297f38d0d9d8f89eb2a3950b6e0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 2, 2026.

Transparency log

Release history Release notifications | RSS feed

2.0.0

2 release files

This release

1.0.0 This release

2 release files

0.9.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page