Now, you can run Python scripts with Java and Gradle builds only.
This Gradle Plugin automatically downloads and installs specific Conda tool
to run python scripts or other executables (pip, conda, mamba etc.) from virtual env.
All install files are downloaded from Miniforge conda distribution by default.
Python project configuration can be fully automated by Gradle tasks now.
You can also check my other plugin for the uv tool.
- Java
11or higher - Gradle
7.0or higher project
Running python scripts or projects by executing single task which will download and install Python virtual environment.
Additional Python configuration (pip/conda packages installation etc.) can be done by defining Gradle tasks
in build.gradle.kts file.
-
Apply a plugin to a project as described on gradle portal.
-
Configure a plugin by specifying desired python version in build script:
pythonPlugin { pythonVersion = "3.8.2" } -
Define a task to run desired python script, for example to run
quicksort.pyscript inmaindir add the following task configuration to build script:tasks { register<VenvTask>("runQuickSort") { workingDir = projectDir.resolve("main") args = listOf("quicksort.py") } } -
Run python script from gradle:
# Linux ./gradlew runQuickSort # Windows gradlew.bat runQuickSort
-
Wait until Conda is installed and environment set up.
Plugin default behavior can be adjusted by specifying the following properties:
pythonVersion-> Python environment version, default3.14.0,condaVersion-> Miniforge version, default25.3.1-0, the available ones can be checked at https://github.com/conda-forge/miniforge/releases,condaInstaller-> Conda environment installer name, default isMiniforge3,condaRepoUrl-> repository URL which should be used to download binaries, defaulthttps://github.com/conda-forge/miniforge/releases/download/condaRepoUsername-> username for the basic auth if needed, absent by defaultcondaRepoPassword-> password for the basic auth, used ifcondaRepoUsernameis specified, should not be passed directly in script file, can be supplied by gradle properties , absent by defaultcondaRepoHeaders-> additional optional headers used for connection, empty map by defaultuseHomeDir-> whentruethe default install directory will be the one fromuser.homesystem property,falseby defaultinstallDir-> property to customize conda installation directory, equals to<rootProjectDir>/.gradle/pythonby default or user home ifuseHomeDir=truesystemArch-> operating system architecture, default is got fromos.archsystem propertyideaDir-> target.ideadirectory to detect Intellij project, equals to<rootProjectDir>/.ideaby default
Sample extension configuration inside of build.gradle.kts file:
pythonPlugin {
pythonVersion = "3.7.0"
condaVersion = "2022.05"
condaInstaller = "Miniforge3"
condaRepoUrl = "https://nexus.com/repositories/conda"
condaRepoUsername = "user"
condaRepoPassword = extra["conda.repo.pass"].toString()
condaRepoHeaders = mapOf(
"CUSTOM_HEADER_1" to "headerValue1",
"CUSTOM_HEADER_2" to "headerValue2"
)
installDir = file(layout.buildDirectory.dir("python"))
systemArch = "arm64"
}All tasks which should be executed in virtual env can be customized as well by the following fields:
venvExec-> name of executable from virtual env which will be executed,pythonby defaultinputFile-> optional input file, none by defaultoutputFile-> optional output file, none by defaultargs-> list of arguments for avenvExecexecutable, empty by defaultworkingDir-> working directory, project directory by defaultenvironment-> map with environment variables to apply during the execution, empty by default
Sample VenvTask configuration inside of build.gradle.kts file:
register<VenvTask>("runPythonScript") {
venvExec = "python"
inputFile = file("inputFile.txt")
outputFile = file("outputFile.txt")
args = listOf("--some-flag", "arg1")
workingDir = projectDir.resolve("main")
environment = mapOf("ENV_VAR_TO_PRINT" to "sampleEnvVar")
}Additional examples alongside with sample PipTasks configurations can be found in examples module in this project.
Integration with the existing Python projects can also be done within a separate Gradle module.
An example can be found here.
By simply running the runDemoScript Gradle task user can bootstrap the whole project locally or in Docker container
via runDemoContainer task.
Auto import installed Python SDK:
- Install SDK-Import Intellij Plugin.
- Execute gradle
envSetuptask. - Choose from "Tools" -> "Reimport SDK" to import installed Python SDK with plugin.
Manual way:
- To have autocomplete and modules properly recognized in Intellij Idea point to Conda environment as described in: https://www.jetbrains.com/help/idea/configuring-python-sdk.html
- To have properly recognized imported source modules in tests, right click on sources directory (for example
main) ->Mark Directory as->as Sources root.
-
Linux -
<installDir>/.gradle/python/Linux/<condaInstaller>-<condaVersion> -
Windows -
<installDir>/.gradle/python/Windows/<condaInstaller>-<condaVersion> -
MacOSX -
<installDir>/.gradle/python/MacOSX/<condaInstaller>-<condaVersion>
Where <installDir> is the root catalog where the Conda will be installed specified by installDir property,
<condaInstaller> is Conda installer e.g. Miniconda3 and <condaVersion> is Conda installer version e.g.
py38_4.8.3
If you are familiar with conda you can also execute
conda commands like conda deactivate or conda install directly with the binaries from the catalogs above.
-
It may be required to unset
PYTHONPATHin system before running any tasks (https://stackoverflow.com/a/31841132) -
You can also run some simple inline Python scripts inside build files like this:
Intellij 'inject language' feature can be useful in such scenario :)
-
/usr/bin/env: ‘python’: No such file or directorywhen executingenvSetuptask -> It is related to the shebang char limit which is 128.When installing the conda if the prefix path is longer than the limit the default shebang (
#!/usr/bin/env python) is being used in the installed conda script file (condabin/conda). Since no python binary is accessible by this path the exception is being thrown.The easiest solution is to store the root project at the shortest possible path or use the
installDirto specify shorter path per particular troublesome subproject.
