> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cirron.com/llms.txt
> Use this file to discover all available pages before exploring further.

# ci.env

> Read env vars with `.env` support and JSON auto-parsing.

Thin convenience over `os.environ` with `.env` file loading and
automatic JSON parsing for structured values. Not a proprietary
config system; `ci.env(key)` is functionally `os.environ.get(key)`
plus two ergonomic additions.

## Signature

```python theme={null}
def env(key: str, default: Any = None) -> Any
```

## Parameters

| Name      | Type  | Default | Purpose                         |
| --------- | ----- | ------- | ------------------------------- |
| `key`     | `str` | -       | Environment variable name       |
| `default` | any   | `None`  | Returned when the key is absent |

## Behavior

* **`.env` loading**: on first call, loads a `.env` file from the
  current working directory via `python-dotenv` if that package is
  installed. If `python-dotenv` isn't installed, `.env` loading is
  silently skipped; `os.environ` is read directly.
* **JSON auto-parsing**: values whose first non-whitespace character
  is `{` or `[` are parsed with `json.loads()`. Scalars (numbers,
  `"true"`, `"false"`, plain strings) stay as strings; cast them
  yourself. This avoids surprises like `"123"` becoming an `int` you
  didn't expect.

## Examples

### Plain env vars

```python theme={null}
api_base = ci.env("API_BASE_URL", default="https://api.example.com")
debug    = ci.env("DEBUG", default=False)
```

### Structured config

```python theme={null}
# CONFIG='{"threshold": 0.5, "capture_embeddings": true}'
config = ci.env("CONFIG")          # returns {"threshold": 0.5, "capture_embeddings": True}
ci.profile(config=config)
```

### Platform context

The Cirron runtime injects these automatically inside pipelines and
deployments:

| Variable               | Purpose                                                                                                           |
| ---------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `CIRRON_RUN_ID`        | Run this process belongs to                                                                                       |
| `CIRRON_PIPELINE_ID`   | Pipeline this run executed as (if any)                                                                            |
| `CIRRON_DEPLOYMENT_ID` | Deployment this process is part of (if any)                                                                       |
| `CIRRON_WORKSPACE_ID`  | Owning workspace                                                                                                  |
| `CIRRON_DATA_DIR`      | Base directory for data staged by a Load Data step (`/data`); read your dataset from a subpath like `/data/input` |
| `CIRRON_DATASET_URI`   | Storage URI of the staged dataset, used to read directly from storage when staging is off                         |

`ci.env()` reads them like any other variable. `ci.profile()` reads
them internally to set span attribution and pick the transport.

```python theme={null}
run_id       = ci.env("CIRRON_RUN_ID")
workspace_id = ci.env("CIRRON_WORKSPACE_ID")
```

## Updating values on the deployment

On the deployment config panel in the Cirron platform dashboard, edit
an env var and hit apply. The platform triggers a **rolling restart**
of the deployment's containers with the new values. There is a
brief pause per replica, not zero-downtime. The next call to
`ci.env()` after restart returns the updated value; the SDK doesn't
cache env values, so no additional invalidation step is needed.

## Alternatives

`ci.env()` is a convenience, not a requirement. `os.environ.get()`,
`python-decouple`, and `pydantic-settings` all work fine with the
SDK.

## Related

<CardGroup cols={2}>
  <Card title="ci.secret" icon="key" href="/sdk/reference/secret">
    For credentials. Never pass a secret through `ci.env`.
  </Card>

  <Card title="Configuration guide" icon="gear" href="/sdk/configuration">
    Full resolution order: explicit → env → `config.toml` → defaults.
  </Card>
</CardGroup>
