Class GraalPyResources
- Python application files
- Third-party Python packages
Resource files can be embedded and distributed in an application file or made available from an external directory.
Virtual Filesystem
If the resource files are part of an application file (jar file or a
native image executable), then at runtime they will be accessed as standard
Java resources through GraalPy VirtualFileSystem. This will be
transparent to Python code running in GraalPy so that it can use standard
Python IO to access those files.
In order to make this work, it is necessary for those embedded resources to
have a common resource root directory. The default value is
/org.graalvm.python.vfs, however the recommended convention is
to use GRAALPY-VFS/{groupId}/{artifactId}. This root directory will
then be in python code mapped to the virtual filesystem mount point,
by default /graalpy_vfs. Refer to
VirtualFileSystem.Builder.resourceDirectory(String) documentation for
more details.
External Directory
As an alternative to Java resources with the Virtual Filesystem, it is also possible to configure the GraalPy context to use an external directory, which is not embedded as a Java resource into the resulting application. Python code will access the files directly from the real filesystem.
Conventions
The factory methods in GraalPyResources rely on the following conventions:
- ${resources_root}/src: used for Python application files. This directory will be configured as the default search path for Python module files (equivalent to PYTHONPATH environment variable).
- ${resources_root}/venv: used for the Python virtual environment holding installed third-party Python packages. The Context will be configured as if it is executed from this virtual environment. Notably packages installed in this virtual environment will be automatically available for importing.
/org.graalvm.python.vfs or an external directory.
Example creating a GraalPy context configured for the usage with a
VirtualFileSystem:
VirtualFileSystem.Builder builder = VirtualFileSystem.newBuilder();
builder.unixMountPoint("/python-resources");
VirtualFileSystem vfs = builder.build();
try (Context context = GraalPyResources.contextBuilder(vfs).build()) {
context.eval("python", "for line in open('/python-resources/data.txt').readlines(): print(line)");
} catch (PolyglotException e) {
if (e.isExit()) {
System.exit(e.getExitStatus());
} else {
throw e;
}
}
In this example we:
- create a
VirtualFileSystemconfigured to have the root/python-resources - create a GraalPy context preconfigured with that
VirtualFileSystem - use the context to invoke a python snippet reading a resource file
GraalPy context instances created by factory methods in this class are preconfigured with some particular resource paths:
${resources_root}/venv- is reserved for a python virtual environment holding third-party packages. The context will be configured as if it were executed from this virtual environment. Notably packages installed in this virtual environment will be automatically available for importing.${resources_root}/src- is reserved for python application files - e.g. python sources. GraalPy context will be configured to see those files as if set in PYTHONPATH environment variable.
${resources_root} is either an external directory or the
virtual filesystem resource root /org.graalvm.python.vfs.
Example creating a GraalPy context configured for the usage with an external resource directory:
try (Context context = GraalPyResources.contextBuilder(Path.of("python-resources")).build()) {
context.eval("python", "import mymodule; mymodule.print_hello_world()");
} catch (PolyglotException e) {
if (e.isExit()) {
System.exit(e.getExitStatus());
} else {
throw e;
}
}
In this example we:
- create a GraalPy context which is preconfigured with GraalPy resources in an external resource directory
- use the context to import the python module
mymodule, which should be either located inpython-resources/srcor in a python package installed inpython-resources/venv(python virtual environment)
For more examples on how to use this class refer to GraalPy Demos and Guides.
- Since:
- 24.2.0
- See Also:
-
Method Summary
Modifier and TypeMethodDescriptionstatic org.graalvm.polyglot.Context.BuilderCreates a GraalPy context builder preconfigured with aVirtualFileSystemand other GraalPy and polyglot Context configuration options optimized for the usage of the Python virtual environment contained in the virtual filesystem.static org.graalvm.polyglot.Context.BuildercontextBuilder(Path externalResourcesDirectory) Creates a GraalPy context preconfigured with GraalPy and polyglot Context configuration options for use with resources located in an external directory in real filesystem.static org.graalvm.polyglot.Context.BuilderCreates a GraalPy context builder preconfigured with the givenVirtualFileSystemand other GraalPy and polygot Context configuration options optimized for the usage of the Python virtual environment contained in the virtual filesystem.static org.graalvm.polyglot.ContextCreates a GraalPy context preconfigured with aVirtualFileSystemand other GraalPy and polyglot Context configuration options optimized for the usage of the Python virtual environment contained in the virtual filesystem.static voidextractVirtualFileSystemResources(VirtualFileSystem vfs, Path externalResourcesDirectory) Extract Python resources which are distributed as part of a jar file or a native image executable into a directory.static PathDetermines a native executable path if running inImageInfo.inImageRuntimeCode().
-
Method Details
-
createContext
public static org.graalvm.polyglot.Context createContext()Creates a GraalPy context preconfigured with aVirtualFileSystemand other GraalPy and polyglot Context configuration options optimized for the usage of the Python virtual environment contained in the virtual filesystem.Following resource paths are preconfigured:
/org.graalvm.python.vfs/venv- is set as the python virtual environment location/org.graalvm.python.vfs/src- is set as the python sources location
When the virtual filesystem is located in other than the default resource directory,
org.graalvm.python.vfs, i.e., using Maven or Gradle optionresourceDirectory, usecontextBuilder(VirtualFileSystem)andVirtualFileSystem.Builder.resourceDirectory(String)when building theVirtualFileSystem.- Returns:
- a new
Contextinstance - Since:
- 24.2.0
-
contextBuilder
public static org.graalvm.polyglot.Context.Builder contextBuilder()Creates a GraalPy context builder preconfigured with aVirtualFileSystemand other GraalPy and polyglot Context configuration options optimized for the usage of the Python virtual environment contained in the virtual filesystem.Following resource paths are preconfigured:
/org.graalvm.python.vfs/venv- is set as the python virtual environment location/org.graalvm.python.vfs/src- is set as the python sources location
Example creating a GraalPy context and overriding the verbose option.
Context.Builder builder = GraalPyResources.contextBuilder().option("python.VerboseFlag", "true"); try (Context context = builder.build()) { context.eval("python", "print('hello world')"); } catch (PolyglotException e) { if (e.isExit()) { System.exit(e.getExitStatus()); } else { throw e; } }When the virtual filesystem is located in other than the default resource directory,
org.graalvm.python.vfs, i.e., using Maven or Gradle optionresourceDirectory, usecontextBuilder(VirtualFileSystem)andVirtualFileSystem.Builder.resourceDirectory(String)when building theVirtualFileSystem.- Returns:
- a new
Context.Builderinstance - Since:
- 24.2.0
- See Also:
-
contextBuilder
Creates a GraalPy context builder preconfigured with the givenVirtualFileSystemand other GraalPy and polygot Context configuration options optimized for the usage of the Python virtual environment contained in the virtual filesystem.Following resource paths are preconfigured:
/org.graalvm.python.vfs/venv- is set as the python virtual environment location/org.graalvm.python.vfs/src- is set as the python sources location
Example creating a GraalPy context configured for the usage with a virtual
FileSystem:VirtualFileSystem.Builder vfsBuilder = VirtualFileSystem.newBuilder(); vfsBuilder.unixMountPoint("/python-resources"); VirtualFileSystem vfs = vfsBuilder.build(); Context.Builder ctxBuilder = GraalPyResources.contextBuilder(vfs); try (Context context = ctxBuilder.build()) { context.eval("python", "for line in open('/python-resources/data.txt').readlines(): print(line)"); } catch (PolyglotException e) { if (e.isExit()) { System.exit(e.getExitStatus()); } else { throw e; } }In this example we:- create a
VirtualFileSystemconfigured to have the root/python-resources - create a GraalPy context preconfigured with that
VirtualFileSystem - use the context to invoke a python snippet reading a resource file
- Parameters:
vfs- theVirtualFileSystemto be used with the createdContext- Returns:
- a new
Context.Builderinstance - Since:
- 24.2.0
- See Also:
-
contextBuilder
Creates a GraalPy context preconfigured with GraalPy and polyglot Context configuration options for use with resources located in an external directory in real filesystem.Following resource paths are preconfigured:
${externalResourcesDirectory}/venv- is set as the python virtual environment location${externalResourcesDirectory}/src- is set as the python sources location
Example
Context.Builder builder = GraalPyResources.contextBuilder(Path.of("python-resources")); try (Context context = builder.build()) { context.eval("python", "import mymodule; mymodule.print_hello_world()"); } catch (PolyglotException e) { if (e.isExit()) { System.exit(e.getExitStatus()); } else { throw e; } }In this example we:- create a GraalPy context which is preconfigured with GraalPy resources in an external resource directory
- use the context to import the python module
mymodule, which should be either located inpython-resources/srcor in a python package installed in/python/venv(python virtual environment) - note that in this scenario, the Python context has access to the extracted resources as well as the rest of the real filesystem
External resources directory is often used for better compatibility with Python native extensions that may bypass the Python abstractions and access the filesystem directly from native code. Setting the
PosixModuleBackendoption to "native" increases the compatibility further, but in such case even Python code bypasses the Truffle abstractions and accesses native POSIX APIs directly. Usage:GraalPyResources.contextBuilder(Path.of("python-resources")).option("python.PosixModuleBackend", "native")When Maven or Gradle GraalPy plugin is used to build the virtual environment, it also has to be configured to generate the virtual environment into the same directory using the
<externalDirectory>tag in Maven or theexternalDirectoryfield in Gradle.- Parameters:
externalResourcesDirectory- the root directory with GraalPy specific embedding resources- Returns:
- a new
Context.Builderinstance - Since:
- 24.2.0
-
getNativeExecutablePath
Determines a native executable path if running inImageInfo.inImageRuntimeCode().Example creating a GraalPy context preconfigured with an external resource directory located next to a native image executable.
Path resourcesDir = GraalPyResources.getNativeExecutablePath().getParent().resolve("python-resources"); try (Context context = GraalPyResources.contextBuilder(resourcesDir).build()) { context.eval("python", "print('hello world')"); }- Returns:
- the native executable path if it could be retrieved, otherwise
null. - Since:
- 24.2.0
- See Also:
-
extractVirtualFileSystemResources
public static void extractVirtualFileSystemResources(VirtualFileSystem vfs, Path externalResourcesDirectory) throws IOException Extract Python resources which are distributed as part of a jar file or a native image executable into a directory. This can be useful to manage and ship resources with the Maven workflow, but use them (cached) from the real filesystem for better compatibility.The structure of the created resource directory will stay the same like the embedded Python resources structure:
${externalResourcesDirectory}/venv- the python virtual environment location${externalResourcesDirectory}/src- the python sources location
Example
Path resourcesDir = Path.of(System.getProperty("user.home"), ".cache", "my.java.python.app.resources"); VirtualFileSystem vfs = VirtualFileSystem.newBuilder().build(); GraalPyResources.extractVirtualFileSystemResources(vfs, resourcesDir); try (Context context = GraalPyResources.contextBuilder(resourcesDir).build()) { context.eval("python", "print('hello world')"); }- Parameters:
vfs- theVirtualFileSystemfrom which resources are to be extractedexternalResourcesDirectory- the target directory to extract the resources to- Throws:
IOException- if resources isn't a directory- Since:
- 24.2.0
- See Also:
-