GraalPy Quick Reference

Olga Gupalo
graalvm
Published in
6 min readOct 18, 2023

--

Co-authored by Tim Felgentreff, the lead of GraalPy development at Oracle

GraalPy is a Python 3 implementation built on GraalVM. It is under active development, showing significant performance improvements over other Python implementations. You can use GraalPy in many ways, for example: as a direct replacement for your current Jython or CPython runtime; to run Python native extensions like NumPy, SciPy, or Matplotlib in a managed Java application; to create native binaries; and so on.

The goal of this post is to help developers get started with GraalPy. We’ve assembled the most useful GraalPy information in a one-page summary, and the remainder of this post digs into its details.

GraalPy 23.1 Quick Reference

This quick reference card fits well on A4 paper so you can download and print it out. Be sure to use the PDF version for printing. If you use US letter paper format instead, make sure you get that version.

There are different versions of GraalPy, depending on your needs. It comes as two distributions:

  • Oracle GraalPy
  • GraalPy Community

Oracle GraalPy is significantly faster than GraalPy Community, and is free for development and production use (licensed under the GraalVM Free Terms and Conditions (GFTC) license). To distinguish between them, the name of the GraalPy Community distribution has a-community suffix.

Each distribution comes as two runtimes:

  • Native
  • JVM

The native runtime is most compatible with CPython. It runs as an ahead-of-time compiled Python launcher, which starts up faster and uses less memory.

The JVM runtime can interoperate with Java and other GraalVM languages can be added to it. You can identify it by the -jvm suffix in its name.

Installing

To install GraalPy on Linux or macOS, we recommend pyenv, the Python version manager. By default, it provides you with a GFTC-licensed native version, perfect as a drop-in replacement for CPython. To install version 23.1.0, run the following command:

pyenv install graalpy-23.1.0

You can also install the GraalPy Community distribution. Pyenv calls this graalpy-community-23.1.0. GraalPy Community is also available on Conda Forge. To install the latest version, use the following command:

conda create -c conda-forge -n graalpy graalpy

Alternatively, visit the GraalPy releases page and download GraalPy for your operating system. Note that on Windows you cannot install native extensions (like NumPy), but you can install pure Python packages via pip. Unzip the archive and, if you prefer, set the environment variables to point to GraalPy. Inside the bin directory you can find the following launchers: graalpy, python, and python3. They accept the same command-line options as the standard CPython.

graalpy <options> <-c cmd | filename>

The graalpy-lt launcher compiles native extensions with the GraalVM LLVM toolchain for better debugging and improved sandboxing, at the cost of performance and memory footprint. The Oracle GraalPy distrubution also includes graalpy-managed. This launcher uses the GraalVM LLVM toolchain as well to compile native extensions, but additionally runs them in a managed mode where all native libraries down to libc are executed from bitcode to improve security. This comes at significant performance cost and reduced compatibility.

You can also build GraalPy from source on Linux, macOS, and Windows.

GraalPy Environment Setup

Setting up a project usually starts with creating a virtual environment and installing desired packages like NumPy or PyTorch, either directly or via requirements.txt.

graalpy -m venv my_project

source my_project/bin/activate

graalpy -m pip install numpy torch -r requirements.txt

We recommend using our Python Compatibility Checker as the initial tool to see if a package is compatible with GraalPy.

GraalPy: Package Compatibility

Note that most native extension packages do not publish binaries for GraalPy, so they will automatically attempt to compile them on the user machine on installation. Make sure you have all libraries and development tools installed. Refer to the various projects’ documentations for details or ask us on our public Slack.

Development Setup

We recommend PyCharm for GraalPy development. To set up GraalPy as your development environment in PyCharm, follow these steps:

  1. Install GraalPy.
  2. Install PyCharm. (For more information, see Install PyCharm.)
  3. Create, or open, a Python project. (For more information, see Create a Python project, or Open, reopen, and close projects, respectively.)
  4. Create a new venv virtual environment for your Python project. (For more information, see Create a virtualenv environment.)
  5. Install packages by following the PyCharm instructions. (For more information, see Install, uninstall, and upgrade packages.)

The PyCharm tools for running, debugging, and profiling work as they should for GraalPy. Of course, you can also set up GraalPy in other code editors such as VS Code. Refer to the manual of the editor on how to select the Python interpreter, and point it to the GraalPy python executable.

Deployment

A GraalPy application can be deployed like any other Python application. In addition, GraalPy provides a tool to create a standalone binary from your Python application with a main script. Just run the following command to produce a my_application binary that includes all Python dependencies and GraalPy itself. It can be distributed without additional dependencies:

graalpy -m standalone native \
--output my_application \
--module my_python_script.py
--venv <venv-dir>

This can be used to deploy entire games and their assets, such as this one for example — the missing universal deployment option for Python:

A PyGame racer that can be deployed as a single self-contained binary with GraalPy

Embed in Java

GraalPy can be embedded into a Java application thanks to the GraalVM Polyglot API. In this way, GraalPy brings dynamic scripting and modern data science libraries closer to Java! To demonstrate this, create an example Java application using the GraalPy standalone tool:

graalpy -m standalone polyglot_app --output-directory MyPythonJavaEmbedding

It creates a Maven project skeleton with Python dependencies that can be used to further develop the embedding. View the generated pom.xml file to add Python packages, and the generated main function to see how Python can be used from Java. Package the application and run: mvn exec:exec. This works even with OpenJDK, but a GraalVM JDK offers much higher performance for Python code running on GraalPy.

To embed Python in an existing Java application, add GraalPy as a Maven or Gradle build tool dependency or explicitly put the GraalPy JAR files on the module path — you will need at least the python-language and python-resource JAR files from Maven Central.

Maven configuration:

<dependency>
<groupId>org.graalvm.polyglot</groupId>
<artifactId>polyglot</artifactId>
<version>23.1.0</version>
</dependency>
<dependency>
<groupId>org.graalvm.polyglot</groupId>
<artifactId>python</artifactId>
<version>23.1.0</version>
<type>pom</type>
</dependency>

Gradle configuration:

dependencies {
implementation("org.graalvm.polyglot:polyglot:23.1.0")
implementation("org.graalvm.polyglot:js:23.1.0")
testImplementation("junit:junit:4.13.2")
}

As of GraalVM Polyglot API version 23.1, all necessary artifacts can be downloaded directly from Maven Central. All artifacts relevant to embedders can be found in the Maven dependency group org.graalvm.polyglot. See the polyglot embedding demonstration on GitHub for a complete configuration example.

Options Specific to GraalPy

Unlike other Python implementations, you can debug Python code with the Chrome Inspector! This makes a simple graphical debugger available even when not running with an IDE such as PyCharm.

graalpy --inspect your_script.py

GraalPy also works with PyCharm and Python debuggers like pdb.

GraalPy uses a garbage collector that reserves memory based on the amount of total system memory. By default it will use much more memory than CPython if available, to improve performance by unnecessarily running the garbage collector too often. The GC can be tweaked using Java options. For example, you can use --vm.Xmx1G to restrict GraalPy to use a maximum of 1 gigabyte of heap memory. Total memory usage may be more if native code such as NumPy or PyTorch directly request memory from the system.

GraalPy uses a JIT compiler which may use multiple cores to compile code. For short running scripts, the compiler may not have time to help before the script is finished. In such cases, JIT compilation can be disabled with --experimental-options --engine.Compilation=false. This option should be used with caution and its benefit depends very much on the concrete workload, so it is marked as experimental.

Summary

In this blog post we illustrated the most useful developer information about GraalPy, squeezed into a single sheet of paper that you can print and use as a quick reference. Try running your Python application with a high-performance and modern GraalPy!

--

--