Python + Web → APK v1.1.3

Build native Android apps
with Python + Web

Write your UI in HTML/CSS/JS and your logic in Python. ENPAF wires them together with a two-way bridge and packages everything into a real, installable APK — no Java, no WSL, no Docker required.

$ pip install enpaf
🐍 Python 3.9+ 📦 12 device modules ✅ 171 tests · CI ⚖ Free for non-commercial
Why ENPAF

Everything you need to ship a mobile app in Python

One project, one language for logic, the web for UI, and a single command to a signed APK.

🐍

Python backend

Routes, bridge handlers, an event system and SQLite storage — your whole app logic in Python.

🌐

Web frontend

Plain HTML/CSS/JS. No bundler, no build step — files are served as-is and load instantly.

🔌

Two-way bridge

Call Python from JS with await enpaf.call(), and push events back from Python with app.emit().

📱

Device capabilities

Wi-Fi, Bluetooth, sensors, NFC, location, camera, audio, battery, notifications, biometrics & permissions.

🛠️

One-command builds

paf build apk produces a signed, installable APK on Windows, macOS or Linux via Gradle + Chaquopy.

Live dev server

paf run previews the exact same app in your browser with hot-reload — iterate without a device.

How it works

Bridge Python logic to your web UI

Register a handler in Python, call it from the web UI. That's the whole model.

main.py
from enpaf import EnpafApp

app = EnpafApp(__name__)

@app.route("/")
def index():
    return app.render("index.html", title=app.name)

@app.bridge_handler("hello")
def hello(params):
    name = params.get("name", "World")
    app.api.vibrate(200)
    return {"message": f"Hi, {name}!"}

if __name__ == "__main__":
    app.run()
app/js/app.js
// Call Python from the web UI
const res = await enpaf.call("hello", { name: "Alex" });
enpaf.device.toast(res.message);   // "Hi, Alex!"

// Listen for events pushed from Python
enpaf.on("progress", (d) => updateBar(d.percent));

// Storage, sensors, permissions — all from JS
await enpaf.storage.set("theme", "dark");
const acc = await enpaf.sensors.read("accelerometer");
await enpaf.permissions.request(["CAMERA"]);
1
Write

Python handlers + a web UI.

2
Preview

paf run in your browser.

3
Ship

paf build apk → signed APK.

The paf CLI

A small command for the whole lifecycle

paf create <name>Scaffold a new project
paf runDev server + hot-reload
paf servePush a build to a device over Wi-Fi
paf build apkBuild an installable APK
paf doctorCheck your build environment
paf infoShow the project config
paf updateUpdate PAF to the latest version

Full reference in the CLI docs →

Device access

Reach the hardware — from Python or JS

Every capability is a module on app and a helper on enpaf.

📶 Wi-Fi 🔵 Bluetooth 🧭 Sensors 🏷️ NFC 📍 Location 📷 Camera / Media 🎙️ Audio 🔋 Battery 🔔 Notifications 🔐 Biometrics ✅ Permissions 📱 Device info
Companion app

A companion loader for your builds

Scan a QR from paf serve and the Companion downloads & installs your APK over Wi-Fi — no cable.

  • QR scan & paste-URL loading
  • Auto-reload watch — alerts when a build changes
  • Favorites & recent builds
  • Device diagnostics + connection tester
  • Biometric lock
ENPAF Companion
Quick start

From zero to an APK in four commands

terminal
$ pip install enpaf
$ paf create myapp
$ cd myapp
$ paf run            # preview at http://127.0.0.1:8080
$ paf build apk      # → dist/myapp-1.0.0.apk

Building APKs needs JDK 17–21 + the Android SDK. Run paf doctor to check. See the installation guide →

Documentation

Dive into the full guide

A detailed wiki covers everything from your first project to release signing.

Ready to build?

Install the framework and create your first project right now.

$ pip install enpaf