← Files JinkōARCHIVED FILE
skills/jinko-calibration-subsampling/scripts/create_subsampling_design.py
6.23 KB · Oct 5, 2026 · 18:30 UTC
#!/usr/bin/env python3
"""Create a Jinkō subsampling design from a completed Trial.
Dry-run by default. Pass --apply to create the remote design. The script
supports a deliberately small scalar workflow; use the typed SDK builders for
advanced target families described in the skill references.
"""
from __future__ import annotations
import argparse
import sys
from typing import Any
try:
from dotenv import load_dotenv
except ImportError: # pragma: no cover - environment dependent
load_dotenv = None
def load_env() -> None:
if load_dotenv is not None:
load_dotenv()
def load_sdk():
try:
from jinko import JinkoClient
from jinko.exceptions import JinkoError
except ImportError:
print(
"Cannot import jinko. Install the SDK: pip install jinko-sdk",
file=sys.stderr,
)
return None
return JinkoClient, JinkoError
def resolve_folder(client: Any, folder_ref: str | None, *, create: bool) -> Any | None:
if folder_ref is None:
return None
folder = client.get_folder(folder_ref)
if folder is None:
folder = client.get_folder_by_name(folder_ref, exact_match_only=True)
if folder is not None:
return folder
if not create:
raise ValueError(
f"Folder {folder_ref!r} was not found. Pass --create-folder to create it."
)
return client.create_folder(folder_ref)
def parse_filter(spec: str) -> tuple[str, str, float, str | None]:
parts = spec.split(":")
if len(parts) not in (3, 4):
raise ValueError(
"--numeric-filter must be descriptor:Eq|Neq|Lt|Lte|Gt|Gte:value[:arm]"
)
descriptor, operator, raw_value, *arm = parts
if operator not in {"Eq", "Neq", "Lt", "Lte", "Gt", "Gte"}:
raise ValueError(f"Unsupported numeric filter operator {operator!r}")
return descriptor, operator, float(raw_value), arm[0] if arm else None
def parse_normal(spec: str) -> tuple[str, float, float, str | None]:
parts = spec.split(":")
if len(parts) not in (3, 4):
raise ValueError(
"--marginal-normal must be descriptor:mean:standard_deviation[:arm]"
)
descriptor, mean, stdev, *arm = parts
return descriptor, float(mean), float(stdev), arm[0] if arm else None
def scalar(trial: Any, descriptor_id: str, arm: str | None) -> Any:
return trial.descriptors.scalars.get(descriptor_id, arm=arm)
def ensure_trial_completed(trial: Any) -> None:
status = trial.status()
value = (
status.get("status")
if isinstance(status, dict)
else getattr(status, "status", None)
)
if value != "completed":
raise RuntimeError(
f"Source trial {trial.sid} must have status 'completed'; current status is {value!r}"
)
def main() -> int:
parser = argparse.ArgumentParser(description="Create a Jinkō subsampling design.")
parser.add_argument(
"--trial-sid", required=True, help="Completed source Trial SID."
)
parser.add_argument("--numeric-filter", action="append", default=[])
parser.add_argument("--marginal-normal", action="append", default=[])
parser.add_argument(
"--observable", action="append", default=[], help="descriptor[:arm]"
)
parser.add_argument("--name", default="sdk-subsampling-design")
parser.add_argument(
"--description", default="Subsampling design created with the Jinkō SDK."
)
parser.add_argument("--folder", help="Existing folder id or exact folder name.")
parser.add_argument("--create-folder", action="store_true")
parser.add_argument("--apply", action="store_true")
args = parser.parse_args()
if args.create_folder and not args.folder:
print("--create-folder requires --folder", file=sys.stderr)
return 1
try:
filters = [parse_filter(value) for value in args.numeric_filter]
marginals = [parse_normal(value) for value in args.marginal_normal]
except ValueError as exc:
print(str(exc), file=sys.stderr)
return 1
print(f"Source trial: {args.trial_sid}")
print(f"Numeric filters: {filters or '<none>'}")
print(f"Normal marginals: {marginals or '<none>'}")
print(f"Observables: {args.observable or '<none>'}")
print(f"Folder: {args.folder or '<none>'}")
if not args.apply:
print(f"Would create subsampling design named {args.name!r}.")
print("Run again with --apply to create the project item.")
return 0
load_env()
sdk = load_sdk()
if sdk is None:
return 1
JinkoClient, JinkoError = sdk
try:
client = JinkoClient()
trial = client.get_trial(args.trial_sid)
ensure_trial_completed(trial)
folder = resolve_folder(client, args.folder, create=args.create_folder)
filter_builders = []
for descriptor_id, operator, value, arm in filters:
descriptor = scalar(trial, descriptor_id, arm)
filter_builders.append(getattr(descriptor, operator.lower())(value))
marginal_builders = [
scalar(trial, descriptor_id, arm).normal(
mean=mean, standard_deviation=stdev
)
for descriptor_id, mean, stdev, arm in marginals
]
observables = []
for value in args.observable:
descriptor_id, *arm = value.split(":", maxsplit=1)
observables.append(scalar(trial, descriptor_id, arm[0] if arm else None))
design = trial.create_subsampling_design(
numeric_filters=filter_builders,
marginals=marginal_builders,
observables=observables,
folder=folder,
name=args.name,
description=args.description,
)
print(f"Created subsampling design {design.sid}")
print(design.url)
diagnostics = design.diagnostics
print(diagnostics.explain())
return 0 if not diagnostics.errors() else 3
except (ValueError, RuntimeError, JinkoError) as exc:
print(f"Subsampling-design creation failed: {exc}", file=sys.stderr)
return 2
except Exception as exc: # noqa: BLE001
print(
f"Subsampling-design creation failed unexpectedly: {exc}", file=sys.stderr
)
return 4
if __name__ == "__main__":
raise SystemExit(main())
SHA-256: b086d336c31c64e8fc48a42d2ffb0e5b99eb4f637a92a528183cb290552970ca