Skip to main content

dfukit

Firmware updates over any link. dfukit is a small update protocol with a server for the device and a client for the host, both in C.

  • One protocol for every link: UART, UDP, TCP, BLE, USB, or a link of your own. dfukit sends frames; the link only has to carry them, and may lose some.
  • A pipeline, not a request per frame: the host sends what the device's window allows, the device acknowledges in bulk, and a lost frame is sent again from where it went missing (go-back-N).
  • Images raw or deflated, decoded on the device as they come in (miniz's inflater, built in).
  • A 32-bit board ID per image target: it selects the backend that writes the image, and a device refuses IDs it does not know before it touches anything.
  • Backends for what is behind a board ID: your own for an OTA slot or a bootloader's slot, one for RAM that comes with dfukit, or a device further down a chain (pass-through).
  • Resume after a lost link, with the device's state kept for a while.
  • No threads, no heap and no platform code in the core: the application feeds it frames and time, and gets frames back through a callback.

The protocol and the internals are described in DESIGN.md, and what changed in CHANGELOG.md.

How an update goes

The host sends START with the image's board ID, size and CRC-32. The device prepares, then tells the host how much data it may send ahead of the acknowledgements: the window. The host streams DATA up to that limit and the device acknowledges as it goes. When a frame is lost, the host goes back and sends again from the missing point (go-back-N); it does the same after a retransmission timeout (RTO) without progress. FINISH checks the CRC and runs the backend's own checks, and ACTIVATE switches to the new image.

Adding it to a project

With CMake, from a copy or a submodule of this repository (dfukit_ram only if you use the RAM backend):

add_subdirectory(dfukit)
target_link_libraries(app PRIVATE dfukit dfukit_ram)

In an ESP-IDF project the repository is a component: add it to EXTRA_COMPONENT_DIRS (or components/) and REQUIRES it.

Building and testing

pip install pytest "nanobind>=2.5"
cmake -S . -B build && cmake --build build && ctest --test-dir build --no-tests=error

For the C libraries alone, add -DDFUKIT_PYTHON=OFF to the first cmake. That build has no tests, so leave out ctest.

The tests run the server and the client against each other through a simulated link that drops, duplicates and delays frames. They are in Python, on the C code through its bindings; tests/README.md has how to measure their coverage.

A device: the server

The server is a struct the application owns. Frames go in with dfukit_server_feed(), answers come out through the send callback, and dfukit_server_poll() runs its timers. One task calls into a server at a time.

#include <string.h>

#include "dfukit_server.h"

static int send_frame(void *ctx, const dfukit_peer_t *to, const uint8_t *frame, size_t len)
{
	// To the peer `to` on your link (its address, as you gave it to dfukit_server_feed())
	return my_link_send(to, frame, len);
}

static dfukit_server_t server;
static dfukit_backend_t backend;

void update_init(void)
{
	const dfukit_server_config_t config = {
		.send = send_frame,
		.name = "my-device",
		.max_frame = 512, // the largest frame the link carries
	};

	dfukit_server_init(&server, &config);
	my_backend_init(&backend, 0x0000a001); // see "Backends"
	dfukit_server_register(&server, &backend);
}

// For each frame from the link, and every few milliseconds
void on_frame(const uint8_t *addr, size_t addr_len, const uint8_t *frame, size_t len)
{
	dfukit_peer_t from = {.len = (uint8_t)addr_len};

	if (addr_len > DFUKIT_PEER_MAX) {
		return; // longer than a peer: map it to 16 bytes of your own (an index, a hash)
	}
	memcpy(from.bytes, addr, addr_len);
	dfukit_server_feed(&server, &from, frame, len, now_ms());
}

void every_10_ms(void)
{
	dfukit_server_poll(&server, now_ms());
}

A peer is an opaque address of up to 16 bytes (DFUKIT_PEER_MAX): a socket address, a BLE connection handle, a bus address; the server drops frames from a longer one. An IPv6 address with its port is 18 bytes: give the server something shorter that names it (a slot in a table of your own). Two peers are the same when their bytes are. The peer that starts a session owns it; another one gets BUSY until it ends, unless it resumes the same image (see "Security"). INFO and STATUS are answered to anyone.

To take deflated images, give the server an inflater and a dictionary as large as the window the backend announces (32 KiB takes any deflate stream):

#include "dfukit_inflate.h"

static dfukit_inflate_t inflate;
static dfukit_inflater_t inflater;
static uint8_t dict[1u << 15];

dfukit_inflate_init(&inflate, &inflater, dict, sizeof(dict));
// and in the server's config: .inflater = &inflater

on_status in the config reports the session's state and progress, on every change and every acknowledgement: for a light or a display. A pass-through session has no progress to report.

INFO lists as many boards as fit in one frame, after a name cut to fit. Neither the C client nor the Python bindings send or parse it: an application that wants it sends the frame itself and reads the answer (DESIGN.md, Messages). It can warn early, but START is the real check.

Backends

A backend puts an image in place for one board ID (dfukit_backend_t, dfukit_server.h). The server calls it in order:

Callback Required When What it does
begin yes START gets ready for an image of start->image_size bytes (may erase)
write yes data comes in writes the decoded image at offset, in order
window yes every acknowledgement how many more stream bytes it can take now (0: wait)
finish yes FINISH its own checks of the whole image; DFUKIT_PENDING while still writing
activate yes ACTIVATE makes the image the one that runs (restarts, or at the next boot)
abort no the session is broken off undoes what it can

The server does not check for missing callbacks: a required one left NULL crashes when it is called. backends/ram/dfukit_ram.c is a complete backend to start from. Setting one up looks like this:

void my_backend_init(dfukit_backend_t *backend, uint32_t board_id)
{
	memset(backend, 0, sizeof(*backend));
	backend->board_id = board_id;
	backend->kind = DFUKIT_KIND_IMAGE;
	backend->max_size = MY_SLOT_SIZE;
	backend->encodings = DFUKIT_ENCODING_BIT(DFUKIT_ENCODING_RAW); // and _DEFLATE, if it fits
	backend->begin = my_begin;
	backend->write = my_write;
	backend->window = my_window;
	backend->finish = my_finish;
	backend->activate = my_activate;
	backend->abort = my_abort;
	backend->ctx = &my_slot;
}

The application owns the backend, and it must outlive the server.

The server has checked the image's CRC-32 before it calls finish. The CRC catches accidents, not attackers: checking signatures is up to the backend, which hands the image to whatever checks them on its platform.

The CRC is a small module of its own (lib/crc32). Its dfukit_crc32() is weak, so an application replaces it by defining one (a hardware engine, say), in an object file that gets linked. MSVC has no weak symbols: there the static library gives way to the application's definition.

The ones that come with dfukit:

Backend Platform Writes
ram any a buffer; for tests and for devices that handle the image themselves

A pass-through backend (kind = DFUKIT_KIND_PASSTHROUGH) does not write anything: forward gets the session's frames as they are, for a device further down a chain, and that device's answers go back with dfukit_server_downstream(). The server does not read the session: it ends with the owner's ABORT, after the idle time, or when the backend calls dfukit_server_passthrough_end(). abort is called however it ends. A pass-through backend needs forward; its abort is optional, and the image callbacks are not used.

A backend usually ends the session once the device behind it has activated. Hand the answer on first, because ending the session first drops it without an error:

void on_frame_from_the_device_behind(const uint8_t *frame, size_t len)
{
	dfukit_server_downstream(&server, frame, len, now_ms());
	if (dfukit_frame_activated(frame, len)) {
		dfukit_server_passthrough_end(&server);
	}
}

Notes for integrators

  • The window is a promise the backend makes to the host, not a limit the server enforces: a host that sends past it still gets its frames to write. A backend that buffers takes more, or fails.
  • One inflater serves every backend: its dictionary must take the largest window_log2 a backend announces, else a stream compressed to that window fails at its CRC.
  • begin runs inside the START it answers: it must be done within the client's tries times its RTO (4 s by default), or open with a window of 0 and do the rest in the background.
  • activate only schedules the switch (a restart after delay_ms, from a timer or a task): the server answers ACTIVATE with what it returns, so it must return before restarting.
  • finish may return DFUKIT_PENDING while it still writes what it buffered; the host asks again.

Security

The protocol has no authentication. dfukit leaves this to the link and the backend:

  • Anyone who can reach the device can send START, and begin may erase flash before any signature has been checked. Restrict who can reach it, or authenticate the link.
  • A peer that knows an image's CRC-32 and sizes can take over a session on that image by resuming it. There is no other credential.
  • The CRC-32 only catches accidents. To refuse an image that is not yours, the backend or the bootloader checks a signature.

A host: the client

The C client is driven like the server: dfukit_client_feed() with the device's frames, dfukit_client_poll() every few milliseconds, frames out through send, and the image read through read at any offset (a resend reads again), so it need not be in RAM.

#include "dfukit_client.h"
#include "dfukit_crc32.h"

dfukit_client_t client;
const dfukit_client_config_t config = {
	.send = link_send,
	.read = image_read,
	.max_frame = 512,
};
dfukit_start_t start = {
	.board_id = 0x0000a001,
	.encoding = DFUKIT_ENCODING_RAW,
	.image_size = image_len,
	.stream_size = image_len,
};

start.crc32 = dfukit_crc32(0, image, image_len);
dfukit_client_init(&client, &config);
// true: ACTIVATE after FINISH. 0: activate now (DFUKIT_ACTIVATE_AT_NEXT_BOOT: at the next boot).
// 0: no delay before the switch, in milliseconds
dfukit_client_begin(&client, &start, true, 0, 0, now_ms());
while (dfukit_client_state(&client) < DFUKIT_CLIENT_DONE) {
	// feed what came in, then:
	dfukit_client_poll(&client, now_ms());
}
// DFUKIT_CLIENT_DONE, or DFUKIT_CLIENT_FAILED and dfukit_client_status() says why

After a lost link (or a DFUKIT_TIMEOUT), dfukit_client_resume() on the new one goes on where the device stopped, or starts over when the device has no state left.

From Python

pip install dfukit

The same client and server, driven the same way. The caller provides the link and the clock, in milliseconds that fit 32 bits. Unlike the C client, begin() takes the whole image as bytes.

import time

import dfukit


def now_ms() -> int:
    return int(time.monotonic() * 1000) & 0xFFFFFFFF


client = dfukit.Client(link_send, lambda offset, length: image[offset : offset + length], max_frame=512)
client.begin(0x0000A001, image, now_ms())
while client.state not in (dfukit.ClientState.DONE, dfukit.ClientState.FAILED):
    for frame in frames_from_the_link():
        client.feed(frame, now_ms())
    client.poll(now_ms())
if client.state == dfukit.ClientState.FAILED:
    raise RuntimeError(dfukit.status_name(client.status))

dfukit.Server is the device's end, with add() for a backend (RamBackend, PassthroughBackend), feed(peer, frame, now) and poll(now); its send callback gets (peer, frame).

A deflated image goes the same way: the client streams the compressed bytes, and begin() still takes the image, for its size and CRC. The stream is raw deflate, with a window the device announces:

compressor = zlib.compressobj(9, zlib.DEFLATED, -15)
stream = compressor.compress(image) + compressor.flush()
client = dfukit.Client(link_send, lambda offset, length: stream[offset : offset + length], max_frame=512)
client.begin(0x0000A001, image, now_ms(), stream_size=len(stream), encoding=1)

On the server, server.set_inflater(dfukit.Inflate(15)) turns deflate on.

License

Apache-2.0 (LICENSE). miniz's inflater in lib/miniz is MIT (its LICENSE).

Metadata

Release files for dfukit 2.1.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 dfukit 2.1.0
File Size Uploaded Provenance Actions
dfukit-2.1.0.tar.gz 131.6 kB With provenance Details for dfukit-2.1.0.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for dfukit 2.1.0
File Actions
dfukit-2.1.0-cp312-abi3-win_amd64.whl CPython 3.12 abi3 Windows x86-64 Details for dfukit-2.1.0-cp312-abi3-win_amd64.whl
dfukit-2.1.0-cp312-abi3-win32.whl CPython 3.12 abi3 Windows x86-32 Details for dfukit-2.1.0-cp312-abi3-win32.whl
dfukit-2.1.0-cp312-abi3-musllinux_1_2_x86_64.whl CPython 3.12 abi3 Linux musl 1.2+ x86-64 Details for dfukit-2.1.0-cp312-abi3-musllinux_1_2_x86_64.whl
dfukit-2.1.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.12 abi3 Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 Details for dfukit-2.1.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
dfukit-2.1.0-cp312-abi3-macosx_11_0_arm64.whl CPython 3.12 abi3 macOS 11.0+ ARM64 Details for dfukit-2.1.0-cp312-abi3-macosx_11_0_arm64.whl
dfukit-2.1.0-cp312-abi3-macosx_10_14_x86_64.whl CPython 3.12 abi3 macOS 10.14+ x86-64 Details for dfukit-2.1.0-cp312-abi3-macosx_10_14_x86_64.whl
dfukit-2.1.0-cp311-cp311-win_amd64.whl CPython 3.11 CPython 3.11 Windows x86-64 Details for dfukit-2.1.0-cp311-cp311-win_amd64.whl
dfukit-2.1.0-cp311-cp311-win32.whl CPython 3.11 CPython 3.11 Windows x86-32 Details for dfukit-2.1.0-cp311-cp311-win32.whl
dfukit-2.1.0-cp311-cp311-musllinux_1_2_x86_64.whl CPython 3.11 CPython 3.11 Linux musl 1.2+ x86-64 Details for dfukit-2.1.0-cp311-cp311-musllinux_1_2_x86_64.whl
dfukit-2.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 Details for dfukit-2.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
dfukit-2.1.0-cp311-cp311-macosx_11_0_arm64.whl CPython 3.11 CPython 3.11 macOS 11.0+ ARM64 Details for dfukit-2.1.0-cp311-cp311-macosx_11_0_arm64.whl
dfukit-2.1.0-cp311-cp311-macosx_10_14_x86_64.whl CPython 3.11 CPython 3.11 macOS 10.14+ x86-64 Details for dfukit-2.1.0-cp311-cp311-macosx_10_14_x86_64.whl
dfukit-2.1.0-cp310-cp310-win_amd64.whl CPython 3.10 CPython 3.10 Windows x86-64 Details for dfukit-2.1.0-cp310-cp310-win_amd64.whl
dfukit-2.1.0-cp310-cp310-win32.whl CPython 3.10 CPython 3.10 Windows x86-32 Details for dfukit-2.1.0-cp310-cp310-win32.whl
dfukit-2.1.0-cp310-cp310-musllinux_1_2_x86_64.whl CPython 3.10 CPython 3.10 Linux musl 1.2+ x86-64 Details for dfukit-2.1.0-cp310-cp310-musllinux_1_2_x86_64.whl
dfukit-2.1.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.10 CPython 3.10 Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 Details for dfukit-2.1.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
dfukit-2.1.0-cp310-cp310-macosx_11_0_arm64.whl CPython 3.10 CPython 3.10 macOS 11.0+ ARM64 Details for dfukit-2.1.0-cp310-cp310-macosx_11_0_arm64.whl
dfukit-2.1.0-cp310-cp310-macosx_10_14_x86_64.whl CPython 3.10 CPython 3.10 macOS 10.14+ x86-64 Details for dfukit-2.1.0-cp310-cp310-macosx_10_14_x86_64.whl

Total release size: 4.4 MB

Release files / dfukit-2.1.0.tar.gz

Download URL dfukit-2.1.0.tar.gz
Size 131.6 kB
Tags Source
SHA-256 checksum
How to use checksums
d5817022164915f6a952fbac6caf407d5667a521d7d0353a9855b789c2ee94c1
BLAKE2b-256 checksum
How to use checksums
fa8b60d77879670ebc2af4910e35e261d716bbdcc8cce2285e18a7aeeb21865d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 4, 2026.

Transparency log

Release files / dfukit-2.1.0-cp312-abi3-win_amd64.whl

Download URL dfukit-2.1.0-cp312-abi3-win_amd64.whl
Size 291.8 kB
Tags CPython 3.12 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
586268071d868f1082e95fc0913580508c4ce6252b953ba37845082f34d2a3da
BLAKE2b-256 checksum
How to use checksums
960c6a03ad78971b45d9d95a4995763d1dfa8ebb32781d78bd06b9256e23bf72
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 4, 2026.

Transparency log

Release files / dfukit-2.1.0-cp312-abi3-win32.whl

Download URL dfukit-2.1.0-cp312-abi3-win32.whl
Size 285.8 kB
Tags CPython 3.12 Windows x86-32 abi3
SHA-256 checksum
How to use checksums
f2b8261b265f6a16d2c8d6f7b5ae8adfd483ebc8c0a932a7e5c41b6777fcb6bd
BLAKE2b-256 checksum
How to use checksums
f384c4a86b9c55c38a1164d2a14b39df90d87cf22456ca8168f25ce2caa44337
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 4, 2026.

Transparency log

Release files / dfukit-2.1.0-cp312-abi3-musllinux_1_2_x86_64.whl

Download URL dfukit-2.1.0-cp312-abi3-musllinux_1_2_x86_64.whl
Size 567.2 kB
Tags CPython 3.12 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
f1a49f1973a55b0febf0badef6c678a8dc4c73e47f7fe01bee17603c524548fd
BLAKE2b-256 checksum
How to use checksums
072fff3a3e786f29afa51bb6ae10175079b1362aabbda9f913b1be282e2d259c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 4, 2026.

Transparency log

Release files / dfukit-2.1.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL dfukit-2.1.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 109.9 kB
Tags CPython 3.12 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
c1621e4c6740e40d7455f9a616302b42afa8c4503415c1facc6377ba86742e05
BLAKE2b-256 checksum
How to use checksums
002238382ef316a8ab3fb582bd3a77c4eda5cb552b39fbf4159410aa6f49b78c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 4, 2026.

Transparency log

Release files / dfukit-2.1.0-cp312-abi3-macosx_11_0_arm64.whl

Download URL dfukit-2.1.0-cp312-abi3-macosx_11_0_arm64.whl
Size 85.2 kB
Tags CPython 3.12 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
ec496d5572028a35114e026a330e39b8ac65c2cc34144dbe263b7a7d7916c26d
BLAKE2b-256 checksum
How to use checksums
4a9a08190a8cf343b9622d5620a8b76857ca0de9437446210c5f283b37b7bc62
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 4, 2026.

Transparency log

Release files / dfukit-2.1.0-cp312-abi3-macosx_10_14_x86_64.whl

Download URL dfukit-2.1.0-cp312-abi3-macosx_10_14_x86_64.whl
Size 89.4 kB
Tags CPython 3.12 abi3 macOS 10.14+ x86-64
SHA-256 checksum
How to use checksums
5edfa77e06a253d040e2704e14f088e26e95df8d55c7f257d8fb1927c447824d
BLAKE2b-256 checksum
How to use checksums
3e41f339892c65b6159b66c81f3e227a93b8d8268d881b62d4adc1ae4a12ebe5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 4, 2026.

Transparency log

Release files / dfukit-2.1.0-cp311-cp311-win_amd64.whl

Download URL dfukit-2.1.0-cp311-cp311-win_amd64.whl
Size 292.5 kB
Tags CPython 3.11 Windows x86-64
SHA-256 checksum
How to use checksums
7e9a371c2d34c89d64ad21cdf6b6a42fef8e60b29d203a30117153579c0ef954
BLAKE2b-256 checksum
How to use checksums
c97c3fd6c5dd3c6a5e547c824d596fa539d0e5b32cde484273c8e9bd97a4c14a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 4, 2026.

Transparency log

Release files / dfukit-2.1.0-cp311-cp311-win32.whl

Download URL dfukit-2.1.0-cp311-cp311-win32.whl
Size 286.7 kB
Tags CPython 3.11 Windows x86-32
SHA-256 checksum
How to use checksums
c79c2f7595222234d154fa9e6cec274cf9d9086306d72ff76814c0f482cc37b0
BLAKE2b-256 checksum
How to use checksums
28cd78f2013bbd04d196b2ba8622fe608768b2f99a6cbb2c8184a98a2d8221c8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 4, 2026.

Transparency log

Release files / dfukit-2.1.0-cp311-cp311-musllinux_1_2_x86_64.whl

Download URL dfukit-2.1.0-cp311-cp311-musllinux_1_2_x86_64.whl
Size 572.2 kB
Tags CPython 3.11 Linux musl 1.2+ x86-64
SHA-256 checksum
How to use checksums
45a70164d31ebb045e68b325235db67d69e9fe2422bb0eeb8b0ac116650f5292
BLAKE2b-256 checksum
How to use checksums
7c192a875e41739edda147bfb48944e6b729d926a86baeda7dcc1125dfd95474
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 4, 2026.

Transparency log

Release files / dfukit-2.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL dfukit-2.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 115.1 kB
Tags CPython 3.11 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
4ca855bb53330969b69796cac1e27ecb9264128fcb4506046a57c92c72318833
BLAKE2b-256 checksum
How to use checksums
a75d481f4d46d56d29b01c9ab947b4341b611a8c44c682ba51ac26626b117c71
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 4, 2026.

Transparency log

Release files / dfukit-2.1.0-cp311-cp311-macosx_11_0_arm64.whl

Download URL dfukit-2.1.0-cp311-cp311-macosx_11_0_arm64.whl
Size 87.2 kB
Tags CPython 3.11 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
18496c49fc8498887245b78ceb50bacdf1261b860b7c377b3cd9d7c9d20feb23
BLAKE2b-256 checksum
How to use checksums
6691bd47aaae7bef57026affef0d550564a102a480f4e520e73189d677a31f3d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 4, 2026.

Transparency log

Release files / dfukit-2.1.0-cp311-cp311-macosx_10_14_x86_64.whl

Download URL dfukit-2.1.0-cp311-cp311-macosx_10_14_x86_64.whl
Size 91.4 kB
Tags CPython 3.11 macOS 10.14+ x86-64
SHA-256 checksum
How to use checksums
03d58b2d91d56796f1ebabead186e633c19be941aef7591683ac37ccb0dec084
BLAKE2b-256 checksum
How to use checksums
8e8cc16423a54185d4ce2695db63af8a2b9f40029d836e27eacfdd437b0c1127
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 4, 2026.

Transparency log

Release files / dfukit-2.1.0-cp310-cp310-win_amd64.whl

Download URL dfukit-2.1.0-cp310-cp310-win_amd64.whl
Size 292.1 kB
Tags CPython 3.10 Windows x86-64
SHA-256 checksum
How to use checksums
02a439e9d89c7905d3cfc82d1cf7e7f164f56b6fddfee9580c1f4cf542d1c34b
BLAKE2b-256 checksum
How to use checksums
aa42c7a80491ea53f67790b95934a42b2c4ebed7d7bdf2603c1781d3c5ae178b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 4, 2026.

Transparency log

Release files / dfukit-2.1.0-cp310-cp310-win32.whl

Download URL dfukit-2.1.0-cp310-cp310-win32.whl
Size 286.5 kB
Tags CPython 3.10 Windows x86-32
SHA-256 checksum
How to use checksums
e2d21f2db6a2da0632d56c7fa48ac91d7ba04ce49aafaecc8da0bacd140a7418
BLAKE2b-256 checksum
How to use checksums
4cf9e3c8d7a11d092ef367a2c783b21ec0f14f37617e86f5931a892cbfaa71bb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 4, 2026.

Transparency log

Release files / dfukit-2.1.0-cp310-cp310-musllinux_1_2_x86_64.whl

Download URL dfukit-2.1.0-cp310-cp310-musllinux_1_2_x86_64.whl
Size 571.9 kB
Tags CPython 3.10 Linux musl 1.2+ x86-64
SHA-256 checksum
How to use checksums
ad9133744273016a9f1626952bd62fec95fbabaa0121bf8d7446ccd04cc42088
BLAKE2b-256 checksum
How to use checksums
ead2e894213681881d6e060f3ddeddd18b7b31e1f084fd99edfd5ccb4adef1b8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 4, 2026.

Transparency log

Release files / dfukit-2.1.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL dfukit-2.1.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 114.6 kB
Tags CPython 3.10 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
5d9465d5e99f68df25db415b000c4145d31f8a898bb61278b73ffb6e4a8cd058
BLAKE2b-256 checksum
How to use checksums
8e6b4eb2e58c36afa9532992ca7883e5e63efe3ea47f6c37ddb095097b87f5d8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 4, 2026.

Transparency log

Release files / dfukit-2.1.0-cp310-cp310-macosx_11_0_arm64.whl

Download URL dfukit-2.1.0-cp310-cp310-macosx_11_0_arm64.whl
Size 86.6 kB
Tags CPython 3.10 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
8719200bf5a403a7714580a11b7fa8cd75ecdcf7acf2f796e99ff56f843245f1
BLAKE2b-256 checksum
How to use checksums
c98e0c53e8bec3e549b8607f3077d46139b1b340e006f61047ad51af2070b6a4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 4, 2026.

Transparency log

Release files / dfukit-2.1.0-cp310-cp310-macosx_10_14_x86_64.whl

Download URL dfukit-2.1.0-cp310-cp310-macosx_10_14_x86_64.whl
Size 90.8 kB
Tags CPython 3.10 macOS 10.14+ x86-64
SHA-256 checksum
How to use checksums
cfaa8e7a354f93a3e194ddc57ea21300465f6b36dcc6423c92be84e72ea7c971
BLAKE2b-256 checksum
How to use checksums
62488055db646e9ad22f683a0dd8b2432f945ec201c5bf5bd98c0b8daf05161e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 4, 2026.

Transparency log

Security for dfukit 2.1.0

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.

Full provenance

All 19 files in this release have been uploaded with provenance metadata.

Select from 19 files

Attestation for dfukit-2.1.0.tar.gz

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 Nov 4, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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