# Python SDK Reference
The Python SDK is a thin native wrapper around the Rust SDK. Python code gets
an idiomatic async API while rototo keeps workspace loading, linting, refresh,
and resolution behavior in the Rust core.
## Install
The package is built with maturin while rototo is in alpha:
```sh
cd sdks/python
python -m maturin develop
```
After release, install the published package:
```sh
python -m pip install rototo
```
The rototo release version stays SemVer, for example `0.1.0-alpha.3`.
Python packaging tools may display the equivalent PEP 440 spelling
`0.1.0a3` for the distribution.
## Load A Workspace
```python
import rototo
workspace = await rototo.Workspace.load("examples/basic")
```
`Workspace.load` accepts the same source strings as the CLI. It lints the
workspace and rejects lint failures before returning.
## Resolve A Variable
```python
resolution = await workspace.resolve_variable(
"premium-message",
{"user": {"tier": "premium"}},
)
print(resolution.value_key)
print(resolution.value)
```
`VariableResolution` has:
| `id` | Variable id. |
| `value_key` | Selected value key. |
| `value` | Selected JSON-compatible Python value. |
## Resolve A Qualifier
```python
resolution = await workspace.resolve_qualifier(
"premium-users",
{"user": {"tier": "premium"}},
)
print(resolution.value)
```
`QualifierResolution` has `id` and `value`.
## Context Validation
Resolution validates context against `schemas/context.schema.json` by default.
Skip validation for one call when a tool needs to evaluate partial context:
```python
resolution = await workspace.resolve_variable(
"premium-message",
context,
validate_context=False,
)
```
The context still must be a JSON object.
## Inspect And Lint
```python
workspace = await rototo.Workspace.inspect("examples/basic")
lint = await workspace.lint()
```
Inspection is for tools. A workspace loaded through `inspect` cannot resolve
variables or qualifiers because it does not compile the runtime model.
## Refreshing Workspace
```python
workspace = await rototo.RefreshingWorkspace.load(
source,
period_seconds=30,
)
resolution = await workspace.resolve_variable("premium-message", context)
status = await workspace.status()
await workspace.shutdown()
```
`RefreshingWorkspace` keeps serving the last successfully loaded workspace when
refresh fails. `status` returns a `RefreshStatus` dataclass with fingerprint,
success, attempt, failure, error, refreshing, and immutable fields.
## Errors
Rust `RototoError` values become `rototo.RototoError` in Python:
```python
try:
await workspace.resolve_variable("missing", {})
except rototo.RototoError as error:
print(error)
```
Invalid Python option values, such as an unknown lint mode, raise Python
`ValueError`.
## Public Types
| `Workspace` | Loaded workspace handle. |
| `RefreshingWorkspace` | Refreshing workspace handle for services. |
| `VariableResolution` | Selected variable value. |
| `QualifierResolution` | Qualifier boolean result. |
| `RefreshStatus` | Refresh state snapshot. |
| `RototoError` | Error raised for rototo failures. |