# Files

> The runner files resource — upload files and attach their IDs to an agent run.

Source: https://maincode.com/docs/python-agent-sdk-files
Section: Agent SDK · Matilda documentation

---

The `Runner` exposes a `files` resource (the client SDK's `FilesResource`) for uploading and retrieving files. Uploaded files can be attached to agent runs via `file_ids`.

## `runner.files.upload(file, ...)`

Uploads a single file by path. Files at or above the chunked threshold use the parallel multipart protocol; smaller files use single-shot upload.

```python title="upload.py"
async def main():
    result = await runner.files.upload(
        "hello.txt",
        content_type="text/plain",
        on_progress=lambda pct: print(f"Upload: {pct}%"),
    )
    print(f"File ID: {result.file_id}, Status: {result.status}")
```

### Parameters

| Field | Type | Description |
| - | - | - |
| `file` | `str \| Path` | Path to the file to upload (required). |
| `content_type` | `str` | MIME type. Defaults to 'application/octet-stream'. |
| `filename` | `str \| None` | Override the reported filename. Defaults to the path basename. |
| `on_progress` | `Callable[[int], None] \| None` | Progress callback (0–100). |

Returns `FileComplete`:

```python
@dataclass
class FileComplete:
    file_id: str
    status: str  # 'pending' | 'scanning' | 'processing' | 'ready' | 'failed' | 'rejected'
```

## `runner.files.upload_many(files, *, file_concurrency=3, ...)`

Uploads multiple files in parallel. One file's failure does not abort the others — per-file outcomes arrive in the result list as `FileComplete` or `UploadError`.

```python title="upload_many.py"
from matilda_client import UploadError


async def main():
    results = await runner.files.upload_many(["doc1.txt", "doc2.txt"])
    for i, result in enumerate(results):
        if isinstance(result, UploadError):
            print(f"File {i} failed: {result}")
        else:
            print(f"File {i}: {result.file_id} ({result.status})")
```

Returns `list[FileComplete | UploadError]`.

## `runner.files.retrieve(file_id)`

Retrieves metadata for a previously uploaded file.

```python
file = await runner.files.retrieve("file-abc123")
print(f"{file['filename']} — {file['status']} ({file['sizeBytes']} bytes)")
```

Returns a `dict` (a `FileAttachment`: `id`, `filename`, `contentType`, `sizeBytes`, `status`, optional `extractedText`, `thumbnailUrl`, `localUri`, `failureReason`, `createdAt`).

## Using files in agent runs

Upload a file, then reference its `file_id` in an agent run:

```python title="use_files.py"
async def main():
    upload = await runner.files.upload("report.txt", content_type="text/plain")

    result = await runner.run(
        {"name": "analyst", "purpose": "analysis", "instructions": "Summarise the report."},
        "What are the key findings?",
        file_ids=[upload.file_id],
    )
    print(result.final_output)
```
