Workflow templates (train / hpo / predict) + CLI entry template#
Workflow templates are shipped as package data under
_templates/workflow/. They are designed to be copied into any project
directory and executed directly.
Each script follows canonical CLI structure:
parse_args(argv=None)main(argv=None) -> intif __name__ == "__main__": raise SystemExit(main())
This example lists workflows and copies one workflow to a temporary folder.
It also shows how to compile a Cython extension (a .so/.pyd) and import
it from the copied workflow directory:
Single-module compile → copy artifact next to workflow → import by path.
Multi-module package build → copy package folder → import via sys.path.
Notes#
Compilation requires a working compiler toolchain and Python headers. During Sphinx-Gallery builds, we skip compilation cleanly if prerequisites are missing.
# Authors: The scikit-plots developers
# SPDX-License-Identifier: BSD-3-Clause
Generate Workflow Package wf_ext_pkg#
Copy template workflow in local or use exist from local folder.
workflows = getattr(cython, "list_workflows", lambda: [])()
print("Workflows:", workflows)
if not workflows:
print("No workflow templates bundled in this build.")
else:
wf = workflows[0]
with tempfile.TemporaryDirectory(dir=".") as tmp:
dest = Path(tmp) / "workflow_copy"
cython.copy_workflow(wf, dest_dir=dest, overwrite=True)
print("Copied workflow to:", dest)
print("Files:", sorted(p.name for p in dest.rglob("*.py")))
# Show how users would run the CLI entrypoint.
cli = dest / "cli.py"
print("\nRun:")
print(f" python {cli} train --help")
print(f" python {cli} hpo --help")
print(f" python {cli} predict --help")
# ------------------------------------------------------------
# Optional: compile and import a .so/.pyd into this copied folder
# ------------------------------------------------------------
# prereqs = getattr(cython, "check_build_prereqs", lambda **_: {"ok": False})()
report = cython.check_build_prereqs(numpy=False)
if not report.get('cython', {}).get('ok'):
print("\nBuild prerequisites not available; skipping compilation demo.")
# Print a compact diagnostic (safe for docs output)
problems = report.get("problems", [])
if problems:
print("Prereq problems:", problems)
else:
# 1) Single-module extension compile -> copy artifact -> import by path
code = (
"def square(int n):\n"
" return n*n\n"
)
res = cython.compile_and_load_result(
code,
module_name="wf_ext_square",
profile="fast-debug",
numpy_support=True,
numpy_required=False,
)
artifact_copy = dest / res.artifact_path.name
artifact_copy.write_bytes(res.artifact_path.read_bytes())
# Import the compiled extension from the copied workflow directory.
m = cython.import_artifact_path(artifact_copy, module_name=res.module_name)
print("\nSingle-module extension imported from copied folder:")
print(" m.square(12) =", m.square(12))
# 2) Multi-module package build -> copy package folder -> import via sys.path
# This creates a package with two extension modules:
# wf_ext_pkg.alpha
# wf_ext_pkg.beta
pkg = cython.build_package_from_code_result(
package_name="wf_ext_pkg",
modules={
"alpha": "def inc(int n):\n return n + 1\n",
"beta": "def dec(int n):\n return n - 1\n",
},
profile="fast-debug",
numpy_support=True,
numpy_required=False,
)
# Copy the built package directory into the workflow folder.
pkg_src_dir = pkg.build_dir / pkg.package_name
pkg_dst_dir = dest / pkg.package_name
# Strict copy (no heuristics): recreate files.
pkg_dst_dir.mkdir(parents=True, exist_ok=True)
for p in pkg_src_dir.rglob("*"):
rel = p.relative_to(pkg_src_dir)
out = pkg_dst_dir / rel
if p.is_dir():
out.mkdir(parents=True, exist_ok=True)
else:
out.write_bytes(p.read_bytes())
# Now import it like a normal package by adding `dest` to sys.path.
sys.path.insert(0, str(dest))
try:
import wf_ext_pkg.alpha as alpha # type: ignore
import wf_ext_pkg.beta as beta # type: ignore
print("\nPackage extension imported from copied folder:")
print(" alpha.inc(10) =", alpha.inc(10))
print(" beta.dec(10) =", beta.dec(10))
finally:
# Clean up sys.path modification
if sys.path and sys.path[0] == str(dest):
sys.path.pop(0)
Workflows: ['churn_basic']
Copied workflow to: tmp8d8j26tu/workflow_copy
Files: ['cli.py', 'hpo.py', 'predict.py', 'train.py']
Run:
python tmp8d8j26tu/workflow_copy/cli.py train --help
python tmp8d8j26tu/workflow_copy/cli.py hpo --help
python tmp8d8j26tu/workflow_copy/cli.py predict --help
Single-module extension imported from copied folder:
m.square(12) = 144
Compiling /home/circleci/.cache/scikitplot/cython/09a9a53b1ba1091db9dae48a27cd6d2a9216a189a623b132a7c025b84d659433/wf_ext_pkg/alpha.pyx because it changed.
Compiling /home/circleci/.cache/scikitplot/cython/09a9a53b1ba1091db9dae48a27cd6d2a9216a189a623b132a7c025b84d659433/wf_ext_pkg/beta.pyx because it changed.
[1/2] Cythonizing /home/circleci/.cache/scikitplot/cython/09a9a53b1ba1091db9dae48a27cd6d2a9216a189a623b132a7c025b84d659433/wf_ext_pkg/alpha.pyx
[2/2] Cythonizing /home/circleci/.cache/scikitplot/cython/09a9a53b1ba1091db9dae48a27cd6d2a9216a189a623b132a7c025b84d659433/wf_ext_pkg/beta.pyx
Package extension imported from copied folder:
alpha.inc(10) = 11
beta.dec(10) = 9
Total running time of the script: (0 minutes 1.250 seconds)
Related examples