Metadata-Version: 2.4
Name: velt-py
Version: 0.1.14
Summary: Python SDK for integrating Velt comments, reactions, attachments, and user management into Django applications
Home-page: https://github.com/snippyly/velt-py-sdk
Author: Velt
Author-email: Velt <support@velt.dev>
License: MIT
Project-URL: Homepage, https://github.com/snippyly/velt-py-sdk
Project-URL: Repository, https://github.com/snippyly/velt-py-sdk
Keywords: velt,comments,collaboration,django,mongodb
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.8
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: Framework :: Django
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pymongo[srv,tls]>=4.6.3
Requires-Dist: mongoengine>=0.27.0
Requires-Dist: blinker>=1.8.2
Requires-Dist: python-dateutil>=2.8.2
Requires-Dist: requests>=2.25.0
Requires-Dist: boto3>=1.28.0
Provides-Extra: auth
Requires-Dist: PyJWT>=2.8.0; extra == "auth"
Requires-Dist: cryptography>=42.0.0; extra == "auth"
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
Requires-Dist: mongomock>=4.1.2; extra == "dev"
Requires-Dist: responses>=0.23.0; extra == "dev"
Requires-Dist: PyJWT>=2.8.0; extra == "dev"
Requires-Dist: cryptography>=42.0.0; extra == "dev"
Dynamic: author
Dynamic: home-page
Dynamic: license-file
Dynamic: requires-python

# Velt Python SDK

Velt is an SDK to add collaborative features to your product within minutes. Example: Comments like Figma, Frame.io, Google Docs or Sheets, Recording like Loom, Huddles like Slack, and much more.

`velt-py` is the official **backend SDK** for Velt. Use it to power a self-hosted Velt backend or to call Velt's REST APIs directly from any Python service.

The SDK exposes two independent backends:

| Backend          | Namespace           | Use case                                              |
| ---------------- | ------------------- | ----------------------------------------------------- |
| **Self-hosting** | `sdk.selfHosting.*` | Store Velt data in your own MongoDB + AWS S3          |
| **REST API**     | `sdk.api.*`         | Call Velt's REST APIs directly — no database required |

- **Self-hosting** (`sdk.selfHosting.*`) simplifies backend implementation by up to **90%**. Pass your DB and storage configs to the SDK, call the relevant method with the raw frontend request payload, and return the response directly to the client.
- **REST API** (`sdk.api.*`) provides fully-typed `@dataclass` request objects across all Velt REST services, returning raw Velt API responses. No database or AWS configuration needed.

## Features

With Velt you can add powerful collaboration features to your backend extremely fast:

- **Comments** like Figma, Frame.io, Google Docs, Sheets and more
- **Recording** like Loom (audio, video, screen)
- **Huddle** like Slack (audio, video, screensharing)
- In-app and off-app **notifications**
- **@mentions** and assignment
- **Presence**, **Cursors**, **Live Selection**
- **Live state sync** and **multiplayer editing** with conflict resolution (CRDT)
- **Activities**, **access control**, **GDPR** data tooling, and AI-powered **agents** & **workflows**
- ... and so much more

## Installation

```bash
pip install velt-py
```

### Requirements

- Python 3.8+
- MongoDB 6+ (Percona Server or MongoDB Atlas) for self-hosting
- `requests` for REST API calls (installed automatically)
- `pymongo` and `boto3` for the self-hosting backend (MongoDB + optional S3 attachments)

## Quick Start

### Initialize the SDK

**Self-hosting** (MongoDB + optional AWS S3):

```python
from velt_py import VeltSDK

sdk = VeltSDK.initialize({
    'database': {
        'connection_string': 'mongodb+srv://user:pass@cluster.mongodb.net/velt-db',
        # Or pass individual components:
        # 'host': 'localhost:27017',
        # 'username': 'your-username',
        # 'password': 'your-password',
        # 'auth_database': 'admin',
        # 'database_name': 'velt-db',
    },
    'apiKey': 'YOUR_VELT_API_KEY',       # or set VELT_API_KEY
    'authToken': 'YOUR_VELT_AUTH_TOKEN', # or set VELT_AUTH_TOKEN
})
```

**REST API only** (no database needed):

```python
from velt_py import VeltSDK

sdk = VeltSDK.initialize({
    'apiKey': 'YOUR_VELT_API_KEY',
    'authToken': 'YOUR_VELT_AUTH_TOKEN',
})

# All sdk.api.* services are now available
result = sdk.api.organizations.getOrganizations(
    GetOrganizationsRequest(organizationIds=['org-123'])
)
```

### Self-hosting example

Each self-hosting method takes a single typed resolver-request object — build it from the incoming frontend JSON with `from_dict(data)` and return the result straight to the client:

```python
from velt_py import GetCommentResolverRequest

result = sdk.selfHosting.comments.getComments(
    GetCommentResolverRequest.from_dict(data)
)
```

#### Comment `save` payload extensions

The comment `save` request mirrors the frontend contract:

- **`targetComment`** — `SaveCommentResolverRequest.targetComment` is the `PartialComment` the
  action occurred on (resolved by the frontend from `commentId`). It is request context for your
  handler only; `saveComments` does **not** persist it (the comment already lives inside the
  annotation's `comments` map).
- **`CommentResolverSaveEvent`** — when the frontend opts into additional save events, the
  `event` field carries one of these non-core values (status change, priority, assign, approve,
  reaction, subscribe, …) in addition to the core `ResolverActions`. `from_dict` parses core
  events to `ResolverActions`, additional events to `CommentResolverSaveEvent`, and any unknown
  value is preserved as a plain string.

```python
from velt_py import SaveCommentResolverRequest, ResolverActions, CommentResolverSaveEvent

request = SaveCommentResolverRequest.from_dict(data)

if request.event == CommentResolverSaveEvent.PRIORITY_CHANGE:
    ...  # react to an annotation-level priority change
elif request.targetComment is not None:
    ...  # the specific comment the action targeted

sdk.selfHosting.comments.saveComments(request)
```

#### Verifying the forwarded resolver token

When the Velt frontend forwards an auth credential to your resolver endpoint (e.g. an
`Authorization: Bearer <token>` header), `sdk.selfHosting.verifyToken(...)` authenticates it before
you serve any data. It is opt-in via a `resolver_auth` config block, framework-agnostic (pass a
headers mapping or a raw token), and **fail-closed** — it returns a structured `VerifyTokenResult`
and never raises for a verification outcome.

Install the JWT extra if you use the built-in verifier (the custom-callback path needs nothing
extra):

```bash
pip install 'velt-py[auth]'
```

```python
sdk = VeltSDK.initialize({
    'database': {...},
    'resolver_auth': {
        # Built-in JWT/JWKS verifier:
        'jwt': {
            'secret': 'your-hmac-secret',          # HS*  — or, for RS*/ES*:
            # 'public_key': '-----BEGIN PUBLIC KEY-----...',
            # 'jwks_url': 'https://your-idp/.well-known/jwks.json',
            'algorithms': ['HS256'],               # REQUIRED allowlist (rejects alg=none / confusion)
            'issuer': 'https://your-idp',          # optional, enforced when set
            'audience': 'velt',                    # optional, enforced when set
            'leeway': 30,                          # optional clock skew (seconds)
            # 'require': ['exp'],                  # optional: reject tokens missing these claims
        },
        # OR a custom escape hatch (takes priority over `jwt`):
        # 'verify': lambda token, headers: my_decode(token),  # return claims | None
    },
})

result = sdk.selfHosting.verifyToken(headers=request.headers)   # or token='...'
if not result.verified:
    return HttpResponse(status=401)        # result.errorCode tells you why
# result.claims holds the decoded payload
sdk.selfHosting.comments.saveComments(SaveCommentResolverRequest.from_dict(data))
```

`verifyToken` **authenticates only — it does not authorize**. The resolver services keep their own
`apiKey`/`organizationId` scoping, and `result.claims` is informational: if you need tenant
isolation, assert the relevant claim (e.g. an org id) against the resolver payload yourself.

### REST API example

Each `sdk.api.*` method takes a single typed request dataclass:

```python
from velt_py.models.comment_annotation_api import AddCommentAnnotationsRequest

sdk.api.commentAnnotations.addCommentAnnotations(
    AddCommentAnnotationsRequest(
        organizationId='org-123',
        documentId='doc-1',
        commentAnnotations=[{
            'location': {'id': 'section-1', 'locationName': 'Introduction'},
            'commentData': [{
                'commentText': 'This needs review',
                'from': {'userId': 'user-1', 'name': 'John Doe', 'email': 'john@example.com'},
            }],
        }],
    )
)
```

### Framework integration

Initialize the SDK once and reuse it across requests. For example, with FastAPI:

```python
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from velt_py import VeltSDK, GetCommentResolverRequest

app = FastAPI()
sdk = VeltSDK.initialize({'database': {'connection_string': 'mongodb+srv://...'}})

@app.post('/api/velt/comments/get')
async def get_comments(request: Request):
    data = await request.json()
    result = sdk.selfHosting.comments.getComments(GetCommentResolverRequest.from_dict(data))
    return JSONResponse(content=result, status_code=result.get('statusCode', 200))
```

See the [Python SDK documentation](https://velt.dev/docs/backend-sdks/python) for Django, Flask, and FastAPI integration guides.

### Shutdown

Call `sdk.close()` during graceful shutdown to release the database connection pool:

```python
sdk.close()
```

## Documentation

- Read the [Python SDK documentation](https://velt.dev/docs/backend-sdks/python) for the full setup guide, configuration reference, and a complete list of `sdk.selfHosting.*` and `sdk.api.*` methods with request/response examples.
- Browse the broader [Velt documentation](https://docs.velt.dev/get-started/overview) for guides and frontend SDK references.
- [velt-py on PyPI](https://pypi.org/project/velt-py)

## Use cases

- Explore [use cases](https://velt.dev/use-case) to learn how collaboration could look on your product.
- [Figma Template](https://www.figma.com/community/file/1402312407969730816/velt-collaboration-kit): visualize what collaboration features could look like on your product.

## Releases

- See the [latest changes](https://docs.velt.dev/release-notes/).

## Security

- Velt is SOC2 Type 2 and HIPAA compliant. [Learn more](https://velt.dev/security)

## Community

- [X](https://x.com/veltjs): updates, announcements, and general Velt tips.
- [Discord](https://discord.gg/GupvcYH27h): ask questions and share tips.

## License

MIT

## Support

For issues and questions, contact support@velt.dev or visit [docs.velt.dev](https://docs.velt.dev).
