mdfr
High-performance ASAM MDF (Measurement Data Format) 3.x and 4.x reader, writer, and embedded streaming logger in Rust.
mdfr provides fast, memory-efficient access to automotive measurement data across desktop analytics, server pipelines, and resource-constrained embedded targets.
Key Capabilities
- High-Performance Reader:
- Full support for ASAM MDF 3.x and 4.x (
.mdf,.mf4). - Multithreaded parallel parsing with Rayon and zero-copy data representation using Apache Arrow.
- Direct integration with Polars DataFrames and NumPy arrays.
- Exporters for Parquet, HDF5, and CSV.
- Full support for ASAM MDF 3.x and 4.x (
- Embedded MDF 4.3 Streaming Logger (
no_std + alloc):- Independent
mdfr-coresubcrate engineered for microcontrollers and RTOS environments (ARM Cortex-M4/M7/A). - High-throughput streaming with both
Sorted(independent DT/DZ blocks) andUnsorted(single interleaved stream) layouts. - Zero-copy hardware bus presets for CAN, CAN-FD, LIN, FlexRay, and Ethernet.
- Lock-free ISR interrupt logging via single-producer single-consumer ring buffer (
SpscRing). - Power-loss resilience: mid-record truncation repair and on-device in-place file recovery (
recover_in_place).
- Independent
- Compile-Time Struct Logging:
#[derive(MdfRecord)]procedural macro (mdfr-derive) to serialize custom Rust structs with automatic physical conversion and unit metadata.
- MDF 4.3 Variable-Length Channels (VLSC):
- First-class support for
cn_type = 7(Variable Length with companion Size Channel) across sortedVDBLOCKand unsortedCG_F_VLSCstreams.
- First-class support for
- Multilingual Support:
- Python bindings via PyO3 (
pip install mdfr). - Stable C FFI for desktop reading (
mdfr.h) and embedded logging (include/mdfr_logger.h).
- Python bindings via PyO3 (
Workspace Architecture
| Crate | Target / Environment | Description |
|---|---|---|
mdfr |
Desktop / Server (std) |
Full-featured crate with Arrow, Polars, Rayon, Parquet, HDF5, Python bindings, and CLI. |
mdfr-core |
Embedded / Bare-metal (no_std + alloc) |
Pure MDF 4.3 block model, Deflate/LZ4 codecs, static arena allocator, and streaming logger engine. |
mdfr-derive |
Proc-Macro | #[derive(MdfRecord)] for compile-time record layout and zero-overhead serialization. |
Python Usage
Install from PyPI:
pip install mdfr
Reading Files and Polars Integration
import mdfr
# Load MDF 3 or 4 file metadata
obj = mdfr.Mdfr("measurement.mf4")
# Load all channels into memory (Arrow-backed)
obj.load_all_channels_data_in_memory()
# Or load a selective subset for low memory footprint
obj.load_channels_data_in_memory({"EngineSpeed", "VehicleSpeed"})
# Retrieve numpy array
speed = obj.get_channel_data("VehicleSpeed")
# Retrieve Polars Series or complete DataFrame grouped by master channel
series = obj.get_polars_series("VehicleSpeed")
df = obj.get_polars_dataframe("VehicleSpeed")
# Export to other analytical formats
obj.export_to_parquet("output.parquet", compression="snappy")
obj.export_to_hdf5("output.h5")
obj.export_to_csv("output.csv")
Streaming Logger (Python)
import mdfr
# Configure a streaming logger
builder = mdfr.MdfLogger(layout="sorted", compression="lz4")
g_vehicle = builder.add_group("Vehicle")
ch_speed = builder.add_channel(g_vehicle, "Speed", "float", 64)
builder.set_channel_unit(ch_speed, "km/h")
logger = builder.start("streamed_log.mf4")
for i in range(100):
logger.begin_record(g_vehicle)
logger.set_f64(ch_speed, 50.0 + i * 0.5)
logger.commit()
logger.close()
Rust Usage
1. Analytical Desktop Reader (mdfr with Polars)
[dependencies]
mdfr = { version = "0.8", features = ["polars", "parquet"] }
use mdfr::mdfreader::Mdf;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut mdf = Mdf::new("measurement.mf4")?;
mdf.load_all_channels_data_in_memory()?;
// Extract Polars DataFrame grouped by master channel
let df = mdf.get_channel_polars_dataframe(Some("Time"))?;
println!("{df}");
// Export to Parquet
mdf.export_to_parquet("measurement.parquet", mdfr::export::parquet::CompressionOption::Snappy)?;
Ok(())
}
2. Embedded Streaming Logger (mdfr-core + mdfr-derive)
[dependencies]
mdfr-core = { version = "0.8", default-features = false, features = ["lz4", "derive"] }
use mdfr_core::logger::{CompressionAlgorithm, DataLayout, Logger, LoggerBuilder};
use mdfr_core::time::ManualClock;
use mdfr_core::MdfRecord;
#[derive(MdfRecord)]
#[mdf(group = "Powertrain")]
struct PowertrainFrame {
#[mdf(name = "RPM", unit = "rpm", linear(0.0, 0.25))]
rpm_raw: u16,
#[mdf(name = "Torque", unit = "Nm", rational(0.0, 0.5, -100.0, 0.0, 0.0, 1.0))]
torque_raw: i16,
#[mdf(name = "Throttle", unit = "%")]
throttle: f32,
#[mdf(name = "FaultActive")]
fault: bool,
}
fn main() -> Result<(), Box<dyn core::error::Error>> {
let mut builder = LoggerBuilder::new(DataLayout::Sorted, CompressionAlgorithm::Lz4Transpose);
let g_pt = builder.add_record_group::<PowertrainFrame>()?;
let schema = builder.build()?;
let file = std::fs::File::create("log.mf4")?;
let clock = ManualClock::new(0.001, 1); // 1 ms resolution
let mut logger = Logger::start(schema, file, clock)?;
let sample = PowertrainFrame {
rpm_raw: 3200, // phys: 800 rpm
torque_raw: 400, // phys: 100 Nm
throttle: 25.0,
fault: false,
};
// Zero-overhead push
logger.push_record(g_pt, &sample)?;
logger.close()?;
Ok(())
}
3. In-Place Power-Loss Recovery
In embedded applications, unexpected power cut before logger.close() leaves the MDF 4.3 header unfinalized. recover_in_place repairs the file directly on the storage device:
let mut file = std::fs::OpenOptions::new().read(true).write(true).open("log.mf4")?;
let recovered_samples = mdfr_core::logger::recover_in_place(&mut file)?;
println!("Repaired {recovered_samples} records in-place without data loss.");
C / C++ Embedded ABI (include/mdfr_logger.h)
mdfr-core exposes a clean, non-panicking C API using function-pointer vtables for I/O (mdfr_sink_t) and timer clocks (mdfr_clock_t), suitable for FatFs, LittleFS, POSIX, or bare-metal ring buffers:
#include "mdfr_logger.h"
// Define storage vtable (e.g. FatFs f_write / f_lseek)
mdfr_sink_t sink = { .ctx = &fil, .write = my_write, .seek = my_seek, .flush = NULL, .close = NULL };
mdfr_clock_t clock = { .ctx = NULL, .now_ticks = get_ticks, .tick_ns = 1000000, .wall_clock_ns = NULL };
mdfr_builder_t* b = mdfr_logger_builder_new(MDFR_LAYOUT_SORTED, MDFR_COMPRESS_LZ4_TRANSPOSE);
uint16_t group = 0;
mdfr_logger_add_group(b, "CAN_Raw", &group);
mdfr_logger_t* logger = NULL;
mdfr_logger_start(b, sink, clock, &logger);
// Push raw hardware-timestamped bus frame
uint8_t payload[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
mdfr_logger_push_raw_at(logger, group, get_hardware_timer(), payload, sizeof(payload));
mdfr_logger_close(logger);
Cargo Features
mdfr (Desktop)
default = ["numpy", "parquet", "polars", "cli"]polars: High-performance Polars DataFrame integration.parquet: Apache Parquet exporter.hdf5: HDF5 exporter (rust-hdf5).numpy: NumPy array conversion via PyO3.cli: Command-line executable (mdfr).
mdfr-core (Embedded)
default = ["deflate", "lz4", "derive"]deflate: Pure Rust Miniz-Oxide Deflate compression (no_std + alloc).lz4: Pure Rust LZ4 compression (no_std + alloc).derive: Proc-macro#[derive(MdfRecord)]integration.capi-arena: Zero-fragmentationStaticArenabare-metal memory allocator.defmt: Implementsdefmt::Formatfor embedded logging.
License
GPL-3.0 License.
Metadata
Release files for mdfr 0.8.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
Total release size: 87.4 MB
Release files / mdfr-0.8.0-cp314-cp314-win_amd64.whl
| Download URL | mdfr-0.8.0-cp314-cp314-win_amd64.whl |
|---|---|
| Size | 4.3 MB |
| Tags | CPython 3.14 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
09c2d4c4119615886de14aefbd057720dc07d8153565ba777cdc79599b55a102
|
|
BLAKE2b-256 checksum How to use checksums |
e1e9897061f2f4f229a78922b6a42f63d7c6b97dc49d803a6b60ee0302f06263
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Release files / mdfr-0.8.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | mdfr-0.8.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 4.6 MB |
| Tags | CPython 3.14 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
001949054ee2b8e10a69ac5fa03d8f40d41a6f4925b4b6edfb334f057614b290
|
|
BLAKE2b-256 checksum How to use checksums |
86165f0b6614fbf605b91b2ec24cde0fc0c7273d61ef0adbfa12c97e62cb3821
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Release files / mdfr-0.8.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | mdfr-0.8.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 4.4 MB |
| Tags | CPython 3.14 Linux glibc 2.17+ ARM64 |
|
SHA-256 checksum How to use checksums |
c6907e640a7902d6360cb6d80ab30337f605675cab47380ce00c4593e5a771f0
|
|
BLAKE2b-256 checksum How to use checksums |
06cd637262da06f4a40b760fb7466b391dfe3d2225340ab7eaacd5e3ab4da98a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Release files / mdfr-0.8.0-cp314-cp314-macosx_11_0_arm64.whl
| Download URL | mdfr-0.8.0-cp314-cp314-macosx_11_0_arm64.whl |
|---|---|
| Size | 4.1 MB |
| Tags | CPython 3.14 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
c464843a745e53f3dc6c26ae1426a8fc8c3020717e79eec561f365e6464b9e46
|
|
BLAKE2b-256 checksum How to use checksums |
982ee0d35142390e3b1e434314fd230ac5b076fd8fbfb1395a6178e92a2d471b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Release files / mdfr-0.8.0-cp313-cp313-win_amd64.whl
| Download URL | mdfr-0.8.0-cp313-cp313-win_amd64.whl |
|---|---|
| Size | 4.3 MB |
| Tags | CPython 3.13 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
9fe18a3cb3a3e0cc5b75ae6ae044d4b5abe123a7b32b672d4cad081d0475b966
|
|
BLAKE2b-256 checksum How to use checksums |
4fac270baa9a48f75d8878e9acdadd41f66f7a3cfe7e90d532af34f6bb78ef69
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Release files / mdfr-0.8.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | mdfr-0.8.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 4.6 MB |
| Tags | CPython 3.13 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
7afff1e034076f6115d8eb1b895fd7021e12a88a327d2a1e6eb2bac900bad816
|
|
BLAKE2b-256 checksum How to use checksums |
7262d729155908ca48121d955ffb37da251ae2000c7e87c8f95b6dd82dfc9708
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Release files / mdfr-0.8.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | mdfr-0.8.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 4.4 MB |
| Tags | CPython 3.13 Linux glibc 2.17+ ARM64 |
|
SHA-256 checksum How to use checksums |
b97c692be023b7754a98ee43cefdcb9c6764af9fdee59807d7b69a1142472120
|
|
BLAKE2b-256 checksum How to use checksums |
17c3c0abb17ea92efaff165e7e45e26b937d1cc724d426d31dbefe5b9ee0aa4a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Release files / mdfr-0.8.0-cp313-cp313-macosx_11_0_arm64.whl
| Download URL | mdfr-0.8.0-cp313-cp313-macosx_11_0_arm64.whl |
|---|---|
| Size | 4.1 MB |
| Tags | CPython 3.13 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
1c08ce00659143fca1428e9396d429191ce4fb916800cee7b9e4ba4a9e78ca3a
|
|
BLAKE2b-256 checksum How to use checksums |
8b389d3efc46ac0a07ba4a68ad79d9c057904b10c3bb18a419081d74a4ddec55
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Release files / mdfr-0.8.0-cp312-cp312-win_amd64.whl
| Download URL | mdfr-0.8.0-cp312-cp312-win_amd64.whl |
|---|---|
| Size | 4.3 MB |
| Tags | CPython 3.12 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
220736a81d38359e4da822015719d70ada49ce5f08dd39010f69228f091cdd01
|
|
BLAKE2b-256 checksum How to use checksums |
a889a27ddabe01bd104fd48a68fda3be4bafadc25d48709a2d0dbf9282179e3e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Release files / mdfr-0.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | mdfr-0.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 4.6 MB |
| Tags | CPython 3.12 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
da50c5eaba54ccb52b658177c3c9958b04e784feb72cff4a02f5938857ce15bd
|
|
BLAKE2b-256 checksum How to use checksums |
c9d281086d5cfe1be9fdf0c772c750b1b1c1b2a10400a4c1f665d4630914fb39
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Release files / mdfr-0.8.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | mdfr-0.8.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 4.4 MB |
| Tags | CPython 3.12 Linux glibc 2.17+ ARM64 |
|
SHA-256 checksum How to use checksums |
aba4c30ba6159ac7f92175391083b6f131345ef3def6e9c4c7607561928ad55f
|
|
BLAKE2b-256 checksum How to use checksums |
1e0ad4e9a6bdbe203988c19d3b7030f9ed42fc8437f950dc1563a30ce54b353f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Release files / mdfr-0.8.0-cp312-cp312-macosx_11_0_arm64.whl
| Download URL | mdfr-0.8.0-cp312-cp312-macosx_11_0_arm64.whl |
|---|---|
| Size | 4.1 MB |
| Tags | CPython 3.12 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
9068648ede0b8250b647ab6b3e125c4f0f621959c6fd52d62d21aadc084d198e
|
|
BLAKE2b-256 checksum How to use checksums |
f4c5dc9b124a5ae6bbddae26e8856596eeef0e437f2b9a55c8eb2bf325962fa1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Release files / mdfr-0.8.0-cp311-cp311-win_amd64.whl
| Download URL | mdfr-0.8.0-cp311-cp311-win_amd64.whl |
|---|---|
| Size | 4.3 MB |
| Tags | CPython 3.11 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
726f5571d01fb9e506dab391ff15a7ecbf87af272c0923bc1297551ce7608d19
|
|
BLAKE2b-256 checksum How to use checksums |
68b2b192af0afcfc634bd7170b6b850f5b850123331e3c654ae62de6816b6ebb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Release files / mdfr-0.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | mdfr-0.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 4.6 MB |
| Tags | CPython 3.11 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
4ad1bf5e2a9c20fa9d09c1288b39fc237f82dbecb6f2776347e0de453a9b66d8
|
|
BLAKE2b-256 checksum How to use checksums |
15f31eb7a6059f9ade7e5c0c143234ab3fc01c87ef6a68c7356dc8a58fca8894
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Release files / mdfr-0.8.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | mdfr-0.8.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 4.4 MB |
| Tags | CPython 3.11 Linux glibc 2.17+ ARM64 |
|
SHA-256 checksum How to use checksums |
fa75f97c03584878e1e2117ccf48f29e76d74577862e413732777d77076c80e1
|
|
BLAKE2b-256 checksum How to use checksums |
668ab09b60ccc4e7dac7453e7c5b57d1ed6c5160c1ad6c6461ed0043efdc4e85
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Release files / mdfr-0.8.0-cp311-cp311-macosx_11_0_arm64.whl
| Download URL | mdfr-0.8.0-cp311-cp311-macosx_11_0_arm64.whl |
|---|---|
| Size | 4.1 MB |
| Tags | CPython 3.11 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
b9016e08c1669f6d6f042057f73ca5e0183044f62ff47fda4e04e1a41ac012da
|
|
BLAKE2b-256 checksum How to use checksums |
0577dfeed6e1587f210521456058ec7e2198bedd1f47f08dc4a387590377f901
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Release files / mdfr-0.8.0-cp310-cp310-win_amd64.whl
| Download URL | mdfr-0.8.0-cp310-cp310-win_amd64.whl |
|---|---|
| Size | 4.3 MB |
| Tags | CPython 3.10 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
0c5703f6ebc8c2fde85cf1c5d13c560334775206796b761f2335b26a222e6614
|
|
BLAKE2b-256 checksum How to use checksums |
172f7e7cf441086bdf86adf0f438592365e78fde09346fd10c32728198016b30
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Release files / mdfr-0.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | mdfr-0.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 4.6 MB |
| Tags | CPython 3.10 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
52f66257c0948ff50a915efe68b4aa085eeeb9606732295a5234784371ccd443
|
|
BLAKE2b-256 checksum How to use checksums |
8889e47c69e31067f4237ea4f16bd49325c409bba1d4ac55d130ebcd7d02bb4c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Release files / mdfr-0.8.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | mdfr-0.8.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 4.4 MB |
| Tags | CPython 3.10 Linux glibc 2.17+ ARM64 |
|
SHA-256 checksum How to use checksums |
c3de26b0e2375f058ca3b8e625759232baa66a0509f3b8e6cbd92af9c21ff192
|
|
BLAKE2b-256 checksum How to use checksums |
52af2e0a42a3df170cd84f0f4364cac28636422dfa8281e65f5f97ea31b36bfd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Release files / mdfr-0.8.0-cp310-cp310-macosx_11_0_arm64.whl
| Download URL | mdfr-0.8.0-cp310-cp310-macosx_11_0_arm64.whl |
|---|---|
| Size | 4.1 MB |
| Tags | CPython 3.10 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
66d7464a727541cefce721be180e9d07102ca0891f63dccd4ac2a18dd3f99cac
|
|
BLAKE2b-256 checksum How to use checksums |
71b01a4f43ef22312fbb2172b1dccd68956230e4e33f04744c5b85e4dc7559cf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Security for mdfr 0.8.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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
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.