pfmg — Python Flatpak Module Generator
A modern, probe-first replacement for flatpak-pip-generator.
Instead of resolving dependencies statically on the host, pfmg installs the package inside a real Flatpak build sandbox, runs ldd on every compiled extension, checks pkg-config, and tests the import. The result is a Flatpak module JSON that you can drop directly into your manifest — with native dependency errors caught before you ever run flatpak-builder.
Requirements
- Python 3.11+
flatpakinstalled on the host (forgenerateandinspect)pip3oruvavailable on the host (for source collection)
Installation
pip install pfmg
How it works
pfmg generate numpy
│
├─ 1. Install package inside org.freedesktop.Sdk sandbox
├─ 2. Run ldd on every .so file → detect missing native libs
├─ 3. Run pkg-config on declared deps → detect missing headers / pc files
├─ 4. Test the Python import
├─ 5. Build-test the generated module (flatpak-builder dry run)
│ └─ if a build dep is missing and resolvable on PyPI → probe it
│ and retry automatically (up to 5 times)
└─ 6. Write module JSON
Errors are matched against a local dataset of SDK profiles, extension profiles, and ready-to-use recipes, so you get actionable suggestions ("add org.freedesktop.Sdk.Extension.rust-stable") instead of raw linker output.
The local dataset
pfmg ships with — and continuously grows — a dataset of:
| Directory | Contents |
|---|---|
data/sdk-profiles/ |
Profiles of base SDKs (libraries, pkgconfig, executables) |
data/ext-profiles/ |
Profiles of SDK extensions |
data/nat-recipes/ |
Ready-to-use Flatpak module JSON for native libraries (zlib, openssl, …) |
data/pip-recipes/ |
Ready-to-use module JSON for Python packages with known native deps |
When pfmg generate encounters an error it queries this dataset and suggests concrete actions: which SDK extension to add, which recipe to prepend to the manifest, or which --build-dep flag to pass.
Use pfmg import, pfmg inspect, and pfmg inspect-all to grow the dataset for your own extensions or SDK versions.
Commands
pfmg generate
Probe one or more Python packages and generate Flatpak module JSON files.
pfmg generate <package> [<package> ...] [OPTIONS]
| Option | Default | Description |
|---|---|---|
--sdk, -s |
org.freedesktop.Sdk |
Base SDK to use |
--runtime |
org.freedesktop.Platform |
Runtime ID |
--sdk-version, -V |
24.08 |
SDK branch |
--extension, -e |
— | SDK extension to activate (repeatable) |
--build-dep, -b |
— | Explicit build-time PyPI dep (repeatable) |
--output-dir, -o |
— | Directory to write module JSON files |
--format, -f |
json |
Output format: json or yaml |
--uv / --pip |
--uv |
Package installer to use inside the sandbox |
--keep |
off | Keep the sandbox work directory after probing |
--raw-output, -r |
off | Print raw sandbox stdout/stderr |
--verbose, -v |
off | Enable debug logging |
Examples:
# Simplest case — latest numpy
pfmg generate numpy
# Pin a version, save the result
pfmg generate numpy==1.26.4 --output-dir ./modules
# Package that needs the Rust toolchain
pfmg generate cryptography \
--extension org.freedesktop.Sdk.Extension.rust-stable \
--output-dir ./modules
# Several packages at once on SDK 24.08
pfmg generate pillow lxml --sdk-version 24.08 --output-dir ./modules
# Manually hint a build-time dep (pfmg tries to auto-resolve these,
# but you can be explicit)
pfmg generate some-package --build-dep meson-python --build-dep ninja
When --output-dir is omitted the module JSON is printed to stdout. If pfmg detects errors it prints a resolution table with suggestions from the local dataset.
pfmg search
Search the local dataset for a library, package name, or executable.
pfmg search <query> [OPTIONS]
| Option | Default | Description |
|---|---|---|
--kind, -k |
all | Filter: nat, pip, sdk, ext |
--module, -m |
off | Print the full module JSON for matching recipes |
pfmg search openssl
pfmg search numpy --kind pip
pfmg search libz --kind nat
pfmg search clang --kind ext --module
Searches SDK profiles, extension profiles, nat-recipes, and pip-recipes using the same fuzzy matching as the error resolver.
pfmg list
List all entries in the local dataset.
pfmg list [OPTIONS]
| Option | Default | Description |
|---|---|---|
--kind, -k |
all | Filter: nat, pip, sdk, ext |
--limit, -n |
50 |
Maximum rows per table |
pfmg list
pfmg list --kind nat
pfmg list --kind pip --limit 100
pfmg show
Show the full content of a recipe by its exact ID.
pfmg show <recipe-id> [OPTIONS]
| Option | Default | Description |
|---|---|---|
--kind, -k |
both | Restrict to nat or pip |
pfmg show zlib
pfmg show numpy --kind pip
pfmg summarize
Print counts of recipes and profiles in the local dataset.
pfmg summarize
pfmg inspect
Introspect a Flatpak SDK or extension and write a static profile JSON to the local dataset. Profiles are used by the resolver to match errors against known providers.
pfmg inspect <sdk-or-extension-id> [OPTIONS]
| Option | Default | Description |
|---|---|---|
--sdk-branch, -B |
25.08 |
Branch of the base SDK |
--ext-branch, -X |
— | Branch of the extension when it differs from --sdk-branch |
--output-dir, -o |
— | Override the default profile output directory |
--nocleanup |
off | Don't uninstall the extension after probing |
--override |
off | Re-probe and overwrite an existing profile |
pfmg auto-detects whether the target is a base SDK or an extension by looking for .Extension. in the ID.
Examples:
# Base SDK
pfmg inspect org.freedesktop.Sdk --sdk-branch 24.08
# Extension on the same branch as the SDK
pfmg inspect org.freedesktop.Sdk.Extension.node24 --sdk-branch 25.08
# Extension with its own branch
pfmg inspect org.freedesktop.Sdk.Extension.gcc8 --sdk-branch 24.08 --ext-branch 1.6
Profiles are written to:
data/sdk-profiles/<shortname>.<branch>.json # base SDKs
data/ext-profiles/<shortname>.<branch>.json # extensions
pfmg inspect-all
Discover every extension available on a Flatpak remote for the given SDK branches and probe them all.
pfmg inspect-all [OPTIONS]
| Option | Default | Description |
|---|---|---|
--sdk-branch, -B |
24.08, 25.08 |
Branches to probe (repeatable) |
--remote, -r |
flathub |
Flatpak remote to query |
--output-dir, -o |
— | Override profile output directory |
--nocleanup |
off | Don't uninstall extensions after probing |
--override |
off | Re-probe profiles that already exist |
Intended to be run once a year when a new SDK generation ships:
# Update profiles for the two current branches
pfmg inspect-all
# When 26.08 ships
pfmg inspect-all -B 25.08 -B 26.08
Extensions whose profile already exists are skipped unless --override is given.
pfmg import
Import native library and Python recipes from a shared-modules directory (e.g. a checkout of flathub/shared-modules).
pfmg import <modules-dir> [OPTIONS]
| Option | Default | Description |
|---|---|---|
--repo-root, -r |
. |
Root of the pfmg repository |
--verbose, -v |
off | Enable debug logging |
pfmg import ~/src/shared-modules
Metadata
Release files for pfmg 0.8.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 |
|---|---|---|---|---|
| pfmg-0.8.0.tar.gz | 78.4 kB | Without provenance | Details for pfmg-0.8.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pfmg-0.8.0-py3-none-any.whl | Python 3 | none | any | Details for pfmg-0.8.0-py3-none-any.whl |
Total release size: 167.0 kB
Release files / pfmg-0.8.0.tar.gz
| Download URL | pfmg-0.8.0.tar.gz |
|---|---|
| Size | 78.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
47bc57e37513171f5fe780adc738b3afcf94a2583b6b821147aba4b215d16673
|
|
BLAKE2b-256 checksum How to use checksums |
29596a7ebcadef7831aba4f7a9bec71bdb14f3e1d5ab5cbee3ccc6a8f9393da2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.4
|
Release files / pfmg-0.8.0-py3-none-any.whl
| Download URL | pfmg-0.8.0-py3-none-any.whl |
|---|---|
| Size | 88.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
17cf20b772038c36da8b5f8c30e9a2e927bba5b61faa8a24d1c5bc355c3f91d9
|
|
BLAKE2b-256 checksum How to use checksums |
a6bca18a1115b495f6b7b44ec91a0b38d2a3654a25f20a08df78a4622d37ec4e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.4
|
Security for pfmg 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.