Metadata-Version: 2.4
Name: pymfx
Version: 1.0.0
Summary: Python library for the Mission Flight Exchange (.mfx) v1.0 format
Author: pymfx contributors
License: Creative Commons Attribution 4.0 International (CC BY 4.0)
        
        Copyright (c) 2026 pymfx contributors
        
        You are free to:
          Share — copy and redistribute the material in any medium or format
          Adapt — remix, transform, and build upon the material for any purpose, even commercially.
        
        Under the following terms:
          Attribution — You must give appropriate credit, provide a link to the license,
          and indicate if changes were made.
        
        Full license text: https://creativecommons.org/licenses/by/4.0/legalcode
        
Project-URL: Homepage, https://github.com/jabahm/pymfx
Project-URL: Documentation, https://github.com/jabahm/pymfx
Project-URL: Repository, https://github.com/jabahm/pymfx
Project-URL: Changelog, https://github.com/jabahm/pymfx/blob/main/CHANGELOG.md
Project-URL: Bug Tracker, https://github.com/jabahm/pymfx/issues
Keywords: uav,drone,mfx,mission,flight,FAIR,UAV,remote-sensing
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Developers
Classifier: Topic :: Scientific/Engineering :: GIS
Classifier: Topic :: Scientific/Engineering :: Information Analysis
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Operating System :: OS Independent
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: viz
Requires-Dist: folium>=0.14; extra == "viz"
Requires-Dist: matplotlib>=3.7; extra == "viz"
Provides-Extra: notebooks
Requires-Dist: jupyter>=1.0; extra == "notebooks"
Requires-Dist: ipykernel>=6.0; extra == "notebooks"
Requires-Dist: folium>=0.14; extra == "notebooks"
Requires-Dist: matplotlib>=3.7; extra == "notebooks"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: ruff>=0.4; extra == "dev"
Requires-Dist: mypy>=1.8; extra == "dev"
Requires-Dist: build>=1.0; extra == "dev"
Requires-Dist: twine>=5.0; extra == "dev"
Requires-Dist: folium>=0.14; extra == "dev"
Requires-Dist: matplotlib>=3.7; extra == "dev"
Dynamic: license-file

# pymfx

Python reference library for the **Mission Flight Exchange** (`.mfx`) v1.0 format.

> `.mfx` is an open, text-based, self-describing format for encapsulating UAV mission data in a single file.  
> It is to drone missions what GPX is to GPS tracks: a minimal, immediately adoptable, community-extensible standard.

---

## Installation

```bash
pip install pymfx
```

Or from source:

```bash
git clone https://github.com/jabahm/pymfx
cd pymfx
pip install -e .
```

**Requirements:** Python ≥ 3.10, no external dependencies.

---

## Quick start

```python
import pymfx

# Read a file
mfx = pymfx.parse("mission.mfx")

print(mfx.meta.drone_id)            # "Parrot-Anafi-SN987654"
print(mfx.meta.date_start)          # "2026-03-16T08:30:00Z"
print(len(mfx.trajectory.points))   # 3

for point in mfx.trajectory.points:
    print(point.t, point.lat, point.lon, point.alt_m)

# Validate
result = pymfx.validate(mfx)
if result.is_valid:
    print("✓ Valid file")
else:
    for issue in result.issues:
        print(issue)

# Write (checksums are auto-computed)
mfx.meta.contact = "new@lab.fr"
pymfx.write(mfx, "mission_v2.mfx")
```

---

## CLI

```bash
# Validate a file (rules V01–V21)
pymfx --validate mission.mfx

# Compute and verify SHA-256 checksums
pymfx --checksum mission.mfx

# Print a summary
pymfx --info mission.mfx
```

---

## Notebooks

Two Jupyter notebooks are included in `notebooks/`:

| Notebook | Description |
|---|---|
| `01_quickstart.ipynb` | Parse, inspect, validate and write a .mfx file step by step |
| `02_build_from_scratch.ipynb` | Build a complete .mfx file from raw Python data |

To run them:

```bash
pip install jupyter
jupyter notebook notebooks/
```

---

## Validation rules

The validator implements all 21 rules from the `.mfx` v1.0 spec:

| ID | Severity | Description |
|----|----------|-------------|
| V01 | Error | Valid @mfx version |
| V02 | Error | [trajectory] checksum correct |
| V03 | Error | [events] checksum correct |
| V04 | Error | [meta] present and in first position |
| V05 | Error | [trajectory] present |
| V06 | Error | date_end present and after date_start if status=complete |
| V07 | Error | t strictly increasing, max 3 decimal places |
| V08 | Error | Field types conform to the defined vocabulary |
| V09 | Error | Number of values per row equals number of schema fields |
| V10 | Error | [no_null] fields do not contain `-` |
| V11 | Warning | [range] constraints respected |
| V12 | Warning | [enum] constraints respected |
| V13 | Warning | Extension sections prefixed with `x_` |
| V14 | Warning | frequency_hz ≥ 1 |
| V15 | Warning | duration_s consistent with date_end − date_start (±5s) |
| V16 | Warning | id is a valid RFC 4122 UUID |
| V17 | Warning | bbox contains all [trajectory] points |
| V18 | Warning | Gap between declared and measured frequency_hz ≤ 20% |
| V19 | Warning | anomalies in [index] matches actual count |
| V20 | Warning | source_format_detail present if source_format=other |
| V21 | Warning | [index] is the last section |

---

## Package structure

```
pymfx/
├── pymfx/
│   ├── __init__.py      Public API
│   ├── models.py        Dataclasses (MfxFile, Meta, Trajectory, ...)
│   ├── parser.py        Read .mfx → Python objects
│   ├── writer.py        Python objects → .mfx
│   ├── validator.py     Rules V01–V21
│   ├── checksum.py      SHA-256 per spec
│   └── cli.py           CLI interface
├── notebooks/
│   ├── 01_quickstart.ipynb
│   └── 02_build_from_scratch.ipynb
└── tests/
    ├── example_minimal.mfx
    ├── test_parser.py
    ├── test_writer.py
    └── test_validator.py
```

---

## License

CC BY 4.0 — See the `.mfx` v1.0 specification for details.

**Format spec:** `mfx_spec_v1.0_final.md`  
**MIME type:** `application/x-mfx`  
**Reference implementation:** `pymfx` — `github.com/jabahm/pymfx`
