Metadata-Version: 2.4
Name: vued
Version: 0.2.0
Summary: Lightweight Python SDK for the local-first Vued API
Author: Vued
License-Expression: LicenseRef-Proprietary
Project-URL: Homepage, https://vued.ai
Project-URL: Documentation, https://docs.vued.ai
Keywords: vued,sdk,api,mcp,meetings,transcripts
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
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
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown

# Vued Python SDK

Synchronous Python SDK for Vued cloud + local runtime APIs.

Use cloud APIs for auth, metadata mutations, signed audio, API keys, and webhooks. Use Vued headless or unlocked Vued Desktop for decrypted meetings, transcripts, and file names.

## For Coding Agents

Use `web-client/docs/vued-api-guide-for-coding-agents.md` as the self-contained implementation reference. Use `web-client/docs/vued-api-setup-prompt.md` for a ready-to-paste agent prompt. Use `web-client/docs/llms.txt` as the docs index.

If you need decrypted meetings, transcripts, or file names, use the local runtime API, local SDK methods, or local MCP. Cloud endpoints intentionally do not return plaintext transcript content.

## Install

```bash
pip install vued
export VUED_API_KEY="vued_live_..."
```

Development:

```bash
cd vued-python-sdk
uv sync
uv run python examples/test_public_api.py --org-id "<org_uuid>"
```

For local plaintext methods, the SDK uses a running Vued local runtime. If none
is reachable, it starts installed headless Vued first, then falls back to Vued
Desktop. Install/setup: https://docs.vued.ai/quickstart

## Quick Start

See the commented guide at `examples/quickstart.py` for org discovery, local decrypted search, pagination, and signed audio.

```python
from vued import Vued

client = Vued(
    api_key="vued_live_...",
    org_id="00000000-0000-0000-0000-000000000000",
)

results = client.search("paid ads cost", limit=10)
meeting = client.get_meeting(results["items"][0]["meeting"]["id"])

print(meeting["meeting"]["title"])
print(meeting["transcript"]["text"])
```

## Client

```python
client = Vued(
    api_key="vued_live_...",
    org_id=None,
    base_url="https://vued-office-api-dev.onrender.com/v1",
    timeout=30.0,
    auto_start_daemon=True,
)
```

| Param | Type | Meaning |
|---|---:|---|
| `api_key` | string | Supabase JWT or `vued_live_...` key. |
| `org_id` | string \| null | Default org for org-scoped calls. |
| `base_url` | string | Cloud `/v1` base URL. |
| `timeout` | float | HTTP timeout seconds. |
| `auto_start_daemon` | bool | Start installed headless Vued when local plaintext methods need it. Defaults to true. |

## Methods

Local plaintext methods require Vued headless or Vued Desktop:

```python
client.search(q, type=None, include_transcript=True, limit=20)
client.semantic_search(q, type=None, limit=5)
client.list_meetings(
    type=None,
    started_after=None,
    started_before=None,
    room_id=None,
    microphone_id=None,
    file_id=None,
    limit=100,
    cursor=None,
)
client.get_meeting(meeting_id)
client.download_meeting(meeting_id, path=".")
client.get_transcript(transcript_id)
client.list_files(
    type=None,
    q=None,
    parent_id=None,
    root_only=None,
    visibility=None,
    record_id=None,
    created_after=None,
    created_before=None,
    updated_after=None,
    updated_before=None,
    sort=None,
    limit=50,
    cursor=None,
)
client.get_file(file_id)
```

Headless daemon helpers:

```python
client.local_status()
client.ensure_daemon(start=True)
```

Cloud methods:

```python
client.list_orgs(limit=50, cursor=None)

client.get_meeting_audio(meeting_id)
client.get_transcript_audio(transcript_id)

client.create_file(name="Folder", type="folder", parent_id=None, visibility="org")
client.update_file(file_id, name=None, parent_id=..., visibility=None)
client.list_file_grants(file_id, limit=50, cursor=None)
client.grant_file(file_id, user_id)
client.revoke_file_grant(file_id, user_id)

client.list_speakers(q=None, limit=50, cursor=None)
client.get_speaker(speaker_id)

client.list_rooms(q=None, limit=50, cursor=None)
client.get_room(room_id)
client.create_room(display_name="Conference Room", microphone_id="mic-1")
client.update_room(room_id, display_name=None, microphone_id=None, is_primary=None, participant_user_ids=None)
client.list_microphones(limit=50, cursor=None)
client.get_microphone(microphone_id)

client.list_users(q=None, limit=50, cursor=None)
client.get_user(user_id)

client.list_api_keys(limit=50, cursor=None)
client.create_api_key(name="Public API key", expires_at=None, scopes=None)
client.revoke_api_key(key_id)

client.list_webhooks(limit=50, cursor=None)
client.create_webhook(name="Webhook", url="https://example.com/vued", events=["meeting.finalized"])
client.update_webhook(webhook_id, name=None, url=None, events=None, payload_fields=None, disabled=None)
client.delete_webhook(webhook_id)
```

Audio URL responses include `filename` and `mime`; signed URLs include a
`.m4a` download filename hint for M4A/AAC audio.

`type` is `None`, `"manual"`, or `"automatic"`.

`sort` for `list_files` is `name_asc`, `name_desc`, `updated_at_asc`, `updated_at_desc`, `created_at_asc`, `created_at_desc`, `date_asc`, or `date_desc`.

For `update_file`, omit `parent_id` to keep the parent, pass a folder ID to move, or pass `None` to move to root.

## Return Contracts

Pages return:

```json
{ "items": [], "next_cursor": null }
```

`search` returns:

```json
{
  "items": [
    {
      "meeting": { "id": "...", "type": "manual", "title": "...", "started_at": "..." },
      "matches": [{ "event": { "id": "...", "text": "..." }, "snippet": "..." }]
    }
  ],
  "next_cursor": null
}
```

`get_meeting` returns:

```json
{
  "meeting": { "id": "...", "object": "meeting", "type": "manual", "title": "..." },
  "transcript": {
    "text": "Speaker: hello",
    "events": [
      {
        "id": "...",
        "index": 0,
        "start": "2026-06-24T21:24:57.909Z",
        "end": "2026-06-24T21:24:58.228Z",
        "speaker": {
          "diarization_id": "speaker_1",
          "profile_id": null,
          "name": "Speaker 1",
          "type": "diarized"
        },
        "text": "Hello."
      }
    ]
  }
}
```

`get_transcript` returns:

```json
{
  "event": { "id": "...", "speaker": { "name": "Speaker 1", "type": "diarized" }, "text": "Hello." },
  "meeting": { "id": "...", "type": "manual", "title": "...", "started_at": "..." }
}
```

Signed audio methods return:

```json
{
  "available": true,
  "url": "https://...",
  "expires_at": 1782345900,
  "retention_days": 1,
  "offset_secs": { "start": 12.3, "end": 15.8 },
  "suggested_clip_secs": { "start": 9.3, "end": 18.8, "margin_secs": 3.0 }
}
```

Full route, parameter, scope, response, webhook, and MCP schemas live in:

```text
web-client/docs/local-api-sdk-mcp.md
```

## MCP

The SDK installs a local MCP stdio shim:

```bash
vued mcp
```

Development:

```bash
uv run vued mcp
```

The shim forwards MCP JSON-RPC to the active local runtime, either headless or Desktop, and exposes:

| Tool | Purpose |
|---|---|
| `search` | Keyword search decrypted meetings/transcripts. |
| `semantic_search` | Semantic search with local plaintext hydration. |
| `list_meetings` | Browse decrypted meeting records. |
| `get_meeting` | Fetch one meeting plus transcript. |
| `get_transcript` | Fetch one transcript event plus meeting ref. |

## Headless Daemon

External agents can use Vued without Electron by running the standalone local
runtime:

```bash
curl -fsSL https://get.vued.ai/install.sh | sh
export VUED_SETUP_TOKEN="vued_user_session_jwt"
export VUED_REFRESH_TOKEN="supabase_refresh_token"
export VUED_ORG_ID="org_uuid"
export VUED_API_KEY="vued_live_optional_existing_key"
export VUED_ENCRYPTION_PASSPHRASE="existing-or-new-vued-encryption-passphrase"
vued setup
```

Running `vued` or any daemon command before setup starts the same guided setup
flow. Interactive setup opens `https://vued.ai/cli-auth` in the browser, then
hands the session and refresh token back to the local CLI callback. Headless
refreshes expired Supabase sessions automatically on cloud 401s. If refresh
requires user action, `vued status`, `vued doctor`, and SDK `local_status()`
surface the daemon `auth_required` state. To change accounts later, run:

```bash
vued setup --reset
```

Setup can also install the local MCP server into detected AI tools. Run this
later if you skipped it during setup:

```bash
vued mcp install
vued mcp install --mcp-targets claude-code,codex,codex-desktop,claude-desktop,cursor
```

To remove the headless runtime and local cache:

```bash
vued uninstall
```

Development from this repo:

```bash
cd web-client
npm run headless:doctor
npm run headless:start
```

The daemon writes the same `local-api.json` discovery file used by the SDK and
MCP, so local plaintext SDK methods continue to work against either Desktop or
headless.

## Errors

```python
from vued import Vued, VuedError, VuedLocalUnavailableError

try:
    client = Vued(api_key="...", org_id="...")
    client.search("pricing")
except VuedLocalUnavailableError:
    print("Install/setup Vued from https://docs.vued.ai/quickstart")
except VuedError as err:
    print(err.status_code, err.body)
```

| Error | Meaning |
|---|---|
| `VuedError` | HTTP failure, non-2xx response, or network error. |
| `VuedLocalUnavailableError` | Local runtime is missing, not set up, locked, or unavailable. |
