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

# Platform Client

> Connect to the Kodexa Platform API from Python using the Platform Client, with typed endpoint classes, pagination, serialization, and authentication.

The Python SDK includes a full REST client for the Kodexa platform. It provides typed endpoint classes for all platform resources with built-in pagination, serialization, and authentication.

<Note>
  The platform client requires the `platform` extras:

  ```bash theme={null}
  pip install kodexa-document[platform]
  ```
</Note>

## Configuration

### Environment Variables

Set these environment variables before using the client:

| Variable              | Description                                                           |
| --------------------- | --------------------------------------------------------------------- |
| `KODEXA_URL`          | Base URL of your Kodexa platform (e.g., `https://platform.kodexa.ai`) |
| `KODEXA_ACCESS_TOKEN` | Your API access token                                                 |

### KodexaPlatform

`KodexaPlatform` provides static utility methods for managing configuration:

```python theme={null}
from kodexa_document.platform import KodexaPlatform

# Set configuration programmatically
KodexaPlatform.set_url("https://platform.kodexa.ai")
KodexaPlatform.set_access_token("your-access-token")

# Read current configuration
url = KodexaPlatform.get_url()
token = KodexaPlatform.get_access_token()

# Get platform info
info = KodexaPlatform.get_server_info()

# Create a client from current config
client = KodexaPlatform.get_client()
```

## KodexaClient

The main entry point for API interactions:

```python theme={null}
from kodexa_document.platform import KodexaClient

# Uses KODEXA_URL and KODEXA_ACCESS_TOKEN env vars
client = KodexaClient()

# Or pass explicitly
client = KodexaClient(
    url="https://platform.kodexa.ai",
    access_token="your-token"
)
```

### Available Endpoints

The client provides endpoint properties for all platform resources:

| Property                    | Type                        | Description               |
| --------------------------- | --------------------------- | ------------------------- |
| `client.organizations`      | `OrganizationsEndpoint`     | Manage organizations      |
| `client.projects`           | `ProjectsEndpoint`          | Manage projects           |
| `client.tasks`              | `TasksEndpoint`             | Manage tasks              |
| `client.document_families`  | `DocumentFamiliesEndpoint`  | Manage document families  |
| `client.executions`         | `ExecutionsEndpoint`        | View executions           |
| `client.knowledge_sets`     | `KnowledgeSetsEndpoint`     | Manage knowledge sets     |
| `client.knowledge_items`    | `KnowledgeItemsEndpoint`    | Manage knowledge items    |
| `client.knowledge_features` | `KnowledgeFeaturesEndpoint` | Manage knowledge features |
| `client.users`              | `UsersEndpoint`             | Manage users              |
| `client.memberships`        | `MembershipsEndpoint`       | Organization memberships  |

### Account Info

```python theme={null}
# Get current user
me = client.me
print(f"Logged in as: {me.first_name} {me.last_name}")

# Get platform overview
platform = client.platform
print(f"Platform version: {platform.version}")
```

## Working with Organizations

```python theme={null}
# List organizations
orgs_page = client.organizations.list()
for org in orgs_page.content:
    print(f"{org.name} ({org.slug})")

# Get a specific organization
org = client.organizations.get("org-id-123")

# Access organization resources
projects = org.projects.list()
stores = org.stores.list()
taxonomies = org.taxonomies.list()
modules = org.module_runtimes.list()
```

## Working with Projects

```python theme={null}
# List projects for an organization
projects = org.projects.list()

# Get a specific project
project = org.projects.get("project-id")

# Access project resources
assistants = project.assistants
stores = project.stores
```

## CRUD Operations

All endpoint classes follow a consistent CRUD pattern:

### List with Pagination

```python theme={null}
# List with defaults (page 1, size 20)
page = client.tasks.list()
print(f"Total: {page.total_elements}")
print(f"Pages: {page.total_pages}")

for task in page.content:
    print(task.id, task.status)

# Custom pagination
page = client.tasks.list(page=2, page_size=50)

# With search query
page = client.tasks.list(query="invoice")

# With sorting
page = client.tasks.list(sort="createdOn:desc")
```

### Streaming (All Pages)

Iterate through all pages automatically:

```python theme={null}
# Stream all tasks
for task in client.tasks.stream():
    print(task.id, task.status)

# Stream with filter
for task in client.tasks.stream(query="pending"):
    process_task(task)
```

### Get by ID

```python theme={null}
task = client.tasks.get("task-id-123")
print(task.status)
```

### Create

```python theme={null}
from kodexa_document.platform.client import TaskEndpoint

new_task = TaskEndpoint(
    title="Review document",
    description="Review the extracted data"
)
new_task.set_client(client)
created = client.tasks.create(new_task)
print(f"Created task: {created.id}")
```

### Update

```python theme={null}
task = client.tasks.get("task-id-123")
task.update_status(TaskStatus(status="IN_PROGRESS"))
```

### Delete

```python theme={null}
client.tasks.delete("task-id-123")
```

## Working with Components

Component endpoints (modules, taxonomies, stores, etc.) support slug-based operations:

```python theme={null}
# Find by slug
module = org.module_runtimes.find_by_slug("fast-pdf-model")

# Deploy a component (creates or updates)
module.deploy()

# Deploy with explicit update
module.deploy(update=True)

# Export as YAML
yaml_str = module.yaml()
```

## Resource Resolution

The client uses the platform's resolver to convert slug-based references to API paths:

```python theme={null}
# Get an object by reference
obj = client.get_object_by_ref("dataDefinitions", "my-org/invoice-taxonomy")
```

## Working with Assistants

```python theme={null}
# Get project assistants
project = org.projects.get("project-id")
assistants = project.assistants

for assistant in assistants:
    print(f"{assistant.name}: {assistant.status}")

# Send an event to an assistant
execution = assistant.send_event("document_uploaded", {
    "document_family_id": "df-123"
})

# Manage assistant memory
assistant.set_memory("config", {"threshold": 0.8})
config = assistant.get_memory("config")
```

## Working with Knowledge Items

```python theme={null}
# Create a knowledge item
item = client.knowledge_items.get("ki-123")

# Upload an attachment
item.upload_attachment("/path/to/file.pdf")

# Download an attachment
item.download_attachment("/output/path/")

# Get attachment URL
url = item.get_attachment_url()
```

## Low-level HTTP Methods

For direct API access, the client exposes HTTP methods with built-in authentication:

```python theme={null}
# GET
response = client.get("/api/projects")

# POST
response = client.post("/api/projects", body={"name": "New Project"})

# PUT
response = client.put(f"/api/projects/{project_id}", body=updated_data)

# DELETE
response = client.delete(f"/api/projects/{project_id}")

# Check existence
exists = client.exists(f"/api/projects/{project_id}")
```

All requests automatically include `X-API-Key` and `cf-access-token` headers.

## Project Import/Export

```python theme={null}
# Export a project
client.export_project(project, "/path/to/export.zip")

# Import a project
client.import_project(org, "/path/to/export.zip")
```

## Error Handling

The client raises exceptions for non-2xx HTTP responses with descriptive messages for common status codes (401, 403, 404, 409, 422, 500, etc.):

```python theme={null}
try:
    project = client.projects.get("nonexistent-id")
except Exception as e:
    print(f"API error: {e}")
```

## PipelineContext

For module developers handling execution events:

```python theme={null}
from kodexa_document.platform import KodexaPlatform

# PipelineContext tracks execution state
from kodexa_document.platform.kodexa import PipelineContext

context = PipelineContext(
    execution_id="exec-123",
    content_provider=my_provider
)

# Update execution status
context.update_status("Processing page 3 of 10", progress=3, progress_max=10)

# Check for cancellation
if context.is_cancelled():
    return
```
