client.assets¶
Bases: SyncResource
Sync image-assets namespace (client.assets).
upload_init ¶
upload_init(dataset_id: UUID | str, *, filename: str, size_bytes: int, content_type: str) -> AssetUploadSinglePart | AssetUploadMultipart
Reserve one presigned upload. Returns a single-part PUT for normal
images; a multipart plan for files over the 100 MB threshold (then
finish with :meth:upload_complete). PUT the bytes with exactly the
content_type you declare here — the presigned signature pins it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
content_type
|
str
|
MIME; must be in the accepted image set (ADR-0017). |
required |
Raises:
| Type | Description |
|---|---|
PayloadTooLargeError
|
over the 50 MB per-image cap (ASSET_TOO_LARGE). |
BadRequestError
|
unaccepted MIME (ASSET_FORMAT_UNSUPPORTED). |
ConflictError
|
dataset at its 1M-asset cap (DATASET_ASSET_CAP_EXCEEDED) or tenant asset cap (RESOURCE_LIMIT_EXCEEDED). |
upload_init_batch ¶
upload_init_batch(dataset_id: UUID | str, *, items: list[UploadItemParam]) -> AssetUploadBatchResult
Reserve up to 100 single-part uploads in one call (folder ingest).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
items
|
list[UploadItemParam]
|
up to 100 |
required |
Per-file failures are returned as upload_type="error" items (not
raised); files over the single-part threshold come back with
error_code="USE_PER_FILE_INIT".
Raises:
| Type | Description |
|---|---|
ConflictError
|
tenant asset cap reached (RESOURCE_LIMIT_EXCEEDED). |
UnprocessableError
|
empty batch or > 100 items. |
upload_complete ¶
upload_complete(dataset_id: UUID | str, upload_id: str, *, s3_key: str, parts: list[SearchQueryPartParam]) -> None
Finalize a multipart upload after every part is PUT. Returns nothing (204); the asset row is then created asynchronously by the S3-event worker.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
upload_id
|
str
|
the id from the multipart :meth: |
required |
s3_key
|
str
|
echoed from that same response. |
required |
parts
|
list[SearchQueryPartParam]
|
|
required |
Raises:
| Type | Description |
|---|---|
BadRequestError
|
|
list ¶
list(dataset_id: UUID | str, *, q: str | None = None, uploaded_by: UUID | str | None = None, status: AssetStatus | str | None = None, content_type: str | None = None, embedding_status: EmbeddingStatus | str | None = None, created_at_from: datetime | str | None = None, created_at_to: datetime | str | None = None, include: str | None = None, include_total: bool = False, limit: int | None = None, cursor: str | None = None) -> Page[Asset]
List a dataset's assets, newest first (cursor-paginated; iterate for all).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q
|
str | None
|
case-insensitive substring on the filename. |
None
|
uploaded_by
|
UUID | str | None
|
filter to assets uploaded by this user id. Exact match. |
None
|
status
|
AssetStatus | str | None
|
processing state filter ( |
None
|
content_type
|
str | None
|
filter to a single MIME type (e.g. |
None
|
embedding_status
|
EmbeddingStatus | str | None
|
|
None
|
created_at_from
|
datetime | str | None
|
keep only assets created at or after this instant
(inclusive lower bound; |
None
|
created_at_to
|
datetime | str | None
|
keep only assets created at or before this instant
(inclusive upper bound; |
None
|
include
|
str | None
|
CSV of embeds — |
None
|
include_total
|
bool
|
also populate |
False
|
Raises:
| Type | Description |
|---|---|
BadRequestError
|
malformed cursor (INVALID_CURSOR). |
UnprocessableError
|
invalid enum filter value. |
get ¶
Fetch one asset.
Raises:
| Type | Description |
|---|---|
NotFoundError
|
no such asset in this dataset (ASSET_NOT_FOUND). |
download_url ¶
Presigned GET URL for the asset's full-resolution object (1-hour expiry).
Raises:
| Type | Description |
|---|---|
NotFoundError
|
no such asset in this dataset (ASSET_NOT_FOUND). |
thumbnail_url ¶
Presigned GET URL for the 320px thumbnail (ADR-0026).
Raises:
| Type | Description |
|---|---|
NotFoundError
|
no such asset (ASSET_NOT_FOUND), or the thumbnail was
never generated — fall back to :meth: |
search ¶
search(dataset_id: UUID | str, *, parts: list[SearchQueryPartParam], instruction: str | None = None, filters: AssetFilterParam | None = None, k: int = 50, include_total: bool = False) -> SearchResult
Multimodal similarity search over embedded assets (ADR-0033). Top-K,
no pagination; only embedding_status="ready" assets participate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parts
|
list[SearchQueryPartParam]
|
ordered query blocks, each exactly one of
|
required |
instruction
|
str | None
|
optional English retrieval instruction (server picks a default when omitted). |
None
|
filters
|
AssetFilterParam | None
|
an |
None
|
k
|
int
|
1..200 (default 50). |
50
|
include_total
|
bool
|
also count filter-matching assets into |
False
|
Raises:
| Type | Description |
|---|---|
NotFoundError
|
an |
ConflictError
|
the referenced asset lost its stored vector (ASSET_NOT_EMBEDDED). |
UnavailableError
|
the embedder is down or the invocation failed (EMBEDDER_UNAVAILABLE / EMBEDDER_INVOCATION_FAILED). |
bulk_delete ¶
bulk_delete(dataset_id: UUID | str, *, asset_ids: list[UUID | str] | None = None, filter: AssetFilterParam | None = None, exclude_asset_ids: list[UUID | str] | None = None, idempotency_key: str | None = None) -> JobHandle
Delete assets in bulk, asynchronously (ADR-0023). Returns a
:class:JobHandle (202); call .wait() to poll to completion.
Pass exactly one of asset_ids or filter (an AssetFilter dict:
q filename substring / created_at_from / created_at_to /
uploaded_by / status / content_type — unknown keys 422).
exclude_asset_ids deselects rows from a filter match. For deleting
a small explicit selection synchronously, use :meth:batch_delete.
Raises:
| Type | Description |
|---|---|
ConflictError
|
idempotency key reused with a different body (IDEMPOTENCY_REPLAY). |
RateLimitError
|
per-tenant active-job cap reached (JOB_PER_TENANT_CAP). |
UnprocessableError
|
neither / both of |
batch_delete ¶
Synchronously delete an explicit selection of assets (1..1000).
Idempotent — ids not in the dataset (or already gone) come back
skipped. For large or filter-based deletes use :meth:bulk_delete.
Raises:
| Type | Description |
|---|---|
PayloadTooLargeError
|
more than 1000 ids (use :meth: |
UnprocessableError
|
empty |
upload_paths ¶
upload_paths(dataset_id: UUID | str, paths: list[str | Path], *, concurrency: int = 8) -> list[UploadResult]
Upload local files: batch upload-init → concurrent PUT. Returns one
:class:UploadResult per input path, in input order.
The asset rows are created asynchronously server-side after the PUTs
land — an ok=True result means the bytes are in S3, not that the asset
is queryable yet. Poll :meth:list until the filenames appear ready.
Files over the 100 MB single-part threshold, wrong MIME, or oversized come
back as ok=False results (handle large files via :meth:upload_init +
:meth:upload_complete). Use unique paths — client_ref is the path.
download_to ¶
Download an asset's bytes to path (parent dirs created). Fetches a
fresh presigned URL, then streams from S3 with an auth-less client.
Returns the written path.
Raises:
| Type | Description |
|---|---|
NotFoundError
|
no such asset in this dataset (ASSET_NOT_FOUND). |
Response models¶
Models returned by client.assets methods (fields, types, and what each means).
Image-asset domain models (ADR-0016/0017/0020/0033/0042).
Response shapes for the assets resource: the asset row itself, the
three-step presigned-upload envelopes, presigned download/thumbnail URLs,
multimodal search hits, and the sync batch-delete result.
AssetSummary is the compact asset reference other domains embed (project
asset-state rows) — it lives here, the lowest common module, per the type
dependency order; higher modules import it rather than re-declaring it.
UploadResult is a client-side outcome record (not a wire model): one entry
per local path handed to assets.upload_paths.
AssetUploadInit
module-attribute
¶
AssetUploadInit = Annotated[AssetUploadSinglePart | AssetUploadMultipart, Field(discriminator='upload_type')]
upload-init response — discriminated on upload_type (single | multipart).
AssetProperties ¶
Bases: BaseModel
Extracted image facts (ImageAsset.properties JSONB). {} when
extraction soft-failed, so every field is optional; extra="allow" keeps
EXIF / future keys through a round-trip.
AssetProjectMembership ¶
Bases: BaseModel
Compact project ref for the asset-list ?include=projects embed.
AssetDownloadUrl ¶
Bases: BaseModel
A short-lived presigned GET URL (content or thumbnail) + its expiry.
MultipartPartUrl ¶
Bases: BaseModel
One presigned PUT for part part_number of a multipart upload.
AssetUploadSinglePart ¶
Bases: BaseModel
upload-init result when the file fits a single PUT: PUT the bytes to
upload_url with the exact content_type you declared.
AssetUploadMultipart ¶
Bases: BaseModel
upload-init result for a large file: PUT each part to its parts[].url,
then call assets.upload_complete(..., upload_id, s3_key, parts=[{part_number,
etag}]). (Not reachable for images today — the 50 MB per-image cap is below
the 100 MB multipart threshold — but modelled for contract completeness.)
AssetUploadBatchItemResult ¶
Bases: BaseModel
Per-file outcome in a batch upload-init. Either a presigned URL
(upload_type="single") or an error (upload_type="error" with
error_code / error_message) — one bad file never poisons the rest.
Map back to your input via client_ref (the SDK uses the local path).
error_code="USE_PER_FILE_INIT" means the file exceeds the single-part
threshold; fall back to assets.upload_init for that one.
AssetUploadBatchResult ¶
Bases: BaseModel
All per-file results from a batch upload-init, in input order.
Asset ¶
Bases: BaseModel
One image asset. status is the processing lifecycle; a fresh upload is
pending until the S3-event worker creates and processes the row (poll
assets.list until your filenames appear ready). embedding_status
is semantic-search coverage (ADR-0033/0042).
AssetSummary ¶
Bases: BaseModel
Compact asset reference embedded by higher domains (project asset-state
rows) to render filename + dimensions without an N+1 lookup. No download URL
— callers fetch assets.download_url per asset when rendering.
SearchHit ¶
Bases: BaseModel
One similarity-search result. similarity is cosine in [0, 1]
(1 = identical). Carries enough asset fields to render a tile without a
follow-up GET (search is dataset-scoped, so no project tags).
SearchResult ¶
Bases: BaseModel
Top-K search response (no pagination). total is populated only when
include_total=True was passed — it counts assets matching the filter
predicate, ignoring vector ranking.
AssetBatchDeleteResultItem ¶
Bases: BaseModel
One row of the sync batch-delete outcome: deleted (removed now) or
skipped (not in this dataset / already gone — batch-delete is idempotent).
AssetBatchDeleteResult ¶
Bases: BaseModel
Aggregate + per-id results of a sync batch-delete.
UploadResult
dataclass
¶
Client-side outcome for one local path handed to assets.upload_paths.
ok is True once the bytes were PUT to S3 successfully. Note the asset row
is created asynchronously server-side afterwards — poll assets.list
until the filename appears ready before treating it as ingested.
error carries the init rejection (bad MIME, oversized) or the PUT
exception string when ok is False.
parse_upload_init ¶
Validate a raw upload-init payload into the right union member.