Core API
Core sim2l functionality.
sim2l
sim2l - Simulation Framework with Database-Backed Persistence
A modular, notebook-agnostic library for defining, deploying, and executing simulations as versioned, reusable artifacts.
- class sim2l.Field(*, default: Any | None = None, optional: bool = False, description: str = '', metadata: dict | None = None, required_if: str | None = None)[source]
Bases:
ABCBase class for all parameter field types
- __init__(*, default: Any | None = None, optional: bool = False, description: str = '', metadata: dict | None = None, required_if: str | None = None)[source]
Initialize field
- Parameters:
default – Default value
optional – Whether field is optional
description – Human-readable description
metadata – Additional metadata
required_if – Conditional requirement expression
- property value
Get field value
- abstract validate(value: Any) Any[source]
Validate and coerce value
- Parameters:
value – Value to validate
- Returns:
Validated/coerced value
- Raises:
ValueError – If validation fails
- abstract serialize() Any[source]
Serialize value to JSON-compatible format
- Returns:
JSON-serializable representation of value
- abstract deserialize(data: Any)[source]
Deserialize value from JSON format
- Parameters:
data – JSON data to deserialize
- class sim2l.Schema(fields: Dict[str, Field])[source]
Bases:
objectContainer for input/output schema definition
- __init__(fields: Dict[str, Field])[source]
Initialize schema
- Parameters:
fields – Dictionary of field name -> Field instance
- validate(data: Dict[str, Any]) Dict[str, Any][source]
Validate data against schema
- Parameters:
data – Dictionary of field values
- Returns:
Validated data
- Raises:
ValueError – If validation fails
- set_values(data: Dict[str, Any])[source]
Set field values from dictionary
- Parameters:
data – Dictionary of field values
- serialize() Dict[str, Any][source]
Serialize all field values
- Returns:
Dictionary of serialized values
- deserialize(data: Dict[str, Any])[source]
Deserialize field values from data
- Parameters:
data – Dictionary of serialized values
- to_dict() Dict[str, Any][source]
Convert schema definition to dictionary
- Returns:
Dictionary representation of schema
- class sim2l.InputSchema(fields: Dict[str, Field])[source]
Bases:
SchemaSchema for simulation inputs
- class sim2l.OutputSchema(fields: Dict[str, Field])[source]
Bases:
SchemaSchema for simulation outputs
- class sim2l.Integer(*, min: int | None = None, max: int | None = None, **kwargs)[source]
Bases:
FieldInteger field with min/max validation
- __init__(*, min: int | None = None, max: int | None = None, **kwargs)[source]
Initialize field
- Parameters:
default – Default value
optional – Whether field is optional
description – Human-readable description
metadata – Additional metadata
required_if – Conditional requirement expression
- serialize() int[source]
Serialize value to JSON-compatible format
- Returns:
JSON-serializable representation of value
- deserialize(data: int)[source]
Deserialize value from JSON format
- Parameters:
data – JSON data to deserialize
- class sim2l.Number(*, units: str | None = None, min: float | None = None, max: float | None = None, **kwargs)[source]
Bases:
FieldNumeric field with units support
- __init__(*, units: str | None = None, min: float | None = None, max: float | None = None, **kwargs)[source]
Initialize field
- Parameters:
default – Default value
optional – Whether field is optional
description – Human-readable description
metadata – Additional metadata
required_if – Conditional requirement expression
- class sim2l.Text(*, choices: List[str] | None = None, maxlen: int | None = None, **kwargs)[source]
Bases:
FieldText field with optional choices and max length
- __init__(*, choices: List[str] | None = None, maxlen: int | None = None, **kwargs)[source]
Initialize field
- Parameters:
default – Default value
optional – Whether field is optional
description – Human-readable description
metadata – Additional metadata
required_if – Conditional requirement expression
- serialize() str[source]
Serialize value to JSON-compatible format
- Returns:
JSON-serializable representation of value
- deserialize(data: str)[source]
Deserialize value from JSON format
- Parameters:
data – JSON data to deserialize
- class sim2l.Array(*, dtype: str = 'float', shape: tuple | None = None, **kwargs)[source]
Bases:
FieldNumPy array field
- __init__(*, dtype: str = 'float', shape: tuple | None = None, **kwargs)[source]
Initialize field
- Parameters:
default – Default value
optional – Whether field is optional
description – Human-readable description
metadata – Additional metadata
required_if – Conditional requirement expression
- class sim2l.Image(*, default: Any | None = None, optional: bool = False, description: str = '', metadata: dict | None = None, required_if: str | None = None)[source]
Bases:
FieldPIL Image field
- class sim2l.Element(*, choices: List[str] | None = None, **kwargs)[source]
Bases:
FieldChemical element field using mendeleev
- __init__(*, choices: List[str] | None = None, **kwargs)[source]
Initialize field
- Parameters:
default – Default value
optional – Whether field is optional
description – Human-readable description
metadata – Additional metadata
required_if – Conditional requirement expression
- class sim2l.List(*, item_type: str = 'Text', **kwargs)[source]
Bases:
FieldList field
- __init__(*, item_type: str = 'Text', **kwargs)[source]
Initialize field
- Parameters:
default – Default value
optional – Whether field is optional
description – Human-readable description
metadata – Additional metadata
required_if – Conditional requirement expression
- serialize() list[source]
Serialize value to JSON-compatible format
- Returns:
JSON-serializable representation of value
- deserialize(data: list)[source]
Deserialize value from JSON format
- Parameters:
data – JSON data to deserialize
- class sim2l.Dict(*, schema: dict | None = None, **kwargs)[source]
Bases:
FieldDictionary field with optional nested schema
- __init__(*, schema: dict | None = None, **kwargs)[source]
Initialize field
- Parameters:
default – Default value
optional – Whether field is optional
description – Human-readable description
metadata – Additional metadata
required_if – Conditional requirement expression
- serialize() dict[source]
Serialize value to JSON-compatible format
- Returns:
JSON-serializable representation of value
- deserialize(data: dict)[source]
Deserialize value from JSON format
- Parameters:
data – JSON data to deserialize
- class sim2l.Boolean(*, default: Any | None = None, optional: bool = False, description: str = '', metadata: dict | None = None, required_if: str | None = None)[source]
Bases:
FieldBoolean field
- serialize() bool[source]
Serialize value to JSON-compatible format
- Returns:
JSON-serializable representation of value
- sim2l.register_field_type(name: str, field_class: Type[Field])[source]
Register a field type
- Parameters:
name – Type name (e.g., “Integer”, “Number”)
field_class – Field class
- sim2l.get_field_class(name: str) Type[Field][source]
Get field class by name
- Parameters:
name – Type name
- Returns:
Field class
- Raises:
ValueError – If type not found
- class sim2l.SimulationDefinition(name: str, version: str, inputs: InputSchema, outputs: OutputSchema, workflow: Callable | Path | bytes, *, description: str = '', author: str = '', tags: List[str] | None = None, dependencies: List[str] | None = None, workflow_type: str = 'notebook')[source]
Bases:
objectDefines a simulation with inputs, outputs, and workflow
- __init__(name: str, version: str, inputs: InputSchema, outputs: OutputSchema, workflow: Callable | Path | bytes, *, description: str = '', author: str = '', tags: List[str] | None = None, dependencies: List[str] | None = None, workflow_type: str = 'notebook')[source]
Initialize simulation definition
- Parameters:
name – Simulation name (unique identifier)
version – Semantic version (e.g., “1.2.0”)
inputs – Input schema
outputs – Output schema
workflow – Workflow implementation (function, notebook path, or bytes)
description – Human-readable description
author – Author name
tags – List of tags for categorization
dependencies – List of required packages
workflow_type – Type of workflow (“notebook”, “function”, “dag”)
- classmethod from_notebook(notebook_path: str | Path, name: str, version: str, **kwargs) SimulationDefinition[source]
Create simulation definition from Jupyter notebook
- Parameters:
notebook_path – Path to notebook file
name – Simulation name
version – Version string
**kwargs – Additional metadata
- Returns:
SimulationDefinition instance
- classmethod from_function(func: Callable, name: str, version: str, inputs: InputSchema, outputs: OutputSchema, **kwargs) SimulationDefinition[source]
Create simulation definition from Python function
- Parameters:
func – Simulation function
name – Simulation name
version – Version string
inputs – Input schema
outputs – Output schema
**kwargs – Additional metadata
- Returns:
SimulationDefinition instance
- run(executor=None, **inputs)[source]
Execute simulation with given inputs
- Parameters:
executor – Executor instance or type string (‘local’, ‘notebook’)
**inputs – Input parameters as keyword arguments
- Returns:
ExecutionResult
Example
>>> sim = load_simulation("my_sim") >>> result = sim.run(temperature=350, power=20) >>> print(result.outputs.max_temperature)
- class sim2l.SimulationMetadata(name: str, version: str, description: str = '', author: str = '', tags: List[str] | None = None, dependencies: List[str] | None = None, created_at: datetime | None = None)[source]
Bases:
objectMetadata for a simulation
- __init__(name: str, version: str, description: str = '', author: str = '', tags: List[str] | None = None, dependencies: List[str] | None = None, created_at: datetime | None = None)[source]
Initialize metadata
- Parameters:
name – Simulation name
version – Semantic version
description – Description
author – Author name
tags – List of tags
dependencies – List of package dependencies
created_at – Creation timestamp
- classmethod from_dict(data: dict) SimulationMetadata[source]
Create from dictionary
- class sim2l.SimulationRepository(db_path: Path | None = None, backend: StorageBackend | None = None)[source]
Bases:
objectRepository for storing and retrieving simulations
- __init__(db_path: Path | None = None, backend: StorageBackend | None = None)[source]
Initialize repository
- Parameters:
db_path – Path to database (for SQLite backend)
backend – Custom storage backend
- deploy(simulation: SimulationDefinition) int[source]
Deploy a simulation to the repository
- Parameters:
simulation – Simulation definition to deploy
- Returns:
Simulation ID in database
- load(name: str, version: str | None = None) SimulationDefinition[source]
Load a simulation by name and version
- Parameters:
name – Simulation name
version – Version string (if None, loads latest)
- Returns:
SimulationDefinition
- list(tags: List[str] | None = None, status: str = 'active') List[Dict[str, Any]][source]
List available simulations
- Parameters:
tags – Filter by tags
status – Filter by status (“active”, “deprecated”, “archived”)
- Returns:
List of simulation metadata dictionaries
- exists(name: str, version: str) bool[source]
Check if simulation exists
- Parameters:
name – Simulation name
version – Version string
- Returns:
True if exists
- delete(name: str, version: str)[source]
Delete a simulation
- Parameters:
name – Simulation name
version – Version to delete
- deprecate(name: str, version: str)[source]
Mark simulation as deprecated
- Parameters:
name – Simulation name
version – Version to deprecate
- get_simulation_id(name: str, version: str) int | None[source]
Get simulation database ID
- Parameters:
name – Simulation name
version – Version string
- Returns:
Simulation ID or None
- classmethod create(db_path: Path, backend: str = 'sqlite') SimulationRepository[source]
Create new repository with initialized database
- Parameters:
db_path – Path to database
backend – Backend type (“sqlite”, etc.)
- Returns:
Initialized repository
- sim2l.load_simulation(name: str, version: str | None = None) SimulationDefinition[source]
Load simulation from default repository
- Parameters:
name – Simulation name
version – Version (if None, loads latest)
- Returns:
SimulationDefinition
- sim2l.list_simulations(**kwargs) List[Dict[str, Any]][source]
List simulations from default repository
- Parameters:
**kwargs – Filter arguments (tags, status)
- Returns:
List of simulation metadata
- sim2l.configure(**kwargs)[source]
Update global configuration
- Parameters:
db_path – Path to simulation database
cache_enabled – Enable/disable caching
default_executor – Default executor type
artifact_storage – “database” or “filesystem”
artifact_base_path – Base path for filesystem artifact storage
log_level – Logging level
- sim2l.deploy_simulation(notebook: str | Path, name: str, version: str, description: str = '', author: str = '', tags: list | None = None, dependencies: list | None = None) int[source]
Deploy a simulation from a Jupyter notebook
- Parameters:
notebook – Path to notebook file
name – Simulation name
version – Semantic version
description – Description
author – Author name
tags – List of tags
dependencies – List of package dependencies
- Returns:
Simulation ID in database
Example
>>> deploy_simulation( ... notebook="thermal_sim.ipynb", ... name="thermal_analysis", ... version="1.0.0", ... description="2D thermal diffusion", ... tags=["physics", "thermal"] ... )
- sim2l.get_inputs() InputSchema[source]
Get input schema in notebook authoring context
This function is used inside notebooks to get the input schema for interactive testing during authoring.
- Returns:
InputSchema with default values
- Example (in notebook):
>>> # First, load the extension and define inputs >>> %load_ext sim2l.notebook >>> %%sim2l_inputs >>> temperature: >>> type: Number >>> units: kelvin >>> >>> # Then get inputs for testing >>> inputs = get_inputs() >>> inputs.temperature = 350
- sim2l.save_outputs(**outputs: Any)[source]
Save simulation outputs in notebook
Saves outputs to both: 1. SQLite database (if execution_id is set in environment) 2. Scrapbook (for backward compatibility)
- Parameters:
**outputs – Output variables as keyword arguments
- Example (in notebook):
>>> save_outputs( ... max_temperature=450.5, ... temperature_distribution=temp_array, ... plot="thermal_plot.png" ... )
- sim2l.compute_squid_id(simtool_name: str, simtool_revision: str, inputs: Dict[str, Any]) str[source]
Compute SQUID ID for a simulation execution
The SQUID ID is computed as: 1. Create prologue with sorted inputs in format “key value” 2. Append simtoolName and simtoolRevision 3. SHA1 hash the prologue 4. Format as: simtoolName/simtoolRevision/hash
This matches the existing simtool SQUID generation for compatibility.
- Parameters:
simtool_name – Simulation name
simtool_revision – Simulation version/revision
inputs – Dictionary of input parameters
- Returns:
“name/revision/hash”
- Return type:
SQUID ID string in format
Example
>>> compute_squid_id( ... simtool_name="thermal_analysis", ... simtool_revision="1.0.0", ... inputs={"temperature": 300, "power": 20} ... ) 'thermal_analysis/1.0.0/a3b5c7d9e1f2...'
- sim2l.get_squid_id_for_parameters(simtoolName: str, simtoolRevision: str, inputs: Dict[str, Any]) Dict[str, str][source]
Get SQUID ID for parameters (API-compatible format)
This function matches the existing API format with camelCase parameters.
- Parameters:
simtoolName – Simulation name
simtoolRevision – Simulation version
inputs – Input parameters dictionary
- Returns:
Dictionary with ‘id’ key containing SQUID ID
Example
>>> get_squid_id_for_parameters( ... simtoolName="thermal_analysis", ... simtoolRevision="1.0.0", ... inputs={"temperature": 300} ... ) {'id': 'thermal_analysis/1.0.0/abc123...'}
- class sim2l.Executor(cache: bool = True, output_dir: Path | None = None)[source]
Bases:
ABCAbstract base class for simulation executors
- __init__(cache: bool = True, output_dir: Path | None = None)[source]
Initialize executor
- Parameters:
cache – Enable caching
output_dir – Output directory for execution artifacts
- abstract execute(simulation: SimulationDefinition, inputs: Dict[str, Any], run_name: str | None = None) ExecutionResult[source]
Execute a simulation
- Parameters:
simulation – Simulation definition to execute
inputs – Input parameters
run_name – Optional run name (UUID generated if None)
- Returns:
ExecutionResult with outputs
- Raises:
ExecutionError – If execution fails
- abstract check_cache(simulation: SimulationDefinition, inputs: Dict[str, Any]) ExecutionResult | None[source]
Check if cached result exists
- Parameters:
simulation – Simulation definition
inputs – Input parameters
- Returns:
Cached ExecutionResult or None
- prepare_inputs(simulation: SimulationDefinition, inputs: Dict[str, Any]) Dict[str, Any][source]
Prepare and validate inputs
- Parameters:
simulation – Simulation definition
inputs – Raw input parameters
- Returns:
Validated input parameters
- Raises:
ValueError – If validation fails
- class sim2l.LocalExecutor(cache: bool = True)[source]
Bases:
ExecutorExecute simulations as Python functions in-process
This executor runs Python functions directly without notebooks.
- check_cache(simulation: SimulationDefinition, inputs: Dict[str, Any]) ExecutionResult | None[source]
Check if cached result exists
- Parameters:
simulation – Simulation definition
inputs – Input parameters
- Returns:
Cached ExecutionResult or None
- execute(simulation: SimulationDefinition, inputs: Dict[str, Any], run_name: str | None = None) ExecutionResult[source]
Execute simulation function locally
- Parameters:
simulation – Simulation definition
inputs – Input parameters
run_name – Optional run name (unused for local execution)
- Returns:
ExecutionResult
- Raises:
ExecutionError – If execution fails
- class sim2l.NotebookExecutor(cache: bool = True, output_dir: Path | None = None, copy_files: bool = True, register_results: bool | None = None)[source]
Bases:
ExecutorExecute simulations using Papermill
This executor runs Jupyter notebooks using Papermill, similar to simtool’s LocalRun class.
- __init__(cache: bool = True, output_dir: Path | None = None, copy_files: bool = True, register_results: bool | None = None)[source]
Initialize NotebookExecutor
- Parameters:
cache – Enable caching
output_dir – Output directory (uses temp if None)
copy_files – Copy supporting files to output directory
register_results – Register results with results service (default: from config)
- check_cache(simulation: SimulationDefinition, inputs: Dict[str, Any]) ExecutionResult | None[source]
Check if cached result exists
- Parameters:
simulation – Simulation definition
inputs – Input parameters
- Returns:
Cached ExecutionResult or None
- execute(simulation: SimulationDefinition, inputs: Dict[str, Any], run_name: str | None = None) ExecutionResult[source]
Execute simulation notebook using Papermill
- Parameters:
simulation – Simulation definition
inputs – Input parameters
run_name – Optional run name
- Returns:
ExecutionResult
- Raises:
ExecutionError – If execution fails
- class sim2l.ExecutionResult(execution_id: str, simulation_id: int, simulation_name: str, simulation_version: str, inputs: Dict[str, Any], outputs: OutputData | None = None, output_schema: OutputSchema | None = None, output_data: Dict[str, Any] | None = None, status: str = 'completed', executed_at: datetime | None = None, duration_seconds: float | None = None, executor_type: str = 'local', executor_config: Dict[str, Any] | None = None, error_message: str | None = None, cache_key: str | None = None, squid_id: str | None = None)[source]
Bases:
objectContainer for simulation execution results
- __init__(execution_id: str, simulation_id: int, simulation_name: str, simulation_version: str, inputs: Dict[str, Any], outputs: OutputData | None = None, output_schema: OutputSchema | None = None, output_data: Dict[str, Any] | None = None, status: str = 'completed', executed_at: datetime | None = None, duration_seconds: float | None = None, executor_type: str = 'local', executor_config: Dict[str, Any] | None = None, error_message: str | None = None, cache_key: str | None = None, squid_id: str | None = None)[source]
Initialize execution result
- Parameters:
execution_id – Unique execution ID (UUID)
simulation_id – Database simulation ID
simulation_name – Simulation name
simulation_version – Simulation version
inputs – Input parameters used
outputs – OutputData instance (if already created)
output_schema – Output schema (if creating OutputData)
output_data – Raw output data dictionary
status – Execution status
executed_at – Execution timestamp
duration_seconds – Execution duration
executor_type – Type of executor used
executor_config – Executor configuration
error_message – Error message if failed
cache_key – Cache key for lookup
squid_id – SQUID ID for this execution
- save(db_path: Path | None = None)[source]
Save execution result to database
- Parameters:
db_path – Database path (uses default if None)
- classmethod load(execution_id: str, db_path: Path | None = None) ExecutionResult[source]
Load execution result from database
- Parameters:
execution_id – Execution ID to load
db_path – Database path (uses default if None)
- Returns:
ExecutionResult instance
- classmethod create(simulation_id: int, simulation_name: str, simulation_version: str, inputs: Dict[str, Any], output_schema: OutputSchema, executor_type: str = 'local', cache_key: str | None = None, squid_id: str | None = None) ExecutionResult[source]
Create a new execution result
- Parameters:
simulation_id – Database simulation ID
simulation_name – Simulation name
simulation_version – Simulation version
inputs – Input parameters
output_schema – Output schema
executor_type – Executor type
cache_key – Cache key
squid_id – SQUID ID
- Returns:
New ExecutionResult instance
Configuration
- sim2l.configure(**kwargs)[source]
Update global configuration
- Parameters:
db_path – Path to simulation database
cache_enabled – Enable/disable caching
default_executor – Default executor type
artifact_storage – “database” or “filesystem”
artifact_base_path – Base path for filesystem artifact storage
log_level – Logging level