From d2adf152ea5c8b38d9a7e1564c09fe77264f5df9 Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Wed, 18 Mar 2026 20:39:03 -0500 Subject: [PATCH] WIP: Add support for more builder parameters * conda - for conda-forge packages * pypi - for PyPI packages * python - for Python version --- README.md | 26 ++++++++++ .../python/ApposePythonScriptEngine.java | 50 ++++++++++++++++--- 2 files changed, 69 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index b55e868..725a3db 100644 --- a/README.md +++ b/README.md @@ -19,3 +19,29 @@ the SciJava Common wiki. See also: * [Python Scripting](https://imagej.net/scripting/python) on the ImageJ wiki. + +## Example + +```python +#@script (language="appose-python", pypi=["cellcast"]) + +#@ Img image + +#@ Double (value=1.0, description="minimum percentile value for normalization") pmin +#@ Double (value=99.8, description="maximum percentile value for normalization") pmax +#@ Double (value=0.479, description="Polygon probability threshold") prob_threshold +#@ Double (value=0.3, description="Non-Maximum Suppression threshold") nms_threshold +#@ Boolean (value=true, description="Set True for GPU inference via WebGPU, False for CPU inference") gpu + +#@output Img labels + +import cellcast.models.stardist_2d as stardist +labels = stardist.predict_versatile_fluo( + image, + pmin, + pmax, + prob_threshold, + nms_threshold, + gpu, +) +``` diff --git a/src/main/java/org/scijava/plugins/scripting/appose/python/ApposePythonScriptEngine.java b/src/main/java/org/scijava/plugins/scripting/appose/python/ApposePythonScriptEngine.java index 60ee909..30ee90b 100644 --- a/src/main/java/org/scijava/plugins/scripting/appose/python/ApposePythonScriptEngine.java +++ b/src/main/java/org/scijava/plugins/scripting/appose/python/ApposePythonScriptEngine.java @@ -237,18 +237,49 @@ private Environment buildEnvironment(final ScriptInfo info) throws ScriptException { if (info == null) return null; - final String envRef = info.get("env"); - if (envRef == null) return null; - final File envFile = resolveEnvFile(envRef, info.getPath()); + final String envValue = info.get("env"); + final File envFile = envValue == null ? null : resolveEnvFile(envValue, info.getPath()); final String envName = sanitizeEnvName(info.getPath()); + final String scheme = info.get("scheme"); + final List pypi = toListOfStrings(info.get("pypi")); + final List conda = toListOfStrings(info.get("conda")); + final String python = info.get("python"); + log.info("Building Appose environment: " + envName); - try { - String scheme = info.get("scheme"); - Builder builder = scheme == null ? - Appose.file(envFile) : Appose.file(envFile).scheme(scheme); + try { + final Builder builder; + if (envFile == null) { + // No environment file given -- use inline builder. + if (conda.isEmpty()) { + // No conda packages required -- use uv. + String[] pypiPkgs = pypi.toArray(new String[0]); + builder = python == null ? + Appose.uv().include(pypiPkgs) : + Appose.uv().python(python).include(pypiPkgs); + } + else { + // Conda packages specified -- use pixi. + List condaPkgList = new ArrayList<>(); + if (conda.stream().anyMatch(v -> v.matches("python\\b.*"))) { + // Python was not included in the conda package list -- add it manually. + // If python version value was given, use that, otherwise open-ended. + condaPkgList.add(python != null ? "python=" + python : "python"); + } + condaPkgList.addAll(conda); + String[] condaPkgs = condaPkgList.toArray(new String[0]); + String[] pypiPkgs = pypi.toArray(new String[0]); + builder = Appose.pixi().conda(condaPkgs).pypi(pypiPkgs); + } + } + else { + // Build with the given environment file. + builder = scheme == null ? + Appose.file(envFile) : + Appose.file(envFile).scheme(scheme); + } return builder.name(envName).build(); } catch (final BuildException e) { @@ -259,6 +290,11 @@ private Environment buildEnvironment(final ScriptInfo info) } } + private List toListOfStrings(String value) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'toListOfStrings'"); + } + /** Resolves an (optionally relative) env file path against the script path. */ private static File resolveEnvFile(final String envRef, final String scriptPath)