Metadata-Version: 2.3
Name: realforce-api-client
Version: 0.0.29
Summary: Python client SDK for the Realforce API
Author: Realforce
License-Expression: MIT
License-File: LICENSE
Keywords: api,client,realforce,sdk
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Requires-Dist: attrs>=22.2.0
Requires-Dist: httpx<0.29.0,>=0.23.0
Requires-Dist: pyjwt[crypto]<3,>=2.4.0
Requires-Dist: python-dateutil<3,>=2.8.0
Description-Content-Type: text/markdown

# Realforce API - Python SDK

Python client SDK for the Realforce API.

**Version:** 0.0.29

## Installation

```bash
pip install realforce-api-client
```

## Authentication

The SDK authenticates with a Bearer token in the `Authorization` header. There are two kinds of token,
depending on whether a human or a machine is calling.

### Machine-to-machine (M2M) apps — recommended for integrations

If you have a Realforce **app** (a `client_id` plus an RSA private key), the SDK does the whole OAuth
`client_credentials` + `private_key_jwt` flow for you — signing the assertion, calling the token
endpoint, caching the short-lived `rfm_` token, and refreshing it before it expires. It works for both
the `.sync()` and `.asyncio()` call variants:

```python
from realforce_api_client.authentication import create_authenticated_client
from realforce_api_client.api.agent import query_agents

client = create_authenticated_client(
    "https://api.realforce.com",
    client_id="your-client-id",
    private_key_pem=open("app-key.pem").read(),  # the PEM shown once when the app/key was created
    # optional scope-down:
    # scopes=["agents:read"],
    # workspace_ids=["00000000-0000-0000-0000-000000000000"],
)

agents = query_agents.sync(client=client, x_workspace_id=workspace_id)
```

`token_url` defaults to `{base_url}/v1/oauth/token`. A failed token request raises
`RealforceAuthenticationError` (inspect `.error` / `.error_description`, e.g. `invalid_client` when the
assertion or key is wrong).

### Personal Access Token (PAT) — for scripts acting as a user

Generate a PAT in the Realforce dashboard and send it as a Bearer token directly:

```python
from realforce_api_client import AuthenticatedClient

client = AuthenticatedClient(
    base_url="https://api.realforce.com",
    token="rfp_xxxxxxxxxxxxxxxx",
)
```

## Workspace ID

Most endpoints are scoped to a workspace. The generated client surfaces this as
an `x_workspace_id` parameter (string GUID) on each method — pass the workspace
your token has access to on every call:

```python
workspace_id = "00000000-0000-0000-0000-000000000000"
agent = get_agent.sync(client=client, agent_id=agent_id, x_workspace_id=workspace_id)
```

## Quick Start

```python
from realforce_api_client import AuthenticatedClient
from realforce_api_client.api.agent import query_agents

client = AuthenticatedClient(
    base_url="https://api.realforce.com",
    token="rfp_xxxxxxxxxxxxxxxx",
)

workspace_id = "..."
agents = query_agents.sync(client=client, x_workspace_id=workspace_id)
```

## Async Usage

Every endpoint exposes both `.sync()` and `.asyncio()` variants:

```python
import asyncio
from realforce_api_client import AuthenticatedClient
from realforce_api_client.api.agent import get_agent

client = AuthenticatedClient(
    base_url="https://api.realforce.com",
    token="rfp_xxxxxxxxxxxxxxxx",
)

async def main():
    agent = await get_agent.asyncio(client=client, agent_id=agent_id, x_workspace_id=workspace_id)

asyncio.run(main())
```

## Error Handling

By default the client raises `httpx.HTTPStatusError` for non-2xx responses. Use
the `_detailed` endpoint variants when you need to inspect the status code and
parsed body without raising:

```python
from realforce_api_client.api.agent import get_agent

response = get_agent.sync_detailed(client=client, agent_id=agent_id, x_workspace_id=workspace_id)
if response.status_code == 200:
    agent = response.parsed
else:
    print(f"HTTP {response.status_code}: {response.content!r}")
```

## Custom httpx Client

`AuthenticatedClient` wraps an `httpx.Client`. Pass `httpx_args` to configure
timeouts, retries, proxies, etc.:

```python
from realforce_api_client import AuthenticatedClient

client = AuthenticatedClient(
    base_url="https://api.realforce.com",
    token="rfp_xxxxxxxxxxxxxxxx",
    httpx_args={"timeout": 30.0},
)
```

## Requirements

- Python 3.9+
- httpx >=0.23.0, <0.29.0

## Support

- Please contact the Realforce support team.

## License

Released under the [MIT License](LICENSE). Copyright (c) 2026 Realforce.

## Third-party notices

This SDK is generated with [openapi-python-client](https://github.com/openapi-generators/openapi-python-client),
which is distributed under the MIT License. The generated client scaffolding
(`client.py`, `types.py`, `errors.py`) derives from that project's templates.

Runtime dependencies — [httpx](https://github.com/encode/httpx) (BSD-3-Clause),
[attrs](https://github.com/python-attrs/attrs) (MIT), and
[python-dateutil](https://github.com/dateutil/dateutil) (Apache-2.0 / BSD-3-Clause) —
are declared dependencies, not vendored, and remain under their respective licenses.
