Skip to main content

tftp

Version Python versions License: MIT Docs CI

A pure-Python TFTP client, server, relay and capture decoder for IPv4 and IPv6 that implements the whole of modern TFTP: RFC 1350, the option extension (RFC 2347) with blksize, timeout, tsize and windowsize (RFC 2348, 2349, 7440), tftp-hpa's extensions, block-number rollover and netascii. Built as infrastructure for network boot: it interoperates with iPXE, tftp-hpa, BusyBox, dnsmasq and curl, serves files, HTTP or another TFTP server, and shows you what crossed the wire.

import tftp

tftp.Client("192.0.2.1").download("pxelinux.0", "pxelinux.0")

with tftp.Server("/srv/tftp") as server:      # IPv6 + IPv4, port 69
    server.serve_forever()

Features

  • Complete option support — blksize up to 65464, RFC 7440 windows, tsize both ways, timeout, tftp-hpa's utimeout, rollover, blksize2, cookie, and Windows bootmgr's mstfwindow. Unlimited file size. A registry for your own options, and profiles (pxe, hpa, legacy, strict) for quirky peers.
  • Fast — windowed transfers move hundreds of MiB/s over loopback in pure Python (see benchmarks); the hot path reads into preallocated buffers and keeps a sent window in memory instead of re-reading.
  • Correct under loss — Sorcerer's Apprentice fix, exponential backoff, gap detection inside a window, repeated OACKs tolerated, ERROR 5 for stray packets without disturbing the transfer, dallying on the last ACK. The engine is tested over a simulated lossy link and fuzzed.
  • IPv4 and IPv6 — dual-stack listening by default; v4 clients are served from plain v4 sockets.
  • Replies from the request's address — on a multi-homed host or a VIP, each transfer answers from the address the request was sent to (pktinfo, via netimps); tested on Linux and Windows.
  • Safe file serving — no path escapes root (.., symlinks, Windows device names), uploads are atomic (a failed upload leaves nothing), quotas and disk-space checks from tsize.
  • Pluggable backends — a handler is two methods, so boot menus or images can be generated per client; built in: a directory, memory, an HTTP(S) gateway, and a terminating proxy to another TFTP server. Slow backends apply backpressure instead of blocking other transfers.
  • Transparent relay — forwards requests byte for byte to upstream servers (routed by subnet, filename or interface), so unknown extensions still work.
  • Capture and debugging — trace every datagram from the client, server or relay; write Wireshark-readable pcaps; read pcap/pcapng files or a live tcpdump pipe, reconstruct each transfer and extract its file.
  • Directory listings — an opt-in extension between pytftp peers: pytftp ls, Client.listdir(), and iterdir/walk/glob on paths; other servers simply ignore it.
  • Deployment — transfer ports pinned to a range for firewalls; per-client roots, case-insensitive names and filename remapping in pytftp serve.
  • asyncio — AsyncClient and AsyncServer with async handlers and streams.
  • pathlib — client.path("boot/x").read_bytes(), and tftp:// URLs in pathlib-next, so UriPath("tftp://h/x").copy("s3://bucket/x") just works (optional extra).
  • Bounded — limits on requests, sessions per client, window memory and transfer time; counters for metrics.
  • CLI — pytftp get|put|serve|relay|capture with --json, --trace and --pcap (optional extra).

Installation

pip install tftp            # library
pip install "tftp[cli]"     # plus the pytftp command
Extra Adds Needed for
cli duho the pytftp command and python -m tftp
path pathlib-next[uri] TftpPath, and tftp:// URLs in pathlib_next.uri.UriPath

Requires Python 3.9+. The one required dependency, netimps, has no dependencies of its own.

Quick start

Client:

import tftp

client = tftp.Client("boot.example.net", blksize=1428, windowsize=16)
result = client.download("images/vmlinuz", "vmlinuz")
print(result.bytes, result.duration, result.negotiated)

data = client.get("pxelinux.cfg/default")          # into memory
client.upload("logs/boot.txt", b"ok\n")            # needs a writable server

Server with uploads, a bounded window and a completion hook:

import tftp

server = tftp.Server(
    "/srv/tftp",
    "::",
    69,
    writable=True,
    options=tftp.ServerOptions(max_blksize=8192, max_windowsize=32),
    on_complete=lambda r: print(r.operation, r.filename, r.peer[0], r.error or "ok"),
)
server.serve_forever()

Generated content:

import io
import tftp

class Menu(tftp.FileSystemHandler):
    def open_read(self, context):
        if context.filename == "menu.cfg":
            return io.BytesIO(b"client %s\n" % context.peer[0].encode())
        return super().open_read(context)

tftp.Server(Menu("/srv/tftp")).serve_forever()

Command line:

pytftp get 192.0.2.1 pxelinux.0 -b 1428 -w 16
pytftp put 192.0.2.1 firmware.bin
pytftp serve /srv/tftp --port 6969 --write --json

Relay, capture and asyncio:

import tftp
from tftp.relay import Relay, RouteTable, by_subnet
from tftp.capture import PcapWriter, analyze

# Forward requests to per-subnet boot servers, recording everything.
with PcapWriter("relay.pcap") as pcap:
    route = RouteTable([by_subnet({"10.1.0.0/16": "10.1.0.5"})], default="10.0.0.20")
    Relay(route, trace=pcap).serve_forever()

# What happened in a capture (yours, or tcpdump's)?
for transfer in analyze("boot.pcapng").transfers:
    print(transfer, transfer.missing_blocks)

# asyncio
async def fetch():
    async for chunk in tftp.aio.AsyncClient("192.0.2.1").stream("vmlinuz"):
        ...
pytftp serve --http https://images.example.com/pxe/ --compat pxe
pytftp relay 10.0.0.20 --route-prefix windows/=wds.lan --trace
tcpdump -i eth0 -U -w - udp | pytftp capture - --filter "op=RRQ,ERROR"

API overview

Module Purpose
tftp.client Client, download, upload
tftp.server Server, ServerLimits, FileSystemHandler, AtomicWriter, RequestContext
tftp.backends MemoryHandler, HttpHandler, UpstreamHandler (proxy), Pipe
tftp.relay Relay and routing helpers
tftp.aio AsyncClient, AsyncServer
tftp.capture trace events, PcapWriter, pcap/pcapng reading, analyze, filters
tftp.options ServerOptions, option registry, profiles, Negotiated
tftp.packet Opcode, ErrorCode, packet types, encode_*/decode
tftp.transfer I/O-free Sender/Receiver engine
tftp.uri tftp:// URLs
tftp.path TftpPath, TftpUriPath (path extra)
tftp.netascii streaming netascii translation
tftp.errors TftpError and the typed RemoteError subclasses
tftp.cli the pytftp command (cli extra)

Everything is also importable from tftp directly. The complete reference, with every signature and gotcha, is src/tftp/AGENTS.md, which ships inside the package.

Development

py -3.14 -m venv .venv/3.14-nt-arm64          # or python3.14 -m venv .venv/3.14-posix-x86_64
.venv/3.14-nt-arm64/Scripts/pip install -e ".[dev]"
.venv/3.14-nt-arm64/Scripts/python -m pytest -q
.venv/3.14-nt-arm64/Scripts/python -m black --check src tests benchmarks examples
python benchmarks/run.py

pytest -m "not slow" skips the rollover tests; tests marked interop run against curl, tftp-hpa, BusyBox and dnsmasq where installed (their servers need passwordless sudo). sudo python tests/firmware_boot.py ipxe network-boots iPXE in QEMU against the server (its uefi scenario does not pass yet). See AGENTS.md for the layout and conventions.

Releasing

This project follows Semantic Versioning and keeps a CHANGELOG.md. Pushing a tag matching v* triggers the release workflow: test gate → build (checking the tag names the version built) → a strict docs build as a gate → GitHub release → publish. The release workflow never deploys the docs site itself: for a final release its last job dispatches the docs workflow at the tag, which owns every Pages deploy.

License

MIT — see LICENSE.

Metadata

Release files for tftp 0.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 tftp 0.0.0
File Size Uploaded
tftp-0.0.0.tar.gz 176.8 kB Details

Built distribution (wheel)

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

Total release size: 338.5 kB

Release files / tftp-0.0.0.tar.gz

Download URL tftp-0.0.0.tar.gz
Size 176.8 kB
Tags Source
SHA-256 checksum
How to use checksums
e85bb0ae569448e8253eefe5c526c0204f074947a587dfc125c4bafe42580145
BLAKE2b-256 checksum
How to use checksums
a4097ef1ebe39db45d722b84ce42223198bb67541749fe8aaba6d6116f7bde9d
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 / tftp-0.0.0-py3-none-any.whl

Download URL tftp-0.0.0-py3-none-any.whl
Size 161.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
dfa72f8f9e268c6ef990376ede67aa6afa1b6f14920cee6a617ed774cca5797b
BLAKE2b-256 checksum
How to use checksums
09135487008104473047a9eaa689aee29703bb9dc39e80de6b62042a734a6720
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.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

This release

0.0.0 This release

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