# Py2Native
A Python-to-native compiler that compiles your proprietary Python files to C via Cython,
then links them into a single native executable (or shared library). All libraries
are kept as they are (eg plain Python) inside a managed `uv` environment — only your code is compiled.
## Links
- [llms-full.txt](llms-full.txt) — complete documentation of the published interfaces (CLI, runtime API, build artifacts, HTTP API)
## Product tiers
| Tier | Package | License | Key differences |
|------------|-----------------|------------|-----------------------------------------------|
| Community | `py2native` | MIT | Full compilation, `uv` embedding, cross-platform |
| Pro | `py2nativepro` | Proprietary| JWT license verification, string compression |
## Repository layout
```
py2native/
├── py2native/ # Open-source compiler (MIT)
│ ├── pyproject.toml
│ ├── README.md
│ └── src/py2native/
│ ├── cli.py # CLI entry point: `py2native build ...`
│ ├── build.py # Build orchestrator (glob sources, call compiler/embed/whl)
│ ├── compiler.py # Cython invocation, C compilation, linking
│ ├── embed.py # --embed: creates uv-managed deployment directory
│ ├── whl.py # --wheel: creates PEP 427 wheel with compiled .pyd/.so
│ ├── templates.py # Cython bootstrap/header templates (code generation)
│ ├── plugin.py # PluginManager: dispatches to platform + pro plugins
│ ├── runtime.py # Locates CPython shared library for linking
│ ├── pristine.py # Manages pristine Python venv for compilation
│ ├── utils.py # Shared utilities (getBuildPath, pythonCall, template)
│ ├── winplatform.py # Windows: compiler flags, PE linking, .pyd naming
│ ├── linuxplatform.py # Linux: ELF linking, auditwheel repair, .so naming
│ └── macplatform.py # macOS: Mach-O linking, .dylib naming
│
├── py2nativetest/ # Test project showing Pro Edition features
├── smoketest.py # Build with smoke test
```
## Architecture
### Compilation pipeline
```
uv run py2native build main.py *.py [--library] [--embed
] [--wheel ]
```
1. **Glob sources** — `build.py` expands glob patterns under `--base`
2. **Plugin dispatch** — `pluginManager.extendBuild(args)` runs Pro license checks
3. **Cython → C** — `compiler.py` generates a `bootstrap.pyx` from `templates.py`,
invokes Cython (`--embed --shared --embed-modules`), then compiles all `.pyx` files to C
4. **C → objects** — `getCompiler()` (setuptools distutils) compiles `.c` files with platform flags
5. **Link** — `link_shared_object()` for library mode, `link_executable()` for exe mode
6. **Wheel (optional)** — `whl.py` creates a PEP 427 wheel with the compiled `.pyd`/`.so`
7. **Embed (optional)** — `embed.py` creates a `uv`-managed deployment directory
### Library mode (`--library`)
Creates a shared library (`.pyd`/`.so`/`.dylib`) instead of an executable. The output wheel
contains:
- A single compiled shared library (contains all modules)
- `__init__.py` — meta-path finder that redirects `import mypkg.submodule` to the shared lib
- `__main__.py` — enables `python -m mypkg`
Both files are **required**: `__init__.py` bridges Python's import system to the native
library; `__main__.py` provides the runnable entry point.
### Plugin system
`pluginManager` (`plugin.py`) dynamically loads plugins by module name:
| Plugin module | Role |
|--------------------|-------------------------------------------|
| `py2nativepro` | JWT license verification, string compression, keygen/sign/show CLI commands |
| `.winplatform` | Windows-specific compile/link flags |
| `.linuxplatform` | Linux-specific compile/link flags, auditwheel repair |
| `.macplatform` | macOS-specific compile/link flags |
Plugins extend the build through lifecycle hooks: `extendBuildParser()`, `extendBuild()`,
`extendCompiler()`, `extendTemplate()`, `getCompileLibArgs()`, `getLinkerArgs()`,
`getExecutableName()`, `getRuntimeLibraries()`, `auditWheel()`.
### Pro plugin (`py2nativepro`)
The closed-source Pro plugin adds:
- **`uv run py2native keygen`** — generates EC P-256 keypair (`private.pem`, `public.pem`)
- **`uv run py2native sign`** — signs a JWT payload with the private key → `license.dat`
- **`uv run py2native show`** — displays JWT claims (optionally verifies signature against public key)
- **`--license`** flag on `build` — requires a valid Pro license (JWT, searched in: CLI flag → `PY2NATIVE_LICENSE` env → `~/.py2native/license.dat`)
- **`--public`** flag on `build` — embeds a PEM public key into the compiled binary for runtime JWT verification via the `py2native_runtime` API
- **String compression** — sets `CYTHON_COMPRESS_STRINGS=90`, making string literals less readable in the compiled binary
License verification at build time: decodes the JWT payload, checks `withRuntimeJwt` and
`withStringCompression` claims, and enables corresponding features.
### Runtime API
Include a .pxd file (with the same name as the module you are checking the jwt)
````
# .pxd
from _p2n_bootstrap cimport _runtime_verify_es256_jwt
````
And in module:
````
# Decode licenseString (JWT) to dict
try:
# Handle verification with embedded key
license = _runtime_verify_es256_jwt(licenseString, issue, aaudience)
except NameError:
# Handle dummy verification (json.loads) when software is not compiled
import base64
import json
license = json.loads(base64.b64decode(licenseString.split(".")[1]+"==="))
````
* Your code can verify the license end adapt its operation accordingly
## Notes:
* Only the public key is stored in the executable
* The elliptic key verification is handled with compiled code in our software
(ie no 3rd party libraries)
## CLI reference
```
uv run py2native build [--embed ] [--wheel ] [--library]
[--base ] [--no-console]
[--license ] [--public ]
...
uv run py2native keygen # Pro only
uv run py2native sign --private # Pro only
uv run py2native show [--public ] # Pro only
```
## Requirements
- CPython 3.11–3.15 (including free-threaded 3.14t & 3.15t)
- Platform C compiler/linker (MSVC on Windows, GCC on Linux, Clang on macOS)
- Windows 8+, manylinux2014/musl Linux, or macOS
- x86-64 or ARM64 CPU
- Internet access (downloads Python distributions and libraries)
## Dependencies (open-source core)
- `cython >= 3.2.4` — Python-to-C transpiler
- `setuptools >= 82.0.1` — provides the distutils C compiler interface
- `uv >= 0.11.8` — package manager for the embedded environment
- `auditwheel >= 6.6.0` (Linux only) — repairs wheels for manylinux compliance
## Known constraints
- No modules with identical names across source files
- Monkey-patching is still possible (third-party libraries remain as Python source)
- LGPL libraries remain replaceable by the end user (compliance)
- `__init__.py` is skipped during compilation (it's a namespace marker, not compilable code)
- In library mode, `__main__.py` is excluded from sources (it's generated by the wheel builder)