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

# Python SDK

> Install and configure the Cognisafe Python SDK.

## Installation

<CodeGroup>
  ```bash OpenAI only theme={null}
  pip install cognisafe
  ```

  ```bash With Anthropic theme={null}
  pip install "cognisafe[anthropic]"
  ```

  ```bash All providers theme={null}
  pip install "cognisafe[all]"
  ```
</CodeGroup>

The base package includes OpenAI and Mistral support. Install extras for Anthropic (`anthropic`) and Cohere (`cohere`), or use `[all]` to get everything.

## Configuration

Call `cognisafe.configure()` once at application startup, before any LLM calls are made.

```python theme={null}
import cognisafe

cognisafe.configure(
    api_key="csk_your_key_here",
    project_id="my-app",
    proxy_url="http://localhost:8080",   # default; omit for cloud
    api_url="http://localhost:8000",     # default; omit for cloud
)
```

<Warning>
  `configure()` must be called before any patch function or LLM call. Patching before configuration raises a `CognisafeNotConfiguredError`.
</Warning>

### Parameters

| Parameter    | Type  | Required | Default                        | Description                                                    |
| ------------ | ----- | -------- | ------------------------------ | -------------------------------------------------------------- |
| `api_key`    | `str` | Yes\*    | `COGNISAFE_API_KEY` env var    | Your project API key (`csk_...`)                               |
| `project_id` | `str` | Yes\*    | `COGNISAFE_PROJECT_ID` env var | Logical project name — used to group requests in the dashboard |
| `proxy_url`  | `str` | No       | `http://localhost:8080`        | URL of the Cognisafe Go proxy                                  |
| `api_url`    | `str` | No       | `http://localhost:8000`        | URL of the Cognisafe FastAPI backend                           |

\* Required if the corresponding environment variable is not set.

### Environment variables

As an alternative to passing values to `configure()`, set these environment variables:

```bash theme={null}
export COGNISAFE_API_KEY="csk_your_key_here"
export COGNISAFE_PROJECT_ID="my-app"
```

`configure()` reads these automatically when the keyword arguments are omitted.

## Provider patches

### OpenAI (proxy mode)

```python theme={null}
import cognisafe
from openai import OpenAI

cognisafe.configure(api_key="csk_...", project_id="my-app")
cognisafe.patch_openai()

client = OpenAI()  # base_url is now the Cognisafe proxy

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Summarise this document."}],
)
```

`patch_openai()` rewrites `openai.base_url` so all calls route through the proxy. The proxy forwards them to `https://api.openai.com` and logs each request asynchronously.

### Anthropic (direct mode)

```python theme={null}
import cognisafe
import anthropic

cognisafe.configure(api_key="csk_...", project_id="my-app")
cognisafe.patch_anthropic()

client = anthropic.Anthropic()

message = client.messages.create(
    model="claude-opus-4-5",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello."}],
)
```

Requires `pip install "cognisafe[anthropic]"`. The SDK wraps `messages.create` and ships payloads to the backend after the response is returned.

### Mistral (proxy mode)

```python theme={null}
import cognisafe
from mistralai import Mistral

cognisafe.configure(api_key="csk_...", project_id="my-app")
cognisafe.patch_mistral()

client = Mistral()

response = client.chat.complete(
    model="mistral-large-latest",
    messages=[{"role": "user", "content": "Hello."}],
)
```

### Cohere (direct mode)

```python theme={null}
import cognisafe
import cohere

cognisafe.configure(api_key="csk_...", project_id="my-app")
cognisafe.patch_cohere()

client = cohere.Client()

response = client.chat(
    model="command-r-plus",
    message="Hello.",
)
```

Requires `pip install "cognisafe[all]"`.

## The `@cognisafe.trace` decorator

Use `trace` for any LLM call that doesn't go through a patched provider — custom endpoints, fine-tuned models, internal APIs:

```python theme={null}
import cognisafe
import requests

cognisafe.configure(api_key="csk_...", project_id="my-app")

@cognisafe.trace(model="my-fine-tuned-gpt4o")
def call_internal_model(prompt: str) -> str:
    resp = requests.post(
        "https://internal.example.com/v1/chat",
        json={"messages": [{"role": "user", "content": prompt}]},
        headers={"Authorization": "Bearer sk-internal-..."},
    )
    return resp.json()["choices"][0]["message"]["content"]

result = call_internal_model("Classify this support ticket.")
```

The decorator captures the function's input arguments and return value, then ships them to `/internal/log` in a background thread. The decorated function's execution is not blocked.
