🧪 Core API Reference

This page documents the core RexF API that you’ll use in your experiments.

Main Module

rexf - Smart Experiments Framework.

A lightweight Python library for reproducible computational experiments with an ultra-simple, smart API.

Usage:

from rexf import experiment, run

@experiment def my_experiment(param1, param2):

result = do_something(param1, param2) return {“score”: result}

# Run single experiment run.single(my_experiment, param1=1.0, param2=2.0)

# Auto-explore parameter space run.auto_explore(my_experiment, strategy=”random”, budget=10)

# Get insights print(run.insights())

# Launch web dashboard run.dashboard()

rexf.experiment(name_or_func=None, *, optimize_for=None)[source]

Ultra-simple experiment decorator with zero configuration required.

Usage:

@experiment def my_experiment(param1, param2):

result = do_something(param1, param2) return {“score”: result}

@experiment(“custom_name”) def my_experiment(param1, param2):

return {“accuracy”: 0.95}

@experiment(optimize_for=”accuracy”) def my_experiment(param1, param2):

return {“accuracy”: 0.95, “loss”: 0.1}

Parameters:
  • name_or_func (Optional[str]) – Optional experiment name or function (for @experiment usage)

  • optimize_for (Optional[str]) – Optional metric name to optimize for in auto-exploration

Returns:

Decorated function with experiment metadata attached

class rexf.ExperimentRun(run_id, experiment_name, parameters, start_time, end_time=None, status='running', git_commit=None, git_status=None, environment_info=None, random_seed=None)[source]

Bases: object

Container for experiment run metadata and results.

__init__(run_id, experiment_name, parameters, start_time, end_time=None, status='running', git_commit=None, git_status=None, environment_info=None, random_seed=None)[source]
property duration: float | None

Get experiment duration in seconds.

classmethod from_dict(data)[source]

Create from dictionary.

Return type:

ExperimentRun

to_dict()[source]

Convert to dictionary.

Return type:

Dict[str, Any]

class rexf.ExperimentData(run)[source]

Bases: object

Unified container for experiment data - alias for ExperimentRun for compatibility.

__init__(run)[source]

Initialize with ExperimentRun.

classmethod create(run_id, experiment_name, parameters, start_time, **kwargs)[source]

Create new experiment data.

Return type:

ExperimentData

The experiment Decorator

rexf.experiment(name_or_func=None, *, optimize_for=None)[source]

Ultra-simple experiment decorator with zero configuration required.

Usage:

@experiment def my_experiment(param1, param2):

result = do_something(param1, param2) return {“score”: result}

@experiment(“custom_name”) def my_experiment(param1, param2):

return {“accuracy”: 0.95}

@experiment(optimize_for=”accuracy”) def my_experiment(param1, param2):

return {“accuracy”: 0.95, “loss”: 0.1}

Parameters:
  • name_or_func (Optional[str]) – Optional experiment name or function (for @experiment usage)

  • optimize_for (Optional[str]) – Optional metric name to optimize for in auto-exploration

Returns:

Decorated function with experiment metadata attached

The decorator automatically captures:

  • Parameters: All function arguments with their values

  • Results: Everything returned by the function

  • Metadata: Execution time, Git commit, environment info

  • Reproducibility: Random seeds, system information

Example:

from rexf import experiment

@experiment
def my_research_function(param1, param2=42):
    # Your experiment code here
    result = perform_calculation(param1, param2)
    return {"metric": result, "quality": assess_quality(result)}

Simple API Module

Ultra-simple API for rexf experiments.

This module provides the zero-config experiment decorator that users actually want. No complex configuration, just decorate your function and go.

rexf.core.simple_api.experiment(name_or_func=None, *, optimize_for=None)[source]

Ultra-simple experiment decorator with zero configuration required.

Usage:

@experiment def my_experiment(param1, param2):

result = do_something(param1, param2) return {“score”: result}

@experiment(“custom_name”) def my_experiment(param1, param2):

return {“accuracy”: 0.95}

@experiment(optimize_for=”accuracy”) def my_experiment(param1, param2):

return {“accuracy”: 0.95, “loss”: 0.1}

Parameters:
  • name_or_func (Optional[str]) – Optional experiment name or function (for @experiment usage)

  • optimize_for (Optional[str]) – Optional metric name to optimize for in auto-exploration

Returns:

Decorated function with experiment metadata attached

rexf.core.simple_api.is_experiment(func)[source]

Check if a function is decorated with @experiment.

Return type:

bool

rexf.core.simple_api.get_experiment_metadata(func)[source]

Get experiment metadata from a decorated function.

Return type:

Dict[str, Any]

rexf.core.simple_api.auto_track_returns(result, experiment_name)[source]

Automatically categorize return values into metrics, results, and artifacts.

Rules: - Numbers (int, float) -> metrics - Strings, complex objects -> results - Files that exist -> artifacts - Dictionaries -> split based on content

Return type:

Dict[str, Any]

rexf.core.simple_api.extract_parameter_values(func, *args, **kwargs)[source]

Extract parameter values from function call arguments.

Return type:

Dict[str, Any]

Models

Data structures used throughout RexF.

Data models and structures for rexf.

class rexf.core.models.ExperimentRun(run_id, experiment_name, parameters, start_time, end_time=None, status='running', git_commit=None, git_status=None, environment_info=None, random_seed=None)[source]

Bases: object

Container for experiment run metadata and results.

__init__(run_id, experiment_name, parameters, start_time, end_time=None, status='running', git_commit=None, git_status=None, environment_info=None, random_seed=None)[source]
property duration: float | None

Get experiment duration in seconds.

to_dict()[source]

Convert to dictionary.

Return type:

Dict[str, Any]

classmethod from_dict(data)[source]

Create from dictionary.

Return type:

ExperimentRun

class rexf.core.models.ExperimentData(run)[source]

Bases: object

Unified container for experiment data - alias for ExperimentRun for compatibility.

__init__(run)[source]

Initialize with ExperimentRun.

classmethod create(run_id, experiment_name, parameters, start_time, **kwargs)[source]

Create new experiment data.

Return type:

ExperimentData

class rexf.core.models.ReproducibilityTracker[source]

Bases: object

Tracks reproducibility information for experiments.

__init__()[source]
get_git_commit()[source]

Get current Git commit hash.

Return type:

Optional[str]

get_git_status()[source]

Get Git repository status.

Return type:

Dict[str, Any]

get_environment_info()[source]

Get environment information.

Return type:

Dict[str, Any]

ExperimentRun

class rexf.core.models.ExperimentRun(run_id, experiment_name, parameters, start_time, end_time=None, status='running', git_commit=None, git_status=None, environment_info=None, random_seed=None)[source]

Bases: object

Container for experiment run metadata and results.

The ExperimentRun class represents a single experiment execution with all its metadata:

# Access experiment data
experiment = run.get_by_id("your_run_id")

print(f"Parameters: {experiment.parameters}")
print(f"Metrics: {experiment.metrics}")
print(f"Duration: {experiment.duration} seconds")
print(f"Status: {experiment.status}")
print(f"Git commit: {experiment.git_commit}")
__init__(run_id, experiment_name, parameters, start_time, end_time=None, status='running', git_commit=None, git_status=None, environment_info=None, random_seed=None)[source]
property duration: float | None

Get experiment duration in seconds.

to_dict()[source]

Convert to dictionary.

Return type:

Dict[str, Any]

classmethod from_dict(data)[source]

Create from dictionary.

Return type:

ExperimentRun

ExperimentData

class rexf.core.models.ExperimentData(run)[source]

Bases: object

Unified container for experiment data - alias for ExperimentRun for compatibility.

Container for structured experiment data used in storage and analysis.

__init__(run)[source]

Initialize with ExperimentRun.

classmethod create(run_id, experiment_name, parameters, start_time, **kwargs)[source]

Create new experiment data.

Return type:

ExperimentData

Function Signature Detection

RexF automatically analyzes your experiment functions to understand their parameters and return values:

Parameter Detection

@experiment
def my_experiment(required_param, optional_param=42, keyword_only=None):
    return {"result": required_param * optional_param}

# RexF automatically detects:
# - required_param: required parameter
# - optional_param: optional with default value 42
# - keyword_only: optional parameter

Return Value Processing

RexF intelligently processes return values:

@experiment
def different_return_types():
    # Dictionary (recommended) - becomes metrics
    return {"accuracy": 0.95, "loss": 0.05}

@experiment
def single_value():
    # Single value - becomes "result" metric
    return 0.95

@experiment
def multiple_values():
    # Tuple/list - becomes indexed metrics
    return [0.95, 0.05, 0.98]  # result_0, result_1, result_2

Error Handling

RexF gracefully handles experiment failures:

@experiment
def potentially_failing_experiment(error_probability=0.1):
    import random
    if random.random() < error_probability:
        raise ValueError("Simulated experiment failure")
    return {"success_metric": 1.0}

# Failed experiments are still recorded with:
# - status: "failed"
# - error message in metadata
# - all parameters preserved
# - execution time captured

Environment Capture

RexF automatically captures environment information for reproducibility:

Git Integration

  • Current commit hash

  • Repository status (clean/dirty)

  • Branch name

  • Remote URL

Python Environment

  • Python version

  • Installed packages and versions

  • Virtual environment info

System Information

  • Operating system

  • Hardware details

  • Execution timestamp

Random Seed Management

  • Automatic seed capture

  • Seed restoration for reproducibility

  • Support for NumPy, Python random, and other libraries

Customization

Advanced Decorator Usage

The @experiment decorator supports customization options:

# Basic usage (recommended)
@experiment
def simple_experiment(param1, param2=42):
    return {"metric": param1 * param2}

# The decorator handles everything automatically:
# - Parameter extraction
# - Result processing
# - Metadata collection
# - Storage management

Integration Notes

Threading and Multiprocessing

RexF is thread-safe and supports concurrent experiment execution:

import concurrent.futures

@experiment
def thread_safe_experiment(worker_id, data_size=1000):
    # Each thread gets its own experiment context
    result = process_data(worker_id, data_size)
    return {"worker_result": result}

# Safe to run in parallel
with concurrent.futures.ThreadPoolExecutor() as executor:
    futures = [
        executor.submit(run.single, thread_safe_experiment, worker_id=i)
        for i in range(4)
    ]

    run_ids = [f.result() for f in futures]

Context Managers

For advanced use cases, you can access the experiment context:

from rexf.core.simple_api import get_current_experiment_context

@experiment
def context_aware_experiment(param1):
    # Access current experiment context
    context = get_current_experiment_context()

    if context:
        print(f"Running experiment: {context.experiment_name}")
        print(f"Run ID: {context.run_id}")

    return {"result": param1 * 2}

Best Practices

Function Design

  • Use descriptive parameter names

  • Provide sensible default values

  • Return dictionaries with meaningful key names

  • Keep functions focused on single experiments

Parameter Naming

  • Use lowercase with underscores: learning_rate

  • Be descriptive: num_samples not n

  • Group related parameters: model_type, model_layers

Return Value Structure

@experiment
def well_structured_experiment(param1, param2=42):
    # Good return structure
    return {
        # Primary metrics
        "accuracy": 0.95,
        "precision": 0.92,
        "recall": 0.94,

        # Performance metrics
        "training_time": 120.5,
        "memory_usage": 256.7,

        # Quality metrics
        "convergence_epoch": 45,
        "final_loss": 0.023
    }

Error Reporting

@experiment
def robust_experiment(param1, validate=True):
    try:
        if validate and param1 < 0:
            raise ValueError(f"Invalid parameter: {param1} must be >= 0")

        result = complex_computation(param1)
        return {"result": result, "validation_passed": True}

    except Exception as e:
        # Let RexF handle the error - it will:
        # 1. Record the experiment as failed
        # 2. Store the error message
        # 3. Preserve all parameters
        # 4. Return a valid run_id for analysis
        raise  # Re-raise to let RexF handle it