-
Notifications
You must be signed in to change notification settings - Fork 132
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Install wheel package at runtime. #1146
Comments
I tried to use pip as a module and I haven't got far away:
|
See #623 (comment). |
Thanks. I understood in the end that I won't really be able to use pip. But I've found a nice open source alternative called plz that I'm trying to compile and modify https://github.com/juancarlospaco/plz It still needs python to run setup.py unfortunately |
Oh and we can build python for Android. This is neat https://github.com/chaquo/chaquopy/blob/master/target/standalone-python.sh |
I'm sure there must be a pure-Python alternative that doesn't need to be compiled.
If all your packages are available as wheels, then that shouldn't be a problem.
I haven't tested that script for a long time, so it probably doesn't work with the current version of Chaquopy. It was also written before Android started to block apps from including executables (#605). |
I've tried to search one but I couldn't find any so far, I'll probably keep looking. Yeah, will have my own repo with wheels build by the scripts. |
Maybe just seuptools is enough |
Ah setuptools might be enough https://github.com/pypa/easy_install/blob/master/easy_install/__init__.py |
For reference I've also found this |
looks like I found what I need for wheel files |
The files directory can't be accessed from python side? PermissionError: [Errno 13] Permission denied: '/data/user/0/dev.marcelnitan.r2droid/files/ |
It can certainly be read and written, but maybe this error comes from doing something else. If you want help, please post the full stack trace and the relevant sections of your code. |
The issue seems to be only with opening the wheel, but not writing files in the directory. This could be worked around by using extenal cache/files directory where it works fine as the source of the wheel file. Could be an installer thing. |
I'm trying to figure out the sysconfig.get_paths() for chaquopy. So far I've created these but I'm not 100% i'm using the right paths
|
14:00:14.425 18328 18328 E AndroidRuntime: com.chaquo.python.PyException: PermissionError: [Errno 13] Permission denied: '/data/data/dev.marcelnitan.r2droid/files/chaquopy_radare2-5.9.0-0-py3-none-android_21_arm64_v8a.whl'
04-27 14:00:14.425 18328 18328 E AndroidRuntime: at <python>.zipfile.__init__(zipfile.py:1284)
04-27 14:00:14.425 18328 18328 E AndroidRuntime: at <python>.installer.sources.open(sources.py:162)
04-27 14:00:14.425 18328 18328 E AndroidRuntime: at <python>.contextlib.__enter__(contextlib.py:137)
04-27 14:00:14.425 18328 18328 E AndroidRuntime: at <python>.init.install(init.py:84)
04-27 14:00:14.425 18328 18328 E AndroidRuntime: at <python>.init.<module>(init.py:116)
04-27 14:00:14.425 18328 18328 E AndroidRuntime: at <python>.importlib._bootstrap._call_with_frames_removed(<frozen importlib._bootstrap>:241)
04-27 14:00:14.425 18328 18328 E AndroidRuntime: at <python>.importlib._bootstrap_external.exec_module(<frozen importlib._bootstrap_external>:940)
04-27 14:00:14.425 18328 18328 E AndroidRuntime: at <python>.java.android.importer.exec_module(importer.py:634)
04-27 14:00:14.425 18328 18328 E AndroidRuntime: at <python>.java.android.importer.exec_module(importer.py:721)
04-27 14:00:14.425 18328 18328 E AndroidRuntime: at <python>.importlib._bootstrap._load_unlocked(<frozen importlib._bootstrap>:690)
04-27 14:00:14.425 18328 18328 E AndroidRuntime: at <python>.importlib._bootstrap._find_and_load_unlocked(<frozen importlib._bootstrap>:1147)
04-27 14:00:14.425 18328 18328 E AndroidRuntime: at <python>.importlib._bootstrap._find_and_load(<frozen importlib._bootstrap>:1176)
04-27 14:00:14.425 18328 18328 E AndroidRuntime: at <python>.importlib._bootstrap._gcd_import(<frozen importlib._bootstrap>:1204)
04-27 14:00:14.425 18328 18328 E AndroidRuntime: at <python>.importlib.import_module(__init__.py:126)
04-27 14:00:14.425 18328 18328 E AndroidRuntime: at <python>.chaquopy_java.Java_com_chaquo_python_Python_getModuleNative(chaquopy_java.pyx:129)
04-27 14:00:14.425 18328 18328 E AndroidRuntime: at com.chaquo.python.Python.getModuleNative(Native Method)
04-27 14:00:14.425 18328 18328 E AndroidRuntime: at com.chaquo.python.Python.getModule(Python.java:84)
04-27 14:00:14.425 18328 18328 E AndroidRuntime: at dev.marcelnitan.r2droid.tabs.HomeTab.Content(HomeTab.kt:48)
04-27 14:00:14.425 18328 18328 E AndroidRuntime: at cafe.adriel.voyager.navigator.tab.TabKt$CurrentTab$1.invoke(Tab.kt:13)
04-27 14:00:14.425 18328 18328 E AndroidRuntime: at cafe.adriel.voyager.navigator.tab.TabKt$CurrentTab$1.invoke(Tab.kt:12)
04-27 14:00:14.425 18328 18328 E AndroidRuntime: at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:109) |
This is the wheel installer script I have so far that can be called from java: # CREDITS: https://github.com/python-poetry/poetry/blob/ef75e7c85508cca498be7c630d8373a5c0b26586/src/poetry/installation/wheel_installer.py
from __future__ import annotations
import logging
from pathlib import Path
from typing import TYPE_CHECKING
from installer import install
from installer.destinations import SchemeDictionaryDestination
from installer.sources import WheelFile
from installer.sources import _WheelFileValidationError
logger = logging.getLogger(__name__)
if TYPE_CHECKING:
from collections.abc import Collection
from typing import BinaryIO
from installer.records import RecordEntry
from installer.utils import Scheme
class WheelDestination(SchemeDictionaryDestination):
""" """
def write_to_fs(
self,
scheme: Scheme,
path: str,
stream: BinaryIO,
is_executable: bool,
) -> RecordEntry:
from installer.records import Hash
from installer.records import RecordEntry
from installer.utils import copyfileobj_with_hashing
from installer.utils import make_file_executable
target_path = Path(self.scheme_dict[scheme]) / path
if target_path.exists():
# Contrary to the base library we don't raise an error here since it can
# break pkgutil-style and pkg_resource-style namespace packages.
logger.warning(f"Installing {target_path} over existing file")
parent_folder = target_path.parent
if not parent_folder.exists():
# Due to the parallel installation it can happen
# that two threads try to create the directory.
parent_folder.mkdir(parents=True, exist_ok=True)
with target_path.open("wb") as f:
hash_, size = copyfileobj_with_hashing(stream, f, self.hash_algorithm)
if is_executable:
make_file_executable(target_path)
return RecordEntry(path, Hash(self.hash_algorithm, hash_), size)
class WheelInstaller:
def __init__(self, prefix: Path) -> None:
self._bytecode_optimization_levels: Collection[int] = ()
self.invalid_wheels: dict[Path, list[str]] = {}
self.paths = {
'data': f"{prefix}/usr",
'include': f"{prefix}/usr/include",
'platinclude': f"{prefix}/usr/include/python3.11",
"platlib": f"{prefix}/chaquopy/AssetFinder/requirements/chaquopy_radare",
'platstdlib': f"{prefix}/usr/include",
'purelib': f"{prefix}/chaquopy/AssetFinder/requirements/chaquopy_radare",
'scripts': f"{prefix}/bin",
'stdlib': f"{prefix}/usr/include/python3.11"
}
def enable_bytecode_compilation(self, enable: bool = True) -> None:
self._bytecode_optimization_levels = (-1,) if enable else ()
def install(self, wheel: Path, interpreter: str = "str") -> None:
with WheelFile.open(wheel) as source:
try:
# Content validation is temporarily disabled because of
# pypa/installer's out of memory issues with big wheels. See
# https://github.com/python-poetry/poetry/issues/7983
source.validate_record(validate_contents=False)
except _WheelFileValidationError as e:
self.invalid_wheels[wheel] = e.issues
scheme_dict = self.paths.copy()
scheme_dict["headers"] = str(
Path(scheme_dict["include"]) / source.distribution
)
destination = WheelDestination(
scheme_dict,
interpreter=interpreter,
script_kind="posix",
bytecode_optimization_levels=self._bytecode_optimization_levels,
)
install(
source=source,
destination=destination,
additional_metadata={
},
) |
Are you sure that's actually the Or maybe you're somehow creating the wheel file without read permissions. If you still can't work it out, please post the code which puts the wheel file in that location, and calls |
Yes, I manually placed the file there and pasted the path to the install method in my python code. Well I just made the installation in the python code and just loaded the module to trigger it |
|
I think the issue is due adb pushing files there, java File can't read them either |
Strange: when I copy a file using Android Studio's Device Explorer, or with
You may need to change the permissions manually by running |
Does it even work with the root group and owner? Files written by the app have their own |
Regardless of who owns it, the third
But in your example, it's only readable by the root user and group:
You can change this with the
|
Ah ok. Anyway can I get the filesDir path in python if I have the context statically visible in a custom Application class in java? In short, accessing static classes defined in the java app in python |
Or even better the AssetsDir (python path) from Chaquopy |
You can get the The asset directory doesn't actually exist at runtime, because assets are read directly from the APK. If you want to access any data files from Python, put them in your Python source code directory as shown here. By the way, there's no need to quote a GitHub comment when you're replying directly below it, unless you want to reply to multiple points separately as I did here. Unnecessary quoting clutters the page and makes the conversation harder to follow. Just post your reply by itself. |
I'm thinking of adding plugin support to my application via pypi and I was wondering if it's possible to install a wheel package or pip package at runtime and then load it in the env.
Is something like this even possible?
The text was updated successfully, but these errors were encountered: