Skip to main content

pydhcp

Tests Version Python versions License: MIT Docs

A Python DHCP library and server implementation.

pydhcp is pure Python and targets Python 3.9 and newer. Packet parsing and structured packet tooling are portable; actual DHCP serving still depends on OS socket permissions and platform-specific UDP behavior.

Features

  • DHCP Packet Parsing — Full support for parsing and constructing DHCP packets.
  • DHCP Server Base — A simple, async-friendly server foundation with overrideable lease and option policy hooks.
  • DHCP Client & Capture Tools — Basic packet-client builders and a tshark-like capture command for troubleshooting.

Installation

pip install pydhcp

TOML packet encode/decode support is optional. Install pydhcp[toml] if you want pydhcp packet --format toml; JSON, YAML, and INI support remain available with the base package.

Quick start

Synchronous Server

from pydhcp.server import DhcpServer

server = DhcpServer(listen="*")
server.listen()

The built-in server intentionally keeps allocation policy small. It renews existing leases and responds to client-requested addresses, while applications can subclass DhcpServer or provide a custom lease backend for pools, reservations, and site-specific options.

You can also bind explicit endpoints or multiple ports when you do not want wildcard behavior:

server = DhcpServer(listen=[("127.0.0.1", [6767, 6768])], per_interface=True)
server.listen()

Asynchronous Server

Every listener has an asyncio counterpart -- AsyncDhcpListener, AsyncDhcpServer, AsyncDhcpRelay and AsyncDhcpCapture. They are mixins over the same receive path rather than parallel implementations, so a fix reaches both halves; a test fails if any receive-path line is duplicated between them.

import asyncio
from pydhcp.server import AsyncDhcpServer

async def main():
    server = AsyncDhcpServer()
    await server.start()      # binds and starts receiving; returns immediately
    try:
        await asyncio.Event().wait()   # serve until cancelled (Ctrl-C)
    finally:
        server.stop()

asyncio.run(main())

start() returns as soon as the sockets are bound, so something has to keep the loop alive — await your application's own work there instead of the Event if you have any. Handlers run on a worker thread, so a blocking handle() will not stall the rest of your application.

Basic Packet Client

DhcpClient is a packet-level helper for tests and troubleshooting. It sends DHCP messages and queues matching replies, but it does not configure host network interfaces.

from pydhcp.client import DhcpClient

client = DhcpClient(listen=("127.0.0.1", 6768))
discover = client.build_discover(b"\x00\x11\x22\x33\x44\x55")
client.send(discover, destination="127.0.0.1", port=6767)

Command Line Interface (CLI)

pydhcp includes a command line interface for listing network adapters, decoding packets, and starting servers.

# List all network interfaces
pydhcp interfaces

# Decode a hex-encoded DHCP packet from stdin as JSON
pydhcp packet --decode --input - --format json

# Decode a hex-encoded DHCP packet from stdin as a compact text summary
pydhcp packet --decode --input - --format summary

# Encode structured packet text back to hex
pydhcp packet --encode --input packet.json --format json --output packet.hex

# Capture DHCPDISCOVER packets as newline-delimited JSON on stdout
pydhcp capture --listen 127.0.0.1:6767 --filter msg_type=DHCPDISCOVER --output -

# Write one structured file per capture
pydhcp capture --listen 127.0.0.1:6767 --output "output/{client_id}/{timestamp}_{msg_type}.{format}" --output-mode per-capture --format json

# Invoke a trusted local command hook with each captured packet on stdin
pydhcp capture --listen 127.0.0.1:6767 --hook ./on-dhcp-capture

# Start the DHCP server from JSON or INI config
pydhcp server --config config.json

# Listen on multiple explicit endpoints while debugging
pydhcp server --listen 127.0.0.1:6767,127.0.0.1:6768

# Increase logging while debugging (-v is repeatable; --loglevel targets one logger)
pydhcp server --listen 127.0.0.1:6767 -v
pydhcp server --listen 127.0.0.1:6767 --loglevel pydhcp=DEBUG

Development

See AGENTS.md for environment setup, dependency install, and test commands.

For comprehensive validation in GitHub Actions, the test workflow also supports manual workflow_dispatch runs and safe ci-* tags. Benchmarks stay repo-local and opt-in: use the workflow's run_benchmarks input or a ci-bench-* tag when you want the benchmark harness included.

python benchmarks/run.py                 # print a summary
python benchmarks/run.py --save          # write benchmarks/results/<name>.json
python benchmarks/run.py --suite parse   # one suite instead of all

Results are min/median/max ms per call over repeated samples; see benchmarks/README.md for the schema and for why local timings are not a performance claim.

Releasing

This project follows Semantic Versioning and keeps a CHANGELOG.md. Pushing a tag matching v* triggers the release workflow.

Documentation site

MkDocs builds the API reference from docs/, published on every release. The docs also include a "Common DHCP Options" page with typed examples.

License

MIT — see LICENSE.

Metadata

Release files for pydhcp 0.7.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 pydhcp 0.7.0
File Size Uploaded
pydhcp-0.7.0.tar.gz 317.5 kB Details

Built distribution (wheel)

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

Total release size: 519.3 kB

Release files / pydhcp-0.7.0.tar.gz

Download URL pydhcp-0.7.0.tar.gz
Size 317.5 kB
Tags Source
SHA-256 checksum
How to use checksums
13a54beda68224c65b1e3aeb79885b872e875713cb4801c6c3943c1b57fa8d54
BLAKE2b-256 checksum
How to use checksums
61902a1d9c2f61c3fe1d9878640b1ceb51130d3d0ba30eccfde8a1ed6928fb00
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 Oct 3, 2026.

Transparency log

Release files / pydhcp-0.7.0-py3-none-any.whl

Download URL pydhcp-0.7.0-py3-none-any.whl
Size 201.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1043f68a916df0e017a198f3f56abed504f2b503dfc57445d1fd4bcdeb2a34ad
BLAKE2b-256 checksum
How to use checksums
27eecb337651a59ccad659344e098b8f54ef22a64cddf92eada1dcedf94f12b0
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 Oct 3, 2026.

Transparency log

Release history Release notifications | RSS feed

0.9.0

2 release files

0.8.1

2 release files

0.8.0

2 release files

This release

0.7.0 This release

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.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