Jarvis-Operas
Jarvis-Operas is a standalone operator layer for registering, loading, and calling Python callables.
- Scope: operators only (likelihood, chi2, prior mapping, data transforms, etc.)
- No dependency on Jarvis-HEP internals
- Native async entrypoint for Jarvis-HEP style execution (
await registry.acall(...)) - Stable
"<namespace>.<name>"naming for references from Jarvis-HEP/Jarvis-PLOT YAML
Architecture and migration references:
docs/architecture.mddocs/migration.md
Install
pip install .
Or for development (includes pytest and installs terminal command):
pip install -e ".[dev]"
Terminal command (jopera)
After install, you can use:
jopera
jopera help examples
jopera list --namespace math
jopera list --namespace math --json
jopera info stat.chi2_cov --json
jopera call math.add --kwargs '{"a": 1, "b": 2}'
jopera acall stat.chi2_cov --arg residual=[1.0,-0.5] --arg cov=[[2.0,0.1],[0.1,1.0]]
jopera call helper.eggbox --kwargs '{"x":0.5,"y":0.0}'
jopera list --namespace math --log-mode info
jopera call math.add --kwargs '{"a": 1, "b": 2}' --log-mode debug
jopera init
jopera init --manifest ./manifest.json --cache-root ~/.jarvis-operas/curve-cache
jopera interp list
jopera interp validate
jopera --help-advanced
Load user operators directly in CLI:
jopera load /absolute/path/to/my_ops.py
jopera call my_ops.my_op --user-ops /absolute/path/to/my_ops.py --arg x=10
jopera info my_ops.my_op --json
CLI behavior:
jopera(no args) prints a quick start cardjopera listprints grouped human-readable output by default (id + name)jopera list --jsonprints machine-readable JSON objects withid/name/namespacejopera info <name_or_id>prints metadata (including a unique id) and a suggested next commandjopera load <path>persists a JO-managed source snapshot for future processes- Re-running
jopera load <path>replaces existing user operators with the same<namespace>.<name> - Removing a function from a user source file does not auto-delete its prior registration
jopera load <path> --session-onlyloads without persistingjopera initprecompiles bundled interpolation manifest libraryjopera init --manifest <manifest.json>precompiles a custom curve JSON manifestjopera interp listlists root interpolation namespacesjopera interp validatevalidates root+namespace manifests- User write policy: the supported user write path is
jopera load - Developer-only write commands (
update,delete-func,delete-namespace,interp add/remove) requireJARVIS_OPERAS_DEV_WRITE=1
Core API
from jarvis_operas import get_global_operas_registry, get_global_operas
registry = get_global_operas_registry()
registry.call("math.add", a=1, b=2)
registry.call("math.identity", x={"k": 1})
operas = get_global_operas()
operas.call("math.add", a=1, b=2)
Supported namespace convention:
- Built-ins use feature namespaces, e.g.:
math.<name>stat.<name>helper.<name>
- User operator files default to
<script_name>.<func_name> - User operators cannot register into protected built-in namespaces (for example
math,stat,helper,interp, built-in interpolation namespaces).
Async call (Jarvis-HEP Factory/Module friendly)
result = await registry.acall(
"stat.chi2_cov",
residual=[1.0, -0.5],
cov=[[2.0, 0.1], [0.1, 1.0]],
)
Behavior:
- Async operator: awaited directly
- Sync operator: offloaded via
asyncio.to_threadby default (or custom executor) - Default numpy async concurrency is CPU-scaled (
os.cpu_count() * 3); override withget_global_operas(numpy_concurrency=...) - Batch helper concurrency:
await registry.acall_helper_many("eggbox", [...])
Example batch helper execution for Factory-side concurrent scans:
results = await registry.acall_helper_many(
"eggbox",
[
{"x": 0.1, "y": 0.2},
{"x": 0.3, "y": 0.4},
{"x": 0.5, "y": 0.6},
],
)
Logger injection
registry methods accept optional logger and operators can optionally define logger argument.
- If no logger is provided, Jarvis-Operas uses
loguru.loggerbound withmodule="Jarvis-Operas" - If logger is provided, Jarvis-Operas reuses it (no duplicate handler creation)
- Console format follows Jarvis-HEP style (
module -> time - [level] >>> message) - Default mode is
warning(only warning/error/critical are shown) - Optional modes:
info,debug
Utility:
from jarvis_operas import get_logger, set_log_mode
set_log_mode("info") # or "debug", default is "warning"
logger = get_logger()
Load user operators from file
from jarvis_operas import OperasRegistry, load_user_ops
registry = OperasRegistry()
loaded = load_user_ops("./my_ops.py", registry)
print(loaded)
Reload behavior:
load_user_ops(...)andjopera loadalways execute the current source file contents- If a user operator resolves to an existing
<namespace>.<name>, the new definition replaces the old one - If a function is removed from the file, JO does not auto-prune the old registration; delete/rename remains an explicit override action
Persistent registration for future Python processes:
from jarvis_operas import get_global_operas_registry, persist_user_ops
persist_user_ops("/absolute/path/to/my_ops.py")
registry = get_global_operas_registry() # auto-loads persisted sources
Persistence store location:
- Default sources registry:
~/.jarvis-operas/sources.json - Default override rules:
~/.jarvis-operas/overrides.json - Legacy base env (still supported):
JARVIS_OPERAS_PERSIST_FILE=/custom/path/persist_store.json- maps to sibling files
sources.jsonandoverrides.json
- maps to sibling files
- Optional explicit envs:
JARVIS_OPERAS_SOURCES_FILE=/custom/path/sources.jsonJARVIS_OPERAS_OVERRIDES_FILE=/custom/path/overrides.json
- Managed user source snapshots:
~/.jarvis-operas/user_sources/ - Override snapshot dir:
JARVIS_OPERAS_USER_SOURCE_DIR=/custom/path/user_sources - Legacy single-file
user_ops.jsonis still readable for backward compatibility
By default, load_user_ops("./my_ops.py", ...) uses my_ops as namespace, so
my_op becomes my_ops.my_op.
my_ops.py can export operators with either style:
- Decorator (recommended)
from jarvis_operas import oper
@oper("my_chi2")
def my_chi2(residual, cov, logger=None):
...
When loaded by load_user_ops("./my_ops.py", ...), this is registered as
my_ops.my_chi2.
- Explicit whitelist
def my_op(x):
return x
__JARVIS_OPERAS__ = {
"my_op": my_op,
}
Integration Contract (Jarvis-HEP / Jarvis-PLOT)
Downstream modules should depend on JO public API only:
- registry provider:
get_global_operas_registry() - runtime calls:
call/acall - lookup/introspection:
resolve_name/get/list/info
Avoid importing JO private modules or private symbols.
Function Docs Generation
Function docs are generated from OperaFunction.metadata:
python scripts/generate_function_docs.py --out docs/functions
Generated artifacts:
docs/functions/functions.jsondocs/functions/<namespace>/<function>.md
Curve publish/runtime cache (namespace manifests + JSON sources)
Use this flow when you have many 1D interpolation curves and want runtime speed:
- Source of truth:
- root index manifest (
interpolations.manifest.json) with namespace list - one manifest per namespace (function metadata list)
- per-function JSON source (
x/yarrays)
- root index manifest (
- Precompile once:
jopera init(bundled library) orjopera init --manifest ./manifest.json(custom)- optional:
jopera init --namespaces dmdd,interp1for partial namespace processing - optional maintenance:
jopera interp list|validate|add|remove
- optional:
- Runtime auto-registration:
get_global_operas_registry()registers hot curves asinterp.<curve_id> - Runtime load path uses
index.json+*.pklonly (no source JSON in hot path)
Namespace rule for registered interpolation operators:
- If
namespaceis set in curve item, register as<namespace>.<curve_id> - Else if
metadata.group(orgroup) is set, register as<group>.<curve_id> - Else fallback to
interp.<curve_id>
Bundled interpolation manifest library resource:
jarvis_operas/manifests/interpolations.manifest.json
Root index example:
{
"version": 2,
"kind": "jarvis_operas_interpolation_namespace_index",
"namespaces": [
{
"namespace": "dmdd",
"manifest": "dmdd/dmdd.manifest.json"
}
]
}
Namespace manifest example:
{
"namespace": "dmdd",
"functions": [
{
"name": "demo_curve",
"source": "dmdd/demo_curve.json",
"kind": "linear",
"hot": true,
"metadata": {
"group": "dmdd"
}
}
]
}
Curve source JSON example:
{
"x": [0.0, 1.0, 2.0],
"y": [0.0, 1.0, 4.0]
}
Python integration API:
from jarvis_operas import (
init_curve_cache,
interpolation_manifest_resource,
load_hot_curve_function_table,
load_interpolation_manifest_library,
register_hot_curves,
)
library_manifest = load_interpolation_manifest_library()
library_path = interpolation_manifest_resource()
init_curve_cache("./manifest.json")
table = load_hot_curve_function_table()
funcs = {}
updated = register_hot_curves(funcs)
Interpolation functions support:
numpybackend: native callablepolarsbackend:map_batchesfallback viaOperaFunction.return_dtype- sync:
registry.call(...) - async:
await registry.acall(...)
Built-in operators
math.add(a, b)stat.chi2_cov(residual, cov)helper.eggbox(x, y)math.identity(x)
All built-ins can be called via sync/async registry APIs and accept scalar, NumPy, and Pandas inputs where applicable. Example:
registry.call("math.add", a=1.0, b=2.0)
registry.call("stat.chi2_cov", residual=[1.0, 0.0], cov=[[2.0, 0.0], [0.0, 1.0]])
registry.call("helper.eggbox", x=0.5, y=0.0)
Query registry for external UIs (JHEP/JPlot)
registry.list()
registry.list(namespace="math")
registry.info("stat.chi2_cov")
registry.info(...) returns metadata, signature, docstring summary, backend support fields, and async flag.
Function docs generation (OperaFunction-driven)
Jarvis-Operas can auto-generate per-function docs from OperaFunction declarations.
python scripts/generate_function_docs.py
Output is generated under docs/functions/:
docs/functions/index.mddocs/functions/<namespace>/index.mddocs/functions/<namespace>/<function>.mddocs/functions/functions.json
Optional filters:
python scripts/generate_function_docs.py --namespaces math,stat
python scripts/generate_function_docs.py --out docs/custom_functions
Workspace clean
Clean local cache/build artifacts:
./scripts/clean_workspace.sh
Metadata
Release files for Jarvis-Operas 1.4.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| jarvis_operas-1.4.2.tar.gz | 8.1 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| jarvis_operas-1.4.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 16.3 MB
Release files / jarvis_operas-1.4.2.tar.gz
| Download URL | jarvis_operas-1.4.2.tar.gz |
|---|---|
| Size | 8.1 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fab4856202d8d30aa0c204fff5d1256a2baf1d46f3e82b60f430d1acc385615f
|
|
BLAKE2b-256 checksum How to use checksums |
544e3fa3c92f00c8a37e1b5de8c48b23b5b61f32970dc26f5c224e3d0db8496c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.13
|
Release files / jarvis_operas-1.4.2-py3-none-any.whl
| Download URL | jarvis_operas-1.4.2-py3-none-any.whl |
|---|---|
| Size | 8.1 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a564ca3060482efcd20af850177df94bcfd22de0ac5593fb8819bff90617aaed
|
|
BLAKE2b-256 checksum How to use checksums |
db43ea47c49041fb7e18e5328e5a32ce238a3c35b32e1780ede5ba0665bb4033
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.13
|