A simple framework to build Android apps using Python and CSS-like styling
Project description
🚀 ApkPy — Build Android Apps in Pure Python
ApkPy is a revolutionary transpiler framework that empowers you to build native Android applications using only Python and CSS-style definitions. We don't use WebViews or heavy runtime rendering engines. ApkPy parses your Python logic and directly generates pure Android Java and XML components, ready to be compiled into a lightning-fast .apk.
1. The Vision 🌟
Forget the steep learning curves of Java, Kotlin, or the massive footprint of cross-platform engines. Why choose ApkPy over interpreted frameworks like Kivy or Flet?
- Smaller APK Sizes: Since we transpile to pure Android projects, you avoid bundling heavy Python interpreters or WebView packages into your deployment.
- Flawless Performance: By generating true native
Activity,Button, andEditTextelements under the hood, your app runs at the maximum possible speed the OS allows. - 100% Native Look & Feel: Because your components interact directly with the Android SDK, OS-level features like haptics, text-selection, and system animations are preserved automatically.
2. How it Works (The Technical Secret) 🛠️
How it works: ApkPy parses your Python code into an Abstract Syntax Tree (AST) and maps UI calls to their corresponding Android XML Layouts and Java Activity classes. It's not a simulation; it's code generation.
3. Full Installation & Setup 📥
Getting started is instantly accessible. You do not need any prior knowledge of Android Studio to start designing.
pip install apkpy
(Need the new features? Run pip install --upgrade apkpy)
4. Complete Syntax Guide (v0.9.3 Standard) 🎨
ApkPy v0.9.3 introduces our most powerful layout engine yet, featuring XML-driven Android generation and pixel-perfect previewing.
The Screen
Everything belongs to a Screen. Screens translate directly to native Android Activities.
login_screen = Screen(id="login_container")
The Container (Nesting)
Containers allow you to group components together, creating complex layouts like cards, headers, or custom grids.
# Create a container on the screen
header_box = container(id="header_style", screen=login_screen)
# Add a label inside that container
label("Welcome Back", parent=header_box)
The CSS Engine
Say goodbye to complex dictionary configurations. ApkPy uses a multi-line string approach with standard CSS syntax. No quotes are needed around values!
style = """
login_container {
gap: 15px;
flex-direction: column;
}
"""
New Layout & Styling Features (v0.9.3+)
Our Android-generation engine has been completely rewritten to use XML-driven layouts, ensuring 1:1 parity between your code and the native Android rendering.
gap: 20px;– Automatically places calculateddpmargins between elements in your layout container.flex-direction: row; / column;– Orients your components mapped directly toandroid:orientation="horizontal"or"vertical".padding: 10px 20px;– Pushes text content away from your component edges.border-radius: 15px;– Generates native XML shape drawables for smooth rounded corners.border-color: #000;andborder-width: 2px;– Easily define component outlines.pressed-color: #cccccc;– Defines the feedback color when a button is clicked (native<selector>).focus-border-color: #2196F3;– When a user taps your inputs, ApkPy dynamically swaps the border colors via native XML states!font-size: 18px;– Set text size in pixels (automatically converted tospfor Android).font-weight: bold;– Makes your text thicker. Supportsboldor numeric values (700,800,900).font-family: 'sans-serif';– Choose between native font styles.
Typography Support 🔠
ApkPy ensures your text looks great and consistent across platforms by mapping CSS generic families to native system fonts:
sans-serif: The modern look. Maps to Roboto (Android) and Segoe UI (Windows) or Helvetica (macOS).serif: The classic look. Maps to Times New Roman.monospace: Perfect for code or alignment. Maps to Consolas (Windows) or Courier.
Note: You can also use font-style: italic; to add emphasis to your labels.
5. Component & Logic Workflow ⚙️
Adding elements and routing interactions is declarative and incredibly clean.
Adding Components:
Simply call the component and attach it to your screen. Give it an id to map it to your CSS string.
btn = button("Login", id="primary_btn", screen=login_screen)
inputs("Your email", type="text", id="email_input", screen=login_screen)
Nesting with parent:
Every component (label, button, inputs, container) now supports a parent parameter. If set, the component will be rendered inside that container instead of directly on the screen.
card = container(id="card_bg", screen=my_screen)
label("Title", parent=card)
button("Click Me", parent=card)
Supported Input Types: ApkPy handles complex input mapping for you:
type="text": Standard keyboard entry.type="password": Secure text entry with hidden characters.type="search": Specialized search field with a clear (✕) button.type="checkbox": Native Boolean toggle.type="range": Interactive slider (0-100).type="radio": Selection group (format:inputs("Option1|Option2", type="radio")).
Linking Logic & Navigation:
Instead of fighting with Android Intent classes, handle navigation with a single method.
login_screen.on_click_navigate(button=btn, to=dashboard_screen)
The Application Lifecycle:
Your file must end by invoking the execution layer with run().
run(start_screen=login_screen)
6. The Two-Step Execution Flow 🔄
ApkPy makes the development lifecycle effortless via two distinct phases:
Phase 1: Development (Hot Previewer)
Simply run your Python file normally:
python main.py
This instantly boots up our Tkinter-based Hot Previewer on your computer. You get immediate visual feedback for your screens, interactive inputs, focus colors, buttons, and navigation without needing an emulator!
Phase 2: Production (Native Compilation)
When you're ready to deploy, run the CLI tool in your project folder:
apkpy build
This triggers the transpiler! ApkPy generates all Java classes, Manifests, XML Layouts, and Drawables completely from scratch. This new XML-driven approach ensures that complex layouts, margins, and alignments are handled natively by the Android OS for maximum stability. Open the resulting bundled .zip project and generate your production .apk!
7. What's New & Bug Fixes (v0.9.3) 🚀
We've been hard at work making ApkPy the most reliable Python-to-Android framework. Here’s what’s new:
- XML Layout Engine: Moved from programmatic Java UI to native Android XML layouts. This fixes 99% of layout inconsistencies and allows for better support of Android Studio's design tools.
- Pixel 9 Pro Previewer: The Hot Previewer (Tkinter) is now perfectly calibrated to match the screen dimensions and aspect ratio of a Pixel 9 Pro.
- Automatic Gravity & Centering: Fixed bugs where elements wouldn't center correctly. Using
justify-contentoralign-itemsnow maps accurately to native Android gravity. - Animation Stability: Fixed glitches in
@keyframesanimations, specifically resolving issues withmargin-topshifts during transitions. - Performance: Optimized the transpilation process for faster builds.
7. FAQ (Quick Answers) ❓
"Does it support Android APIs?" Yes! We are currently expanding support for native permissions, GPS, Camera, and more in upcoming versions.
"Do I need the Android SDK installed?"
To write and preview your app using python main.py, no SDK is required. However, apkpy build generates a native Android Studio project. To compile that project into a final .apk, you will need the Android SDK/Java installed on your machine (or just upload the generated folder to a CI/CD service like GitHub Actions).
8. Spacing & Margins (Precision Layout) 📐
Margins allow you to create "invisible space" around your components. This is essential for moving buttons down, separating inputs, or creating breathing room between elements.
Example Code:
my_button {
/* Move the button 50 pixels down from whatever is above it */
margin-top: 50px;
/* Push the button 20 pixels away from the left edge */
margin-left: 20px;
}
header {
/* Put a 30 pixel gap at the bottom of the title */
margin-bottom: 30px;
}
Margin Guide (For Absolute Beginners):
| Property | What it does (in simple terms) |
|---|---|
margin |
Adds space to all four sides (top, bottom, left, and right) at once. It's like putting a bubble around the whole component. |
margin-top |
Pushes the component down. It adds space to the top edge. Use this if you want something to move lower on the screen. |
margin-bottom |
Pushes the next component away. It adds space to the bottom edge. |
margin-left |
Pushes the component to the right. It adds space to the left side. |
margin-right |
Pushes the component to the left. It adds space to the right side. |
[!TIP] In ApkPy, you can use
px(like20px). The compiler automatically converts this todpfor Android, so your app looks perfect on every phone screen size!
9. Native Permissions & Features 📱
ApkPy allows you to interact directly with Android system features using a simple Python API.
Declaring Manifest Permissions
Declare what your app needs so the compiler can update AndroidManifest.xml automatically.
from apkpy_lib import declare_permissions
declare_permissions(["CAMERA", "LOCATION_FINE", "INTERNET"])
Runtime Permission Requests & Toasts
Prompt users for permissions and provide instant feedback with native Toasts.
from apkpy_lib import permissions, toast
def ask_camera():
def on_result(granted):
if granted:
toast("Camera access granted! 📸")
else:
toast("We need camera permission to continue.")
permissions.request("CAMERA", on_response=on_result)
10. Master Example: Mini Profile App 👤
This example tells a short story: It collects a user's name, requests camera permission for a "profile picture," and displays a thank-you toast. It demonstrates inputs, permissions, toasts, and advanced CSS styling.
from apkpy_lib import Screen, button, label, inputs, run, toast, declare_permissions, permissions
# 1. Declare permission for the compiler
declare_permissions(["CAMERA"])
# 2. Setup the Screen
profile_screen = Screen(id="profile_container")
# 3. Logic: Handle Camera Request
def update_photo():
def on_perm(granted):
if granted:
toast("Thanks! Accessing camera for your photo...")
else:
toast("We need camera access to take a photo!")
permissions.request("CAMERA", on_response=on_perm)
# 4. Build the UI
label("Mini Profile App", id="header", screen=profile_screen)
inputs("Enter your Full Name", type="text", id="field", screen=profile_screen)
inputs("Short Bio", type="text", id="field", screen=profile_screen)
# Button that triggers permission logic
btn_photo = button("Set Profile Picture", id="btn_outline", command=update_photo, screen=profile_screen)
btn_save = button("Save Profile", id="btn_primary", screen=profile_screen)
# 5. Advanced CSS System
style = """
profile_container {
flex-direction: column;
gap: 20px;
background-color: #ffffff;
}
header {
color: #1a1a1a;
font-size: 24px;
font-weight: bold;
}
field {
border-color: #e0e0e0;
border-radius: 12px;
padding: 14px;
focus-border-color: #6200EE;
}
btn_outline {
background-color: #ffffff;
color: #6200EE;
border-color: #6200EE;
border-width: 2px;
border-radius: 20px;
pressed-color: #f3e5f5;
}
btn_primary {
background-color: #6200EE;
color: white;
border-radius: 20px;
pressed-color: #3700B3;
}
"""
run(start_screen=profile_screen)
11. Declarative CSS Animations 🎬 (v0.9.0)
ApkPy now supports native declarative animations using a syntax inspired by CSS Keyframes. You can define how a component should transition from one state to another, and the framework will generate the corresponding native Android Animation XML and Java logic.
How it Works: The @keyframes Block
An animation is defined using the @keyframes keyword followed by a name. Inside, you define two states:
from(or0%): The starting state of the component when it appears.to(or100%): The final state where the component should end.
@keyframes slideUp {
from {
opacity: 0;
margin-top: 50px;
}
to {
opacity: 1;
margin-top: 0px;
}
}
Applying the Animation
To trigger an animation, use these two properties on your component ID:
animation-name: The name of the@keyframesblock you defined.animation-duration: How long the animation lasts (e.g.,1000msor2s).
my_button {
animation-name: slideUp;
animation-duration: 1500ms;
}
Supported Properties:
| Property | Description | Example |
|---|---|---|
opacity |
Fades the component in or out (0.0 is invisible, 1.0 is solid). | opacity: 0; to opacity: 1; |
margin-top |
Moves the component vertically (Y-axis). | margin-top: 100px; to 0px; |
margin-left |
Moves the component horizontally (X-axis). | margin-left: -50px; to 0px; |
scale |
Resizes the component (1.0 is normal size). | scale: 0.5; to scale: 1.0; |
Pro Examples for your App:
1. Smooth Fade-In (Entry Effect)
Makes your title or logo appear slowly from nothing.
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
2. The "Pop" Effect (Scaling)
Makes a button grow into its place.
@keyframes pop {
from { scale: 0.5; opacity: 0; }
to { scale: 1.0; opacity: 1; }
}
3. Side Slide (Horizontal Entry)
Slides a component from the left edge into its position.
@keyframes slideFromLeft {
from { margin-left: -200px; opacity: 0; }
to { margin-left: 0px; opacity: 1; }
}
[!IMPORTANT] Cross-Platform Support: These animations are fully functional in the Tkinter Previewer (Phase 1) so you can test the "vibe" of your app, and they are compiled into Native Android XML (Phase 2) for maximum performance on real devices.
🤝 Community & Support
Found a bug? Open an issue on Reddit!
Want to contribute? We are looking for contributors to expand our Native Component library! Join us in making Python a first-class citizen for Android development.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file apkpy-0.9.4.tar.gz.
File metadata
- Download URL: apkpy-0.9.4.tar.gz
- Upload date:
- Size: 94.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b244b1e995db14755682f0708adfcb4f10233641d03f0bbb90272ace442d7c45
|
|
| MD5 |
91150e68895a505615b93ee69df20137
|
|
| BLAKE2b-256 |
d124b4970b8a2bb796a62b23cef4a1afe01c0d154504af200f1783bdb35c5fd1
|
File details
Details for the file apkpy-0.9.4-py3-none-any.whl.
File metadata
- Download URL: apkpy-0.9.4-py3-none-any.whl
- Upload date:
- Size: 95.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
244e636781413eb13b24c26f002296c5c1cd7d4d43892fc21d9ac3a5bce11f01
|
|
| MD5 |
74def1c73b5f8e65a113265d5e5ff8fe
|
|
| BLAKE2b-256 |
7cb3519f189d0618d7ad771e867003afb9bd776d2d1d0af14752183ec53fb04d
|