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:

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.

Write files in Python

Use os.environ["HOME"], as described in the “os” section.

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:

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.

FileNotFoundError

See the questions above about reading and writing files.

Read-only file system

See the question above about writing files.

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.