py2apk 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- py2apk-0.3.0/LICENSE +12 -0
- py2apk-0.3.0/PKG-INFO +203 -0
- py2apk-0.3.0/README.md +179 -0
- py2apk-0.3.0/py2apk.egg-info/PKG-INFO +203 -0
- py2apk-0.3.0/py2apk.egg-info/SOURCES.txt +10 -0
- py2apk-0.3.0/py2apk.egg-info/dependency_links.txt +1 -0
- py2apk-0.3.0/py2apk.egg-info/entry_points.txt +2 -0
- py2apk-0.3.0/py2apk.egg-info/requires.txt +3 -0
- py2apk-0.3.0/py2apk.egg-info/top_level.txt +1 -0
- py2apk-0.3.0/py2apk.py +698 -0
- py2apk-0.3.0/pyproject.toml +37 -0
- py2apk-0.3.0/setup.cfg +4 -0
py2apk-0.3.0/LICENSE
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Copyright (c) 2026 Two Plasma Studios. All rights reserved.
|
|
2
|
+
|
|
3
|
+
CONFIDENTIALITY AND PROPRIETARY NOTICE
|
|
4
|
+
|
|
5
|
+
This software and all associated documentation files (the "Software") are the intellectual property of Two Plasma Studios.
|
|
6
|
+
|
|
7
|
+
Strictly Prohibition on Copying and Distribution:
|
|
8
|
+
1. No part of this Software may be copied, reproduced, modified, reverse engineered, decompiled, disassembled, or distributed in any form or by any means, electronic or mechanical, without the prior written permission of the copyright owner.
|
|
9
|
+
2. The Software is provided solely for personal running/execution via official package managers (e.g., pip).
|
|
10
|
+
3. Commercial use, reselling, or hosting the Software as a service (SaaS) is strictly prohibited.
|
|
11
|
+
|
|
12
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
py2apk-0.3.0/PKG-INFO
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: py2apk
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Turn a Python script into an Android APK with a GUI - no Docker, no compiling on your machine
|
|
5
|
+
Author: TwoPlasmaStudios
|
|
6
|
+
License-Expression: LicenseRef-Proprietary
|
|
7
|
+
Project-URL: Homepage, https://github.com/TwoPlasmaStudios/py2apk
|
|
8
|
+
Project-URL: Issues, https://github.com/TwoPlasmaStudios/py2apk/issues
|
|
9
|
+
Keywords: android,apk,python,packaging,flask,webview,gui
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Environment :: X11 Applications
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
14
|
+
Classifier: Operating System :: MacOS
|
|
15
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Provides-Extra: icon
|
|
22
|
+
Requires-Dist: pillow; extra == "icon"
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+
# py2apk
|
|
26
|
+
|
|
27
|
+
[Türkçe](README.tr.md)
|
|
28
|
+
|
|
29
|
+
Turn a Python script into an Android APK, from a simple desktop GUI.
|
|
30
|
+
No Docker, no WSL, no compiler on your machine, and it runs on Windows, macOS and Linux.
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
pip install py2apk
|
|
34
|
+
py2apk
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Pick your `.py` file, choose an app type, press **Build APK**. That's it.
|
|
38
|
+
|
|
39
|
+
## How it works
|
|
40
|
+
|
|
41
|
+
py2apk is split in two parts so that you never have to compile anything:
|
|
42
|
+
|
|
43
|
+
1. **The factory** (`factory.py` + a GitHub Actions workflow) runs once on GitHub.
|
|
44
|
+
It cross-compiles CPython for Android (arm64-v8a and x86_64), builds the Android
|
|
45
|
+
wheels for a set of popular libraries (Flask, NumPy, pandas, Pillow, ...), and
|
|
46
|
+
publishes everything as a GitHub Release.
|
|
47
|
+
2. **The tool** (`py2apk.py`, the GUI you run) downloads those ready-made pieces,
|
|
48
|
+
scans your imports, bundles your code and the libraries it needs, writes the
|
|
49
|
+
Android manifest, and packages and signs the APK.
|
|
50
|
+
|
|
51
|
+
The only things downloaded on your machine are a JDK 17 and the Android build-tools
|
|
52
|
+
(if you don't already have them), kept in `~/.py2apk`.
|
|
53
|
+
|
|
54
|
+
## Install
|
|
55
|
+
|
|
56
|
+
From PyPI (once published):
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
pip install py2apk
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Straight from GitHub (works today):
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
pip install git+https://github.com/TwoPlasmaStudios/pyapk.git
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Requirements: Python 3.10+ with tkinter. The Windows and macOS installers from
|
|
69
|
+
python.org include tkinter. On Debian/Ubuntu: `sudo apt install python3-tk`.
|
|
70
|
+
Optional: `pip install py2apk[icon]` (Pillow) to use JPG/WebP logos and get a sharp preview.
|
|
71
|
+
|
|
72
|
+
## Use it
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
py2apk # opens the GUI
|
|
76
|
+
py2apk path/to/app.py # opens the GUI with a file preselected
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
1. **Python file**: your entry script. Other `.py` files and packages next to it are
|
|
80
|
+
included automatically, so keep the project in its own folder.
|
|
81
|
+
2. **App**: name, package name (e.g. `com.me.myapp`), version and an optional logo.
|
|
82
|
+
3. **App type**: see below.
|
|
83
|
+
4. **Libraries**: detected from your imports. Each one shows whether a ready-made
|
|
84
|
+
Android build exists. Add extra packages in the *Extra packages* field.
|
|
85
|
+
5. Press **Build APK**. The first build downloads the JDK and Android tools (several
|
|
86
|
+
hundred MB); later builds are fast. The APK is written next to your script.
|
|
87
|
+
|
|
88
|
+
Install it with `adb install MyApp-1.0.apk` or copy it to the phone and open it
|
|
89
|
+
(allow installs from unknown sources). The APK is signed with a debug key, which is
|
|
90
|
+
fine for testing and sideloading but not for Google Play.
|
|
91
|
+
|
|
92
|
+
### App types
|
|
93
|
+
|
|
94
|
+
| Type | Status | What you get |
|
|
95
|
+
|---|---|---|
|
|
96
|
+
| **Console** | works | `print()` output is shown on screen. For scripts, bots, calculations. No `input()`. |
|
|
97
|
+
| **Web UI** | works | Run Flask/FastAPI/etc. in your script. The app opens it full screen in a WebView. |
|
|
98
|
+
| **Pygame / Games** | not yet | Needs an SDL2 runtime. |
|
|
99
|
+
| **Kivy** | not yet | Needs an SDL2 runtime. |
|
|
100
|
+
|
|
101
|
+
Tkinter does not exist on Android. Use the **Web UI** type for graphical apps.
|
|
102
|
+
|
|
103
|
+
#### Web UI example
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
import os
|
|
107
|
+
from flask import Flask
|
|
108
|
+
|
|
109
|
+
app = Flask(__name__)
|
|
110
|
+
|
|
111
|
+
@app.get("/")
|
|
112
|
+
def index():
|
|
113
|
+
return "<h1>Hello from Android!</h1>"
|
|
114
|
+
|
|
115
|
+
app.run(host="127.0.0.1", port=int(os.environ.get("PORT", 5000)), debug=False)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Keep `debug=False` (the reloader starts a second process, which Android won't allow) and
|
|
119
|
+
listen on `127.0.0.1`. The port is set in the GUI and passed to your code as `PORT`.
|
|
120
|
+
If the server fails to start, the app shows the Python traceback instead of a blank page.
|
|
121
|
+
|
|
122
|
+
## Libraries
|
|
123
|
+
|
|
124
|
+
The factory builds Android wheels for a fixed list of popular packages
|
|
125
|
+
(see `LIBS` in `factory.py`), plus all of their dependencies. Pure-Python packages
|
|
126
|
+
work as they are. Packages with C extensions only work if an Android build exists.
|
|
127
|
+
|
|
128
|
+
* Packages in the Release are used first.
|
|
129
|
+
* Anything else is tried from PyPI (pure-Python or Android wheels) with `pip`.
|
|
130
|
+
* If nothing is found you get a warning in the log and the package is skipped.
|
|
131
|
+
|
|
132
|
+
Which libraries are available changes as the factory improves: open the
|
|
133
|
+
`index.json` asset of the Release (or look at the status column in the GUI).
|
|
134
|
+
Some heavy packages (SciPy, scikit-learn, OpenCV, anything needing Rust or Fortran
|
|
135
|
+
toolchains) are the hardest to cross-compile and may be marked as failed.
|
|
136
|
+
|
|
137
|
+
## Run your own factory
|
|
138
|
+
|
|
139
|
+
Fork the repository, enable Actions, give the workflow write access
|
|
140
|
+
(*Settings -> Actions -> General -> Workflow permissions -> Read and write*), then run
|
|
141
|
+
**Actions -> factory -> Run workflow**. When it finishes, a release tagged `cp313` appears.
|
|
142
|
+
Point the tool at your fork:
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
# Windows (PowerShell)
|
|
146
|
+
$env:PY2APK_REPO = "you/your-fork"
|
|
147
|
+
# macOS / Linux
|
|
148
|
+
export PY2APK_REPO=you/your-fork
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Or use *Advanced -> GitHub repository* inside the GUI.
|
|
152
|
+
|
|
153
|
+
## Environment variables
|
|
154
|
+
|
|
155
|
+
| Variable | Meaning |
|
|
156
|
+
|---|---|
|
|
157
|
+
| `PY2APK_REPO` | GitHub `owner/repo` that hosts the Release (default `TwoPlasmaStudios/pyapk`) |
|
|
158
|
+
| `PY2APK_HOME` | Cache folder (default `~/.py2apk`) |
|
|
159
|
+
| `PY2APK_PY` | Release tag, i.e. the Python version (default `cp313`) |
|
|
160
|
+
|
|
161
|
+
## Troubleshooting
|
|
162
|
+
|
|
163
|
+
* **"Library index could not be fetched"**: the repository must be public and the factory
|
|
164
|
+
must have finished at least once.
|
|
165
|
+
* **App crashes or shows a traceback**: run `adb logcat -s pyapk` while opening it.
|
|
166
|
+
* **Import error for a native library**: that package has no Android build yet. Check its
|
|
167
|
+
status in the GUI.
|
|
168
|
+
* **Build fails while downloading tools**: check your connection; downloads resume from the cache.
|
|
169
|
+
|
|
170
|
+
## Limitations
|
|
171
|
+
|
|
172
|
+
* Python 3.13 runtime, arm64-v8a and x86_64 only, minimum Android 7.0 (API 24).
|
|
173
|
+
* No tkinter, pygame or Kivy yet.
|
|
174
|
+
* Console apps have no interactive input.
|
|
175
|
+
* Debug-signed APKs only.
|
|
176
|
+
|
|
177
|
+
## Publishing to PyPI (maintainers)
|
|
178
|
+
|
|
179
|
+
Releases are published by `.github/workflows/publish.yml` with PyPI Trusted Publishing
|
|
180
|
+
(no API token needed). It only runs for tags that start with `v`, so the `cp313` release
|
|
181
|
+
created by the factory never triggers it.
|
|
182
|
+
|
|
183
|
+
One-time setup:
|
|
184
|
+
|
|
185
|
+
1. Check that the name is free: https://pypi.org/project/py2apk/ should return 404.
|
|
186
|
+
2. On pypi.org: *Your projects -> Publishing -> Add a new pending publisher* with
|
|
187
|
+
project `py2apk`, owner `TwoPlasmaStudios`, repository `pyapk`,
|
|
188
|
+
workflow `publish.yml`, environment `pypi`.
|
|
189
|
+
3. On GitHub: *Settings -> Environments -> New environment* named `pypi`.
|
|
190
|
+
|
|
191
|
+
Each release: bump `version` in `pyproject.toml`, then
|
|
192
|
+
|
|
193
|
+
```
|
|
194
|
+
git tag v0.3.0
|
|
195
|
+
git push origin v0.3.0
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Manual alternative: `pip install build twine`, `python -m build`, `twine upload dist/*`
|
|
199
|
+
(use an API token, username `__token__`).
|
|
200
|
+
|
|
201
|
+
## License
|
|
202
|
+
|
|
203
|
+
MIT. Libraries in the Release keep their own licenses; CPython is under the PSF license.
|
py2apk-0.3.0/README.md
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# py2apk
|
|
2
|
+
|
|
3
|
+
[Türkçe](README.tr.md)
|
|
4
|
+
|
|
5
|
+
Turn a Python script into an Android APK, from a simple desktop GUI.
|
|
6
|
+
No Docker, no WSL, no compiler on your machine, and it runs on Windows, macOS and Linux.
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
pip install py2apk
|
|
10
|
+
py2apk
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Pick your `.py` file, choose an app type, press **Build APK**. That's it.
|
|
14
|
+
|
|
15
|
+
## How it works
|
|
16
|
+
|
|
17
|
+
py2apk is split in two parts so that you never have to compile anything:
|
|
18
|
+
|
|
19
|
+
1. **The factory** (`factory.py` + a GitHub Actions workflow) runs once on GitHub.
|
|
20
|
+
It cross-compiles CPython for Android (arm64-v8a and x86_64), builds the Android
|
|
21
|
+
wheels for a set of popular libraries (Flask, NumPy, pandas, Pillow, ...), and
|
|
22
|
+
publishes everything as a GitHub Release.
|
|
23
|
+
2. **The tool** (`py2apk.py`, the GUI you run) downloads those ready-made pieces,
|
|
24
|
+
scans your imports, bundles your code and the libraries it needs, writes the
|
|
25
|
+
Android manifest, and packages and signs the APK.
|
|
26
|
+
|
|
27
|
+
The only things downloaded on your machine are a JDK 17 and the Android build-tools
|
|
28
|
+
(if you don't already have them), kept in `~/.py2apk`.
|
|
29
|
+
|
|
30
|
+
## Install
|
|
31
|
+
|
|
32
|
+
From PyPI (once published):
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
pip install py2apk
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Straight from GitHub (works today):
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
pip install git+https://github.com/TwoPlasmaStudios/pyapk.git
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Requirements: Python 3.10+ with tkinter. The Windows and macOS installers from
|
|
45
|
+
python.org include tkinter. On Debian/Ubuntu: `sudo apt install python3-tk`.
|
|
46
|
+
Optional: `pip install py2apk[icon]` (Pillow) to use JPG/WebP logos and get a sharp preview.
|
|
47
|
+
|
|
48
|
+
## Use it
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
py2apk # opens the GUI
|
|
52
|
+
py2apk path/to/app.py # opens the GUI with a file preselected
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
1. **Python file**: your entry script. Other `.py` files and packages next to it are
|
|
56
|
+
included automatically, so keep the project in its own folder.
|
|
57
|
+
2. **App**: name, package name (e.g. `com.me.myapp`), version and an optional logo.
|
|
58
|
+
3. **App type**: see below.
|
|
59
|
+
4. **Libraries**: detected from your imports. Each one shows whether a ready-made
|
|
60
|
+
Android build exists. Add extra packages in the *Extra packages* field.
|
|
61
|
+
5. Press **Build APK**. The first build downloads the JDK and Android tools (several
|
|
62
|
+
hundred MB); later builds are fast. The APK is written next to your script.
|
|
63
|
+
|
|
64
|
+
Install it with `adb install MyApp-1.0.apk` or copy it to the phone and open it
|
|
65
|
+
(allow installs from unknown sources). The APK is signed with a debug key, which is
|
|
66
|
+
fine for testing and sideloading but not for Google Play.
|
|
67
|
+
|
|
68
|
+
### App types
|
|
69
|
+
|
|
70
|
+
| Type | Status | What you get |
|
|
71
|
+
|---|---|---|
|
|
72
|
+
| **Console** | works | `print()` output is shown on screen. For scripts, bots, calculations. No `input()`. |
|
|
73
|
+
| **Web UI** | works | Run Flask/FastAPI/etc. in your script. The app opens it full screen in a WebView. |
|
|
74
|
+
| **Pygame / Games** | not yet | Needs an SDL2 runtime. |
|
|
75
|
+
| **Kivy** | not yet | Needs an SDL2 runtime. |
|
|
76
|
+
|
|
77
|
+
Tkinter does not exist on Android. Use the **Web UI** type for graphical apps.
|
|
78
|
+
|
|
79
|
+
#### Web UI example
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
import os
|
|
83
|
+
from flask import Flask
|
|
84
|
+
|
|
85
|
+
app = Flask(__name__)
|
|
86
|
+
|
|
87
|
+
@app.get("/")
|
|
88
|
+
def index():
|
|
89
|
+
return "<h1>Hello from Android!</h1>"
|
|
90
|
+
|
|
91
|
+
app.run(host="127.0.0.1", port=int(os.environ.get("PORT", 5000)), debug=False)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Keep `debug=False` (the reloader starts a second process, which Android won't allow) and
|
|
95
|
+
listen on `127.0.0.1`. The port is set in the GUI and passed to your code as `PORT`.
|
|
96
|
+
If the server fails to start, the app shows the Python traceback instead of a blank page.
|
|
97
|
+
|
|
98
|
+
## Libraries
|
|
99
|
+
|
|
100
|
+
The factory builds Android wheels for a fixed list of popular packages
|
|
101
|
+
(see `LIBS` in `factory.py`), plus all of their dependencies. Pure-Python packages
|
|
102
|
+
work as they are. Packages with C extensions only work if an Android build exists.
|
|
103
|
+
|
|
104
|
+
* Packages in the Release are used first.
|
|
105
|
+
* Anything else is tried from PyPI (pure-Python or Android wheels) with `pip`.
|
|
106
|
+
* If nothing is found you get a warning in the log and the package is skipped.
|
|
107
|
+
|
|
108
|
+
Which libraries are available changes as the factory improves: open the
|
|
109
|
+
`index.json` asset of the Release (or look at the status column in the GUI).
|
|
110
|
+
Some heavy packages (SciPy, scikit-learn, OpenCV, anything needing Rust or Fortran
|
|
111
|
+
toolchains) are the hardest to cross-compile and may be marked as failed.
|
|
112
|
+
|
|
113
|
+
## Run your own factory
|
|
114
|
+
|
|
115
|
+
Fork the repository, enable Actions, give the workflow write access
|
|
116
|
+
(*Settings -> Actions -> General -> Workflow permissions -> Read and write*), then run
|
|
117
|
+
**Actions -> factory -> Run workflow**. When it finishes, a release tagged `cp313` appears.
|
|
118
|
+
Point the tool at your fork:
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
# Windows (PowerShell)
|
|
122
|
+
$env:PY2APK_REPO = "you/your-fork"
|
|
123
|
+
# macOS / Linux
|
|
124
|
+
export PY2APK_REPO=you/your-fork
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Or use *Advanced -> GitHub repository* inside the GUI.
|
|
128
|
+
|
|
129
|
+
## Environment variables
|
|
130
|
+
|
|
131
|
+
| Variable | Meaning |
|
|
132
|
+
|---|---|
|
|
133
|
+
| `PY2APK_REPO` | GitHub `owner/repo` that hosts the Release (default `TwoPlasmaStudios/pyapk`) |
|
|
134
|
+
| `PY2APK_HOME` | Cache folder (default `~/.py2apk`) |
|
|
135
|
+
| `PY2APK_PY` | Release tag, i.e. the Python version (default `cp313`) |
|
|
136
|
+
|
|
137
|
+
## Troubleshooting
|
|
138
|
+
|
|
139
|
+
* **"Library index could not be fetched"**: the repository must be public and the factory
|
|
140
|
+
must have finished at least once.
|
|
141
|
+
* **App crashes or shows a traceback**: run `adb logcat -s pyapk` while opening it.
|
|
142
|
+
* **Import error for a native library**: that package has no Android build yet. Check its
|
|
143
|
+
status in the GUI.
|
|
144
|
+
* **Build fails while downloading tools**: check your connection; downloads resume from the cache.
|
|
145
|
+
|
|
146
|
+
## Limitations
|
|
147
|
+
|
|
148
|
+
* Python 3.13 runtime, arm64-v8a and x86_64 only, minimum Android 7.0 (API 24).
|
|
149
|
+
* No tkinter, pygame or Kivy yet.
|
|
150
|
+
* Console apps have no interactive input.
|
|
151
|
+
* Debug-signed APKs only.
|
|
152
|
+
|
|
153
|
+
## Publishing to PyPI (maintainers)
|
|
154
|
+
|
|
155
|
+
Releases are published by `.github/workflows/publish.yml` with PyPI Trusted Publishing
|
|
156
|
+
(no API token needed). It only runs for tags that start with `v`, so the `cp313` release
|
|
157
|
+
created by the factory never triggers it.
|
|
158
|
+
|
|
159
|
+
One-time setup:
|
|
160
|
+
|
|
161
|
+
1. Check that the name is free: https://pypi.org/project/py2apk/ should return 404.
|
|
162
|
+
2. On pypi.org: *Your projects -> Publishing -> Add a new pending publisher* with
|
|
163
|
+
project `py2apk`, owner `TwoPlasmaStudios`, repository `pyapk`,
|
|
164
|
+
workflow `publish.yml`, environment `pypi`.
|
|
165
|
+
3. On GitHub: *Settings -> Environments -> New environment* named `pypi`.
|
|
166
|
+
|
|
167
|
+
Each release: bump `version` in `pyproject.toml`, then
|
|
168
|
+
|
|
169
|
+
```
|
|
170
|
+
git tag v0.3.0
|
|
171
|
+
git push origin v0.3.0
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Manual alternative: `pip install build twine`, `python -m build`, `twine upload dist/*`
|
|
175
|
+
(use an API token, username `__token__`).
|
|
176
|
+
|
|
177
|
+
## License
|
|
178
|
+
|
|
179
|
+
MIT. Libraries in the Release keep their own licenses; CPython is under the PSF license.
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: py2apk
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Turn a Python script into an Android APK with a GUI - no Docker, no compiling on your machine
|
|
5
|
+
Author: TwoPlasmaStudios
|
|
6
|
+
License-Expression: LicenseRef-Proprietary
|
|
7
|
+
Project-URL: Homepage, https://github.com/TwoPlasmaStudios/py2apk
|
|
8
|
+
Project-URL: Issues, https://github.com/TwoPlasmaStudios/py2apk/issues
|
|
9
|
+
Keywords: android,apk,python,packaging,flask,webview,gui
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Environment :: X11 Applications
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
14
|
+
Classifier: Operating System :: MacOS
|
|
15
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Provides-Extra: icon
|
|
22
|
+
Requires-Dist: pillow; extra == "icon"
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+
# py2apk
|
|
26
|
+
|
|
27
|
+
[Türkçe](README.tr.md)
|
|
28
|
+
|
|
29
|
+
Turn a Python script into an Android APK, from a simple desktop GUI.
|
|
30
|
+
No Docker, no WSL, no compiler on your machine, and it runs on Windows, macOS and Linux.
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
pip install py2apk
|
|
34
|
+
py2apk
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Pick your `.py` file, choose an app type, press **Build APK**. That's it.
|
|
38
|
+
|
|
39
|
+
## How it works
|
|
40
|
+
|
|
41
|
+
py2apk is split in two parts so that you never have to compile anything:
|
|
42
|
+
|
|
43
|
+
1. **The factory** (`factory.py` + a GitHub Actions workflow) runs once on GitHub.
|
|
44
|
+
It cross-compiles CPython for Android (arm64-v8a and x86_64), builds the Android
|
|
45
|
+
wheels for a set of popular libraries (Flask, NumPy, pandas, Pillow, ...), and
|
|
46
|
+
publishes everything as a GitHub Release.
|
|
47
|
+
2. **The tool** (`py2apk.py`, the GUI you run) downloads those ready-made pieces,
|
|
48
|
+
scans your imports, bundles your code and the libraries it needs, writes the
|
|
49
|
+
Android manifest, and packages and signs the APK.
|
|
50
|
+
|
|
51
|
+
The only things downloaded on your machine are a JDK 17 and the Android build-tools
|
|
52
|
+
(if you don't already have them), kept in `~/.py2apk`.
|
|
53
|
+
|
|
54
|
+
## Install
|
|
55
|
+
|
|
56
|
+
From PyPI (once published):
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
pip install py2apk
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Straight from GitHub (works today):
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
pip install git+https://github.com/TwoPlasmaStudios/pyapk.git
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Requirements: Python 3.10+ with tkinter. The Windows and macOS installers from
|
|
69
|
+
python.org include tkinter. On Debian/Ubuntu: `sudo apt install python3-tk`.
|
|
70
|
+
Optional: `pip install py2apk[icon]` (Pillow) to use JPG/WebP logos and get a sharp preview.
|
|
71
|
+
|
|
72
|
+
## Use it
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
py2apk # opens the GUI
|
|
76
|
+
py2apk path/to/app.py # opens the GUI with a file preselected
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
1. **Python file**: your entry script. Other `.py` files and packages next to it are
|
|
80
|
+
included automatically, so keep the project in its own folder.
|
|
81
|
+
2. **App**: name, package name (e.g. `com.me.myapp`), version and an optional logo.
|
|
82
|
+
3. **App type**: see below.
|
|
83
|
+
4. **Libraries**: detected from your imports. Each one shows whether a ready-made
|
|
84
|
+
Android build exists. Add extra packages in the *Extra packages* field.
|
|
85
|
+
5. Press **Build APK**. The first build downloads the JDK and Android tools (several
|
|
86
|
+
hundred MB); later builds are fast. The APK is written next to your script.
|
|
87
|
+
|
|
88
|
+
Install it with `adb install MyApp-1.0.apk` or copy it to the phone and open it
|
|
89
|
+
(allow installs from unknown sources). The APK is signed with a debug key, which is
|
|
90
|
+
fine for testing and sideloading but not for Google Play.
|
|
91
|
+
|
|
92
|
+
### App types
|
|
93
|
+
|
|
94
|
+
| Type | Status | What you get |
|
|
95
|
+
|---|---|---|
|
|
96
|
+
| **Console** | works | `print()` output is shown on screen. For scripts, bots, calculations. No `input()`. |
|
|
97
|
+
| **Web UI** | works | Run Flask/FastAPI/etc. in your script. The app opens it full screen in a WebView. |
|
|
98
|
+
| **Pygame / Games** | not yet | Needs an SDL2 runtime. |
|
|
99
|
+
| **Kivy** | not yet | Needs an SDL2 runtime. |
|
|
100
|
+
|
|
101
|
+
Tkinter does not exist on Android. Use the **Web UI** type for graphical apps.
|
|
102
|
+
|
|
103
|
+
#### Web UI example
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
import os
|
|
107
|
+
from flask import Flask
|
|
108
|
+
|
|
109
|
+
app = Flask(__name__)
|
|
110
|
+
|
|
111
|
+
@app.get("/")
|
|
112
|
+
def index():
|
|
113
|
+
return "<h1>Hello from Android!</h1>"
|
|
114
|
+
|
|
115
|
+
app.run(host="127.0.0.1", port=int(os.environ.get("PORT", 5000)), debug=False)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Keep `debug=False` (the reloader starts a second process, which Android won't allow) and
|
|
119
|
+
listen on `127.0.0.1`. The port is set in the GUI and passed to your code as `PORT`.
|
|
120
|
+
If the server fails to start, the app shows the Python traceback instead of a blank page.
|
|
121
|
+
|
|
122
|
+
## Libraries
|
|
123
|
+
|
|
124
|
+
The factory builds Android wheels for a fixed list of popular packages
|
|
125
|
+
(see `LIBS` in `factory.py`), plus all of their dependencies. Pure-Python packages
|
|
126
|
+
work as they are. Packages with C extensions only work if an Android build exists.
|
|
127
|
+
|
|
128
|
+
* Packages in the Release are used first.
|
|
129
|
+
* Anything else is tried from PyPI (pure-Python or Android wheels) with `pip`.
|
|
130
|
+
* If nothing is found you get a warning in the log and the package is skipped.
|
|
131
|
+
|
|
132
|
+
Which libraries are available changes as the factory improves: open the
|
|
133
|
+
`index.json` asset of the Release (or look at the status column in the GUI).
|
|
134
|
+
Some heavy packages (SciPy, scikit-learn, OpenCV, anything needing Rust or Fortran
|
|
135
|
+
toolchains) are the hardest to cross-compile and may be marked as failed.
|
|
136
|
+
|
|
137
|
+
## Run your own factory
|
|
138
|
+
|
|
139
|
+
Fork the repository, enable Actions, give the workflow write access
|
|
140
|
+
(*Settings -> Actions -> General -> Workflow permissions -> Read and write*), then run
|
|
141
|
+
**Actions -> factory -> Run workflow**. When it finishes, a release tagged `cp313` appears.
|
|
142
|
+
Point the tool at your fork:
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
# Windows (PowerShell)
|
|
146
|
+
$env:PY2APK_REPO = "you/your-fork"
|
|
147
|
+
# macOS / Linux
|
|
148
|
+
export PY2APK_REPO=you/your-fork
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Or use *Advanced -> GitHub repository* inside the GUI.
|
|
152
|
+
|
|
153
|
+
## Environment variables
|
|
154
|
+
|
|
155
|
+
| Variable | Meaning |
|
|
156
|
+
|---|---|
|
|
157
|
+
| `PY2APK_REPO` | GitHub `owner/repo` that hosts the Release (default `TwoPlasmaStudios/pyapk`) |
|
|
158
|
+
| `PY2APK_HOME` | Cache folder (default `~/.py2apk`) |
|
|
159
|
+
| `PY2APK_PY` | Release tag, i.e. the Python version (default `cp313`) |
|
|
160
|
+
|
|
161
|
+
## Troubleshooting
|
|
162
|
+
|
|
163
|
+
* **"Library index could not be fetched"**: the repository must be public and the factory
|
|
164
|
+
must have finished at least once.
|
|
165
|
+
* **App crashes or shows a traceback**: run `adb logcat -s pyapk` while opening it.
|
|
166
|
+
* **Import error for a native library**: that package has no Android build yet. Check its
|
|
167
|
+
status in the GUI.
|
|
168
|
+
* **Build fails while downloading tools**: check your connection; downloads resume from the cache.
|
|
169
|
+
|
|
170
|
+
## Limitations
|
|
171
|
+
|
|
172
|
+
* Python 3.13 runtime, arm64-v8a and x86_64 only, minimum Android 7.0 (API 24).
|
|
173
|
+
* No tkinter, pygame or Kivy yet.
|
|
174
|
+
* Console apps have no interactive input.
|
|
175
|
+
* Debug-signed APKs only.
|
|
176
|
+
|
|
177
|
+
## Publishing to PyPI (maintainers)
|
|
178
|
+
|
|
179
|
+
Releases are published by `.github/workflows/publish.yml` with PyPI Trusted Publishing
|
|
180
|
+
(no API token needed). It only runs for tags that start with `v`, so the `cp313` release
|
|
181
|
+
created by the factory never triggers it.
|
|
182
|
+
|
|
183
|
+
One-time setup:
|
|
184
|
+
|
|
185
|
+
1. Check that the name is free: https://pypi.org/project/py2apk/ should return 404.
|
|
186
|
+
2. On pypi.org: *Your projects -> Publishing -> Add a new pending publisher* with
|
|
187
|
+
project `py2apk`, owner `TwoPlasmaStudios`, repository `pyapk`,
|
|
188
|
+
workflow `publish.yml`, environment `pypi`.
|
|
189
|
+
3. On GitHub: *Settings -> Environments -> New environment* named `pypi`.
|
|
190
|
+
|
|
191
|
+
Each release: bump `version` in `pyproject.toml`, then
|
|
192
|
+
|
|
193
|
+
```
|
|
194
|
+
git tag v0.3.0
|
|
195
|
+
git push origin v0.3.0
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Manual alternative: `pip install build twine`, `python -m build`, `twine upload dist/*`
|
|
199
|
+
(use an API token, username `__token__`).
|
|
200
|
+
|
|
201
|
+
## License
|
|
202
|
+
|
|
203
|
+
MIT. Libraries in the Release keep their own licenses; CPython is under the PSF license.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
py2apk
|