Skip to main content

Vautra Python SDK

Python SDK for Vautra projects, buckets, and object storage.

The SDK signs every request and sends it to https://app.vautra.com/api by default. Keep the secret access key on a trusted server; it is a credential, not a public identifier.

Requirements

  • Python 3.9 or newer.
  • requests 2.31 or newer (installed automatically).

Installation

pip install vautra-sdk

The distribution is vautra-sdk; the import name is vautra. The npm package of the same name is the separate Node.js SDK.

Authentication

Create an access key in the Vautra dashboard, then build one client and reuse it — each client owns a connection pool:

from vautra import Vautra

vautra = Vautra(
    access_key_id="...",
    secret_access_key="...",
)

Credentials fall back to the VAUTRA_ACCESS_KEY_ID and VAUTRA_SECRET_ACCESS_KEY environment variables, and api_url to VAUTRA_API_URL, when the corresponding argument is omitted:

from vautra import Vautra

with Vautra() as vautra:              # reads the environment
    page = vautra.projects.list()

Every request carries a fresh nonce, including retries, so signed headers are never replayed. Access-key permissions and project or bucket restrictions are enforced by the Vautra backend.

Invalid configuration raises VautraConfigError immediately, before any request is sent. api_url must use https:// unless it points at a loopback address, so signed credentials never travel over plaintext.

Client options

Option Default Description
access_key_id $VAUTRA_ACCESS_KEY_ID Required.
secret_access_key $VAUTRA_SECRET_ACCESS_KEY Required. Never logged; the client redacts it in repr().
api_url $VAUTRA_API_URL or https://app.vautra.com/api Must be https:// for remote hosts.
timeout 30.0 Seconds, for non-upload requests. Use 0 or None to disable.
session new session Supply your own requests.Session to control proxies or TLS verification.

Every method also accepts a per-call timeout= override and a cancel_event= (a threading.Event).

Vautra is a context manager, and close() releases the connection pool:

with Vautra(access_key_id="...", secret_access_key="...") as vautra:
    ...

Object keys

Vautra object keys are flat file names, not S3-style paths:

  • No / or \ separators — documents/report.pdf is rejected.
  • Maximum 255 bytes (UTF-8), no control characters, no trailing period.
  • The key must end in a supported extension.

Supported extensions are currently: txt, csv, json, xml, html, css, js, ts, md, pdf, png, jpg, jpeg, gif, webp, svg, zip, gz, doc, docx, xlsx, pptx, mp3, mp4, webm, wav, ogg. Files whose contents do not match their extension are rejected on upload.

Invalid keys raise VautraError immediately, before an upload session is created.

Projects

page = vautra.projects.list(
    page=1,
    page_size=20,
    search="production",
    key_management="managed",
)

project = vautra.projects.get("project-id")

List methods return {"data": [...], "meta": {"page", "pageSize", "total", "totalPages"}}.

Buckets

page = vautra.buckets.list(project_id="project-id", page=1, page_size=20)

bucket = vautra.buckets.get("bucket-id")

created = vautra.buckets.create(
    project_id="project-id",
    name="documents",
    versioning_enabled=True,
)

Bucket deletion is intentionally not exposed by the SDK.

List objects

page = vautra.objects.list("bucket-id", page=1, page_size=20, search="invoice")

Upload objects

For large local files, pass a path. The SDK reads only the active chunks instead of loading the whole file into memory:

obj = vautra.objects.upload(
    bucket_id="bucket-id",
    key="movie.mp4",
    body="C:/videos/movie.mp4",     # str, pathlib.Path, or {"path": ...}
    content_type="video/mp4",
)

For content already in memory:

vautra.objects.upload(
    bucket_id="bucket-id",
    key="hello.txt",
    body=b"Hello from Vautra",
    content_type="text/plain",
)

When content_type is omitted, Vautra derives the stored MIME type from the key's extension.

Supported body types

Body Behaviour
bytes, bytearray, memoryview Used directly.
str Encoded as UTF-8.
pathlib.Path, os.PathLike, {"path": "..."} Opened and read by range; memory stays flat.
A seekable binary file object Read by range from its current position. The SDK does not close a handle it did not open.
A non-seekable stream (pipe, socket, generator of bytes) Spooled to a temporary file so failed parts can be retried, then cleaned up.
Any object with size and read(start, end) Used as a random-access source.

A stream cannot be rewound, so a failed part could not otherwise be retried. Spooling keeps memory flat regardless of stream size. Prefer a path when the data is already on disk.

Text-mode file objects are rejected — open files with "rb".

Upload options

import threading

cancel = threading.Event()

vautra.objects.upload(
    bucket_id="bucket-id",
    key="archive.zip",
    body="./archive.zip",
    concurrency=2,            # 1-4
    max_attempts=3,           # 1-5
    attempt_timeout=180.0,    # seconds per request
    cancel_event=cancel,
    on_started=lambda upload_id: print("session", upload_id),
    on_progress=lambda p: print(p["stage"], p["loadedBytes"], p["totalBytes"]),
)

Progress stages are starting, uploading, finalizing, and success. loaded_bytes never goes backwards and a retried part is counted once.

Part and completion requests retry network failures, HTTP 408, 429, and 5xx. Retry delays are one second then three seconds. Other 4xx responses are terminal, as are errors raised locally by the SDK.

If an upload fails after its session is created, the SDK makes a best-effort request to cancel and clean up that session. Secure cross-process resume is not supported.

SDK access keys work only with Vautra-managed projects and their buckets. Customer-managed projects are intentionally excluded from SDK access-key scopes.

Upload status and cancellation

status = vautra.objects.upload_status("upload-id")
vautra.objects.cancel_upload("upload-id")

upload_status() is for inspection only; it does not enable resume.

To cancel a running upload, set the threading.Event you passed as cancel_event:

import threading

cancel = threading.Event()
worker = threading.Thread(
    target=vautra.objects.upload,
    kwargs={
        "bucket_id": "bucket-id",
        "key": "large.zip",
        "body": "./large.zip",
        "cancel_event": cancel,
    },
)
worker.start()
cancel.set()

The upload raises VautraCancelledError, and the session is cleaned up. An already-set event raises before any request is sent.

Because requests is synchronous, cancellation takes effect between parts and between retry attempts — it does not interrupt a request already on the wire. attempt_timeout bounds that window.

Download objects

Return the object as bytes:

data = vautra.objects.download("object-id")

Buffered downloads are capped at 256 MiB so a large object cannot exhaust memory. Pass max_bytes to change the cap, or 0 to disable it. Objects above the cap raise VautraError with status 413.

Write directly to a file, which streams and is not capped:

vautra.objects.download("object-id", destination="./report.pdf")

The file is written to a temporary sibling and renamed into place, so an interrupted download never leaves a truncated file at destination.

Or consume the stream yourself:

with vautra.objects.download_stream("object-id") as stream:
    print(stream.content_type, stream.content_length)
    for chunk in stream:
        sink.write(chunk)

Downloads through the SDK are available only for Vautra-managed projects.

Delete objects

vautra.objects.delete("object-id")

Deletion is subject to access-key permissions and backend object-state rules.

Errors

Every SDK error derives from VautraError:

from vautra import VautraError

try:
    vautra.buckets.get("missing-bucket")
except VautraError as error:
    print(error.status, error.code, error.message)
Exception Raised when
VautraError The API returned a failure. Carries status, code, details.
VautraConfigError Client configuration is unusable. Raised before any request.
VautraTimeoutError A request exceeded its time budget (status 408).
VautraConnectionError The API could not be reached (status 0).
VautraCancelledError The caller's cancel_event was set.

Errors also expose retryable, which the upload retry loop uses to avoid burning attempts on failures that would repeat identically.

The SDK never follows redirects: signed credentials are not forwarded to another host, and an unexpected 3xx surfaces as a VautraError with code unexpected_redirect.

Thread safety

A Vautra client is safe to share across threads. Uploads use a bounded worker pool internally and read bodies under a lock.

Development

python -m venv .venv && .venv/Scripts/activate    # or source .venv/bin/activate
pip install -e ".[dev]"
pytest
ruff check . && mypy

The test suite runs against a mock Vautra API whose signature verification is a port of the backend's verifier, so a passing test means the SDK interoperates with the real service rather than with a permissive stub.

To try a real upload:

python examples/upload_file.py ./examples/sample.txt --bucket-id BUCKET --key sample.txt

License

MIT. See LICENSE.

Release files for vautra-sdk 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for vautra-sdk 1.0.0
File Size Uploaded
vautra_sdk-1.0.0.tar.gz 43.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for vautra-sdk 1.0.0
File Interpreter ABI Platform
vautra_sdk-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 75.5 kB

Release files / vautra_sdk-1.0.0.tar.gz

Download URL vautra_sdk-1.0.0.tar.gz
Size 43.0 kB
Tags Source
SHA-256 checksum
How to use checksums
97ce5200c4419e5687ec4e443139a1f4215e7acfab97e404f80de9d9339aaa40
BLAKE2b-256 checksum
How to use checksums
aa253c56ea6360629c929ddcce65680ba338bb6314d1c9d4e49a12df2300fa4b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.5

Release files / vautra_sdk-1.0.0-py3-none-any.whl

Download URL vautra_sdk-1.0.0-py3-none-any.whl
Size 32.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5a312a2ac76c7cfb464d9ac08628689078357cae6078dd8d4c069fef2324fe1f
BLAKE2b-256 checksum
How to use checksums
fcf0e8926d22984edbce5ea9e788255703ee98d9d7d0731e51c390956927dc3c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.5

Release history Release notifications | RSS feed

1.1.2

2 release files

1.1.1

2 release files

1.1.0

2 release files

This release

1.0.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page