FAQ¶
General¶
What does Chaquopy’s name mean?¶
It comes from Jack London’s use of the word “chechaquo” (now usually spelled “cheechako”), a Native American term meaning “newcomer”. We chose it to reflect our goal of opening up new frontiers in how Python can be used.
Does Chaquopy support React Native?¶
Yes, it can be used with any framework which lets you do the following:
Add content to your app’s build.gradle files.
Call Java methods.
Does Chaquopy support iOS?¶
Not at the moment. For a list of ways to use Python in iOS apps, see the Python wiki (“iOS” column on the right).
One good option is the BeeWare framework. For example, have a look at the Electron Cash iOS app (source code, App Store), which you can compare with the similar Chaquopy-based Android app (source code, Google Play).
How can I make my app smaller?¶
If your app uses TensorFlow, consider replacing it with TensorFlow Lite:
Install it by adding
tflite-runtime
to the pip block of your build.gradle file.Convert your model to tflite format.
Run your model using the tflite API.
More generally, try reducing the number of ABIs in your APK. Because of the way Chaquopy packages its native components, the APK splits and app bundle features won’t help much. Instead, use a product flavor dimension to build separate APKs or app bundles for each ABI. If you plan to release your app on Google Play, each flavor must also have a different version code. For example:
android {
def versionBase = 123
flavorDimensions "abi"
productFlavors {
arm32 {
dimension "abi"
ndk { abiFilters "armeabi-v7a" }
versionCode 1000000 + versionBase
}
arm64 {
dimension "abi"
ndk { abiFilters "arm64-v8a" }
versionCode 2000000 + versionBase
}
}
}
How do I …¶
Read files in Python¶
To read a file from your source code directory, use a path relative to __file__
, as described
in the “Data files” section.
To upload files to the device while your app is running, use os.environ["HOME"]
and the
Device File Explorer, as described in the “os” section.
To read photos, downloads, and other files from the external storage directory (“sdcard”), see the question below.
Read files from external storage (“sdcard”)¶
Since API level 29, Android has a scoped storage policy which prevents direct
access to external storage, even if your app has the READ_EXTERNAL_STORAGE
permission.
Instead, you can use the system file picker, and pass the
file to Python as a byte array:
val REQUEST_OPEN = 0
fun myMethod() {
startActivityForResult(
Intent(if (Build.VERSION.SDK_INT >= 19) Intent.ACTION_OPEN_DOCUMENT
else Intent.ACTION_GET_CONTENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
setType("*/*")
}, REQUEST_OPEN)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == REQUEST_OPEN && resultCode == RESULT_OK) {
val uri = data!!.data!!
// For Java, see https://stackoverflow.com/a/10297073
val content = contentResolver.openInputStream(uri)!!.use { it.readBytes() }
myPythonModule.callAttr("process", content)
}
}
The Python function can then access the file content however you like:
def process(content):
# `content` is already a bytes-like object, but if you need a standard bytes object:
content = bytes(content)
# If you need a file-like object:
import io
content_file = io.BytesIO(content)
# If you need a filename (less efficient):
import tempfile
with tempfile.NamedTemporaryFile() as temp_file:
temp_file.write(content)
filename = temp_file.name # Valid only inside the `with` block.
Pass images to/from Python¶
The easiest way is to encode the image as a PNG or JPG file and pass it as a byte array. For an example of this, see the chaquopy-matplotlib app.
You may get better performance by passing the raw image data as an array, but then you’ll be responsible for using the correct image dimensions and pixel format.
Call back from Python¶
There are many ways of doing this: here’s one example from the Electron Cash project:
Kotlin code passes a method reference to Python.
The Python code creates a background thread which later calls the method using normal Python syntax.
Build errors¶
First, make sure you’re seeing the complete build log in Android Studio:
In version 3.6 and newer, click the “Build: failed” caption to the left of the message.
In version 3.5 and older, click the “Toggle view” button to the left of the message.
Chaquopy cannot compile native code¶
You’re trying to install a native package which we haven’t built yet. There may be a different version available, in which case there will be a “pre-built wheels” message in the build log. Otherwise, please visit our issue tracker for help.
No Python interpreter configured for the module¶
This message is harmless: see the “Android Studio plugin” section.
No version of NDK matched the requested version¶
This can be fixed by installing the NDK version mentioned in the message, or upgrading to Android Gradle plugin version 4.1 or later.
The warning “Compatible side by side NDK version was not found” is harmless, but can be resolved in the same ways.
Runtime errors¶
Depending on your Android version, a crashing app may show a message that it “has stopped” or “keeps stopping”, or the app might just disappear. Either way, you can find the stack trace in the Logcat. Some of the most common exceptions are listed below.
ModuleNotFoundError¶
Make sure you’ve built all required packages into your app using the pip block in your build.gradle file.
No address associated with hostname¶
Make sure your app has the INTERNET permission, and the device has Internet access.