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_log2a backend announces, else a stream compressed to that window fails at its CRC. beginruns inside theSTARTit 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.activateonly schedules the switch (a restart afterdelay_ms, from a timer or a task): the server answersACTIVATEwith what it returns, so it must return before restarting.finishmay returnDFUKIT_PENDINGwhile 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, andbeginmay 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)
| 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)
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 logRelease 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 logRelease 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 logRelease 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 logRelease 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 logRelease 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 logRelease 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 logRelease 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 logRelease 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 logRelease 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 logRelease 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 logRelease 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 logRelease 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 logRelease 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 logRelease 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 logRelease 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 logRelease 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 logRelease 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 logRelease 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 logSecurity 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.
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 logA 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.