🧪 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}
- 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:
objectContainer 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]
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}
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}
- rexf.core.simple_api.is_experiment(func)[source]
Check if a function is decorated with @experiment.
- Return type:
- rexf.core.simple_api.get_experiment_metadata(func)[source]
Get experiment metadata from a decorated function.
- 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
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:
objectContainer 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]
- class rexf.core.models.ExperimentData(run)[source]
Bases:
objectUnified container for experiment data - alias for ExperimentRun for compatibility.
- class rexf.core.models.ReproducibilityTracker[source]
Bases:
objectTracks reproducibility information for experiments.
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:
objectContainer for experiment run metadata and results.
The
ExperimentRunclass 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]
ExperimentData
- class rexf.core.models.ExperimentData(run)[source]
Bases:
objectUnified container for experiment data - alias for ExperimentRun for compatibility.
Container for structured experiment data used in storage and analysis.
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_rateBe descriptive:
num_samplesnotnGroup 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