<p align="center">
  <img src="https://docufa.st/logo.png" alt="Docufast" width="120" />
</p>

<h1 align="center">Docufast Python SDK</h1>

<p align="center">
  <strong>Programmatic access to your Docufast workspaces, collections, and media.</strong>
</p>

<p align="center">
  <a href="https://pypi.org/project/docufast/"><img src="https://img.shields.io/pypi/v/docufast?color=orange" alt="PyPI" /></a>
  <a href="https://pypi.org/project/docufast/"><img src="https://img.shields.io/pypi/pyversions/docufast" alt="Python" /></a>
  <a href="https://docufa.st"><img src="https://img.shields.io/badge/docs-docufa.st-blue" alt="Docs" /></a>
  <a href="https://pypi.org/project/docufast/"><img src="https://img.shields.io/pypi/l/docufast" alt="License" /></a>
</p>

---

## Installation

```bash
pip install docufast
# or
poetry add docufast
# or
uv add docufast
```

## Quick Start

```python
from docufast import Docufast

client = Docufast(api_key="df_sdk_xxx", base_url="https://api.docufa.st")

# List your workspaces
workspaces = client.workspaces.list()

# Upload a document with custom metadata
doc = client.documents.upload(
    collection_id="uuid",
    file_path="./invoice.pdf",
    external_metadata={"customer_id": "123", "type": "invoice"},
)

# Create a note
note = client.notes.create(
    collection_id="uuid",
    name="Meeting Notes",
    data="Key decisions from today's meeting...",
    external_metadata={"meeting_id": "456"},
)

client.close()
```

## Context Manager

```python
with Docufast(api_key="df_sdk_xxx") as client:
    workspaces = client.workspaces.list()
    for ws in workspaces:
        print(ws.name)
```

## Resources

| Resource | Methods |
|----------|---------|
| `client.workspaces` | `list()` |
| `client.collections` | `list(workspace_id)`, `create(...)`, `delete(id)` |
| `client.documents` | `upload(...)`, `get(id)`, `update_metadata(...)`, `download(id)`, `delete(id)` |
| `client.images` | `upload(...)`, `get(id)`, `update_metadata(...)`, `delete(id)` |
| `client.audio` | `upload(...)`, `get(id)`, `update_metadata(...)`, `delete(id)` |
| `client.videos` | `upload(...)`, `get(id)`, `update_metadata(...)`, `delete(id)` |
| `client.notes` | `create(...)`, `get(id)`, `update_metadata(...)`, `delete(id)` |
| `client.entities` | `list()`, `create(...)`, `get(id)`, `delete(id)`, `link_to_document(...)` |
| `client.locations` | `list()`, `create(...)`, `get(id)`, `delete(id)`, `link_to_document(...)` |

## External Metadata

Every media type supports an `external_metadata` field — a free-form JSON object for storing app-specific data alongside your files:

```python
doc = client.documents.upload(
    collection_id="uuid",
    file_path="./report.pdf",
    external_metadata={
        "source": "billing-system",
        "customer_id": "cust_123",
        "generated_at": "2026-03-10T12:00:00Z",
    },
)

# Update metadata later
client.documents.update_metadata(doc.id, {
    "source": "billing-system",
    "customer_id": "cust_123",
    "status": "reviewed",
})
```

## Entities & Locations

Track people, companies, and physical locations linked to your documents:

```python
# Create an entity
sender = client.entities.create(name="Acme Corp", entity_type="company")

# Create a location
office = client.locations.create(name="HQ", location="123 Main St")

# Link them to a document
client.entities.link_to_document(doc.id, sender_entity_id=sender["id"])
client.locations.link_to_document(doc.id, office["id"])
```

## API Keys

Generate API keys from the **Developers** page at [docufa.st](https://docufa.st). Keys are scoped to specific workspaces and prefixed with `df_sdk_`.

## Links

- [docufa.st](https://docufa.st) — Document management platform
- [pamfili.co](https://pamfili.co) — Built by pamfili.co
