SDK Usage
How your application code reads parameter values, with the right caching and override semantics for production.
The simple case
Retrieving configuration in your application code should be simple and unobtrusive. In the typical case, fetching parameter values is a single line:
You can also start from a Project entity:
Production code typically looks just like this — no wrappers, no fallbacks, no special-casing for tests. Tests “just work” because of the contextvar precedence (covered in Connector Injection).
Retrieval modes
There are three ways to call Parameters.get(), depending on your use case:
By Environment (live config):
By Version (Immutable pin):
By Experiment ID (Latest draft):
Accessing values
The ResolvedParameters object returned by Parameters.get() supports dot access and dictionary access. Values are unwrapped to native Python types automatically based on the schema:
Explicit typed accessors
For cases where you want runtime type validation, typed accessors are also available. These raise TypeError on a type mismatch:
params.get_text("system_prompt")params.get_string("model")params.get_number("temperature")params.get_integer("max_tokens")params.get_boolean("use_streaming")params.get_enum("use_case")params.get_model_ref("primary_model")params.get_secret_ref("api_key")
You can provide a default value as the second argument: params.get_number("temperature", 0.7).
Resolution order (Policy)
The Parameters.get() method resolves values using a strict precedence order (first match wins):
- Connector Contextvar: Injected by the platform during a test run. This wins unconditionally so tests cannot accidentally hit the network for live configuration.
- Environment Variables:
RHESIS_PARAMETERS_PINorRHESIS_PARAMETERS_ENVIRONMENT(legacy:RHESIS_PARAMETERS_LABEL). Lets ops pin a deploy without code changes. - Explicit Kwargs:
version>experiment_id>environment> implicitenvironment='default'. Lets application code be explicit. - HTTP API Fetch: If none of the above short-circuit the resolution, it fetches from the Rhesis API.
The order is “innermost wins” — overrides closer to the running call beat global settings.
Caching, with intent
The SDK implements an in-process cache so production code can call Parameters.get() on every request without paying constant network costs.
- Version entries are cached forever, because versions are immutable by definition.
- Environment and Experiment ID entries are cached with a Time-To-Live (TTL), defaulting to 60 seconds. Since the underlying version an environment points to can change, stale entries trigger a refresh on the next access.
You can manually invalidate the cache during testing using Parameters.invalidate(...).
Environment Variable Overrides
The SDK respects environment variables as a deployment primitive.
RHESIS_PARAMETERS_PIN=v3pins the application to an immutable version regardless of environment movement. This acts as a production safety net or staged rollout mechanism.RHESIS_PARAMETERS_ENVIRONMENT=productionswitches the application to a non-default environment without requiring code changes.
This gives operators a code-free escape hatch to manage configuration rollouts.
Error handling & graceful degradation
By default, Parameters.get() fails loudly. It raises RhesisAPIError on backend failure (for example an unbound environment) and KeyError when you read a parameter name that is not present in the resolved map.
Failing loudly is the default behavior because silently serving stale configuration in production is often worse than a noisy error.
However, if your application requires graceful degradation, you must implement it yourself. The chatbot demo application provides an example of a try/except wrapper that falls back to environment defaults:
Authoring experiments programmatically
You can author experiments entirely through the SDK using the Experiment entity:
Running experiments against test sets
Once you have an experiment, you can execute it directly against a test set and endpoint:
You can also pass an Experiment object to TestSet.execute():
When you pass only experiment_id without a version, the backend automatically resolves to the experiment’s latest version. You don’t need to look up the version identifier yourself.