Platform
ScaiWave ScaiGrid ScaiCore ScaiBot ScaiDrive ScaiKey Models Tools & Services
Solutions
Organisations Developers Internet Service Providers Managed Service Providers AI-in-a-Box
Resources
Support Documentation Blog Downloads
Company
About Research Careers Investment Opportunities Contact
Log in

Python SDK reference

Complete reference for the scaiatlas Python SDK (v0.1.2). Install with pip install scaiatlas (Python 3.9+).

Clients#

ScaiAtlas (sync)#

python
1
2
3
4
5
6
7
8
9
ScaiAtlas(
    *,
    api_key: str | None = None,
    auth: Authenticator | None = None,
    base_url: str = "https://api.scaiatlas.io",
    timeout: float = 30.0,
    retry_config: RetryConfig | None = None,
    config: ClientConfig | None = None,
)

If config is given, its base_url/timeout/retry_config win. Auth precedence: api_keyauth → anonymous. Use as a context manager to close cleanly.

Constructors:

Method Purpose
ScaiAtlas.from_env() Read SCAIATLAS_API_KEY, SCAIATLAS_BASE_URL, SCAIATLAS_TIMEOUT, SCAIATLAS_VERIFY_SSL.
ScaiAtlas.with_oauth(client_id, *, base_url=…, auth_url=…, scopes=None, **kw) Browser OAuth (PKCE).
ScaiAtlas.with_device_flow(client_id="scaiatlas-cli", *, base_url=…, auth_url=…, scopes=None, **kw) Headless device flow.

Instance methods: login(), logout(), close(), __enter__/__exit__. (login/logout apply to OAuth/device-flow clients.)

Resource properties: namespaces, models, versions, variants, upload, download, search, admin (→ .users, .groups, .api_keys).

python
1
2
3
4
5
from scaiatlas import ScaiAtlas

with ScaiAtlas.from_env() as client:
    for ns in client.namespaces.list_all():
        print(ns.name)

AsyncScaiAtlas (async)#

Same constructors and configuration. Use async with; await every operation.

python
1
2
3
4
5
6
7
8
9
import asyncio
from scaiatlas import AsyncScaiAtlas

async def main():
    async with AsyncScaiAtlas(api_key="sk_live_...") as client:
        async for ns in client.namespaces.list_all():
            print(ns.name)

asyncio.run(main())

Resource properties: namespaces, models, versions, variants, search, admin. upload and download are sync-only and are not exposed on the async client — run transfers with ScaiAtlas (e.g. in a thread executor).

ClientConfig#

python
1
2
3
ClientConfig(base_url="https://api.scaiatlas.io", timeout=30.0,
             retry_config=RetryConfig(), verify_ssl=True)
ClientConfig.from_env()

RetryConfig#

Import from scaiatlas._http.retry.

python
1
2
3
RetryConfig(max_retries=3, initial_delay=0.5, max_delay=30.0,
            exponential_base=2.0, jitter=0.1,
            retryable_status_codes={408, 429, 500, 502, 503, 504})

Exponential backoff with jitter; retries the status codes above.


Pagination#

List methods return PaginatedResponse[T]:

python
1
2
3
4
5
resp = client.models.list("poolnoodle", per_page=50)
resp.items            # list[Model] for this page
resp.pagination       # PaginationMeta: page, per_page, total_pages, total_count, has_next, has_prev
for m in resp:        # iterate this page
    ...

Every list method has a companion that transparently walks all pages:

python
1
2
3
4
for m in client.models.list_all("poolnoodle"):   # sync: Iterator[Model]
    ...
async for m in aclient.models.list_all("poolnoodle"):   # async: async generator
    ...

Namespaces — client.namespaces#

Method Signature
list (*, page=1, per_page=20, visibility=None) -> PaginatedResponse[Namespace]
list_all (*, per_page=100, visibility=None) -> Iterator[Namespace]
get (name) -> Namespace
create (name, *, display_name=None, description=None, visibility="tenant") -> Namespace
update (name, *, display_name=None, description=None) -> Namespace
delete (name) -> None
list_members (name, *, page=1, per_page=20) -> PaginatedResponse[NamespaceMember]
add_member (name, user_id, role="member") -> NamespaceMember
remove_member (name, user_id) -> None

visibilitypublic|tenant|private. roleowner|admin|member|viewer.


Models — client.models#

Method Signature
list (namespace, *, page=1, per_page=20, type=None, tags=None) -> PaginatedResponse[Model]
list_all (namespace, *, per_page=100, type=None, tags=None) -> Iterator[Model]
get (namespace, name) -> Model
create (namespace, name, *, type, display_name=None, description=None, license=None, capabilities=None, modalities=None, metadata=None, tags=None) -> Model
update (namespace, name, *, display_name=None, description=None, license=None, capabilities=None, modalities=None, metadata=None, tags=None) -> Model
delete (namespace, name) -> None

type is a required keyword on create (a model type).


Versions — client.versions#

Method Signature
list (namespace, model, *, page=1, per_page=20) -> PaginatedResponse[Version]
list_all (namespace, model, *, per_page=100) -> Iterator[Version]
get (namespace, model, version) -> Version
create (namespace, model, version, *, format, release_notes=None, requirements=None, quantization=None, files=None) -> Version
update (namespace, model, version, *, release_notes=None, status=None) -> Version
delete (namespace, model, version) -> None

version may be latest on get. For publishing files, prefer the upload manager (below) over calling create directly.


Variants — client.variants#

Method Signature
list (namespace, model, version, *, page=1, per_page=20) -> PaginatedResponse[Variant]
list_all (namespace, model, version, *, per_page=100) -> Iterator[Variant]
get (namespace, model, version, name) -> Variant
create (namespace, model, version, variant_name, *, format, quantization=None) -> Variant
delete (namespace, model, version, name) -> None

formatsafetensors|pytorch|gguf|onnx|other.


Search — client.search#

Method Signature
models (query, *, page=1, per_page=20, type=None, tag=None, namespace=None, sort="updated", order="desc") -> PaginatedResponse[Model]
models_all (query, *, per_page=100, type=None, tag=None, namespace=None, sort="updated", order="desc") -> Iterator[Model]
namespaces (query, *, page=1, per_page=20) -> PaginatedResponse[Namespace]
namespaces_all (query, *, per_page=100) -> Iterator[Namespace]

sortupdated|created|name|downloads; orderasc|desc. Filter by a single tag.


Upload — client.upload (sync only)#

python
1
2
3
4
5
6
7
8
session = client.upload.version(
    namespace, model, version, *,
    format: str,
    release_notes: str | None = None,
    requirements: dict | None = None,
    chunk_size: int = 10 * 1024 * 1024,       # 10 MB
    progress_callback: Callable[[UploadProgress], None] | None = None,
) -> UploadSession

UploadSession (context manager):

Method Purpose
add_file(path, *, target_path=None) Add one file (computes SHA-256, streams chunks).
add_directory(dir, *, pattern="*", recursive=True) Add every matching file.
complete() -> Version Finalize the version.
abort() Cancel and clean up.

If an exception leaves the with block before complete(), the session auto-aborts.

UploadProgress (dataclass): file_path, file_name, bytes_uploaded, total_bytes, chunk_index, total_chunks, and percent_complete (property).


Download — client.download (sync only)#

Method Signature
version (namespace, model, version, destination, *, resume=False, verify_checksum=True, progress_callback=None, chunk_size=8*1024*1024) -> list[Path]
file (namespace, model, version, file_path, destination, *, resume=False, verify_checksum=True, progress_callback=None, chunk_size=…) -> Path
stream (namespace, model, version, file_path, *, chunk_size=…) -> Iterator[bytes]

DownloadProgress (dataclass): file_path, file_name, bytes_downloaded, total_bytes, and percent_complete (property).


Admin — client.admin#

client.admin.users, client.admin.groups, client.admin.api_keys.

Userslist(*, page=1, per_page=20, search=None), list_all(...), get(user_id), list_permissions(user_id, *, page=1, per_page=20, resource_type=None), grant_permission(user_id, resource_type, resource_id, permission), revoke_permission(user_id, permission_id). resource_typenamespace|model|version; permissionread|write|admin.

Groupslist(*, page=1, per_page=20, search=None), list_all(...), get(group_id), list_members(group_id, *, page=1, per_page=20), list_members_all(...).

API keyslist(*, page=1, per_page=20, user_id=None), list_all(...), get(key_id), create(name, *, scopes=None, expires_in_days=None) -> APIKeyCreated, update(key_id, *, name=None, scopes=None), revoke(key_id). create returns the full key once.


Models (data types)#

Response models ignore unknown fields; request/create models forbid extras.

Namespace#

id, name, display_name?, description?, visibility (public|tenant|private, default tenant), model_count (0), created_at?, updated_at?, owner_tenant_id?.

NamespaceMember#

id, user: UserSummary?, group: GroupSummary?, role, granted_by, granted_at. UserSummary = {id, email, display_name?, tenant_id}; GroupSummary = {id, name, tenant_id}.

Model#

id, namespace, name, display_name?, description?, type (ModelType), license?, capabilities?, modalities? (Modalities), metadata?, tags?, version_count (0), latest_version?, download_count (0), created_at, updated_at, created_by?. Computed: full_name = namespace/name. Modalities = {input: [...], output: [...]}.

Version#

id, model_id, namespace, model, version, full_name, version_major, version_minor, version_patch, version_prerelease?, release_notes?, requirements?, format, quantization?, files: [VersionFile], total_size (0), checksum_sha256, status (default ready), variant_count (0), created_at, updated_at, published_at?, created_by?. VersionFile = {path, size, checksum_sha256} with computed aliases name (=path) and sha256 (=checksum_sha256).

Variant#

id, version_id, variant_name, format, quantization?, total_size (0), checksum_sha256, is_primary (False), status (default available), files: [VariantFile], created_at. VariantFile = {path, size, checksum_sha256}.

PaginatedResponse[T] / PaginationMeta#

PaginatedResponse = { items: [T], pagination: PaginationMeta }, iterable and indexable. PaginationMeta = { page, per_page, total_pages, total_count, has_next, has_prev }.

Auth models#

TokenInfo = {access_token, token_type="Bearer", expires_in?, refresh_token?, scope?}. UserInfo = {id, username, email?, display_name?, avatar_url?, created_at?}.


Exceptions#

Import from scaiatlas.exceptions (top-level for the common ones). See Errors for the full hierarchy and handling patterns. Summary:

gdscript
1
2
3
4
5
6
7
8
9
ScaiAtlasError
├── APIError (status_code, response_body)
   ├── AuthenticationError (401)   ├── ConflictError (409)
   ├── AuthorizationError (403)    ├── ValidationError (422, .errors)
   ├── NotFoundError (404)         └── RateLimitError (429, .retry_after)
├── UploadError (file_path, chunk_index)
├── DownloadError (file_path, bytes_downloaded)
   └── ChecksumError (expected, actual)
└── TimeoutError (timeout_seconds)
Updated 2026-07-16 04:44:25 View source (.md) rev 2