> ## Documentation Index
> Fetch the complete documentation index at: https://usefused.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# harnest.assets

> Public Python signatures, fields, and methods.

[All Python modules](https://usefused.com/docs/harnest/reference/api/overview.md) · [Import and compatibility guidance](https://usefused.com/docs/harnest/build/python-imports.md)

## Exports

| Name | Kind |
| - | - |
| [`AssetMediaMetadata`](#assetmediametadata) | Class |
| [`AssetNotFoundError`](#assetnotfounderror) | Class |
| [`AssetQuotaError`](#assetquotaerror) | Class |
| [`AssetRecord`](#assetrecord) | Class |
| [`AssetScope`](#assetscope) | Class |
| [`AssetStorage`](#assetstorage) | Class |
| [`AssetStore`](#assetstore) | Class |
| [`AssetStoreError`](#assetstoreerror) | Class |
| [`AssetURLStorage`](#asseturlstorage) | Class |
| [`AssetValidationError`](#assetvalidationerror) | Class |
| [`DEFAULT_MAX_ASSET_BYTES`](#default_max_asset_bytes) | Value or type alias |
| [`DEFAULT_MAX_TOTAL_ASSET_BYTES`](#default_max_total_asset_bytes) | Value or type alias |
| [`MemoryAssetStore`](#memoryassetstore) | Class |
| [`Stored`](#stored) | Class |

## AssetMediaMetadata

Store inspected, non-content media properties safe for policy checks.

```python theme={null}
AssetMediaMetadata(
    width: int | None = None,
    height: int | None = None,
    duration_seconds: float | None = None,
    page_count: int | None = None,
    frame_count: int | None = None,
    channel_count: int | None = None,
    sample_rate_hz: int | None = None,
) -> None
```

Fields (`—` means no declared default):

| Field | Type | Default |
| - | - | - |
| `width` | `int \| None` | `None` |
| `height` | `int \| None` | `None` |
| `duration_seconds` | `float \| None` | `None` |
| `page_count` | `int \| None` | `None` |
| `frame_count` | `int \| None` | `None` |
| `channel_count` | `int \| None` | `None` |
| `sample_rate_hz` | `int \| None` | `None` |

> [accordion] Parameters and example
>
> | Parameter | Type | Default |
> | - | - | - |
> | `width` | `int \| None` | `None` |
> | `height` | `int \| None` | `None` |
> | `duration_seconds` | `float \| None` | `None` |
> | `page_count` | `int \| None` | `None` |
> | `frame_count` | `int \| None` | `None` |
> | `channel_count` | `int \| None` | `None` |
> | `sample_rate_hz` | `int \| None` | `None` |
>
> ```python theme={null}
> from harnest.assets import AssetMediaMetadata
>
> metadata = AssetMediaMetadata()
> ```

## AssetNotFoundError

Indicate that an asset is absent or inaccessible to the caller.

> [accordion] Example
>
> ```python theme={null}
> from harnest.assets import AssetNotFoundError
>
> try:
>     ...
> except AssetNotFoundError as error:
>     ...
> ```

## AssetQuotaError

Indicate that an asset or store capacity limit was exceeded.

> [accordion] Example
>
> ```python theme={null}
> from harnest.assets import AssetQuotaError
>
> try:
>     ...
> except AssetQuotaError as error:
>     ...
> ```

## AssetRecord

Describe a stored asset without exposing its binary content.

```python theme={null}
AssetRecord(
    asset_id: str,
    scope: AssetScope,
    media_type: str,
    size_bytes: int,
    created_at: datetime,
    expires_at: datetime | None = None,
    metadata: AssetMediaMetadata | None = None,
) -> None
```

Fields (`—` means no declared default):

| Field | Type | Default |
| - | - | - |
| `asset_id` | `str` | `—` |
| `scope` | `AssetScope` | `—` |
| `media_type` | `str` | `—` |
| `size_bytes` | `int` | `—` |
| `created_at` | `datetime` | `—` |
| `expires_at` | `datetime \| None` | `None` |
| `metadata` | `AssetMediaMetadata \| None` | `None` |

> [accordion] Parameters and example
>
> | Parameter | Type | Default |
> | - | - | - |
> | `asset_id` | `str` | Required |
> | `scope` | `AssetScope` | Required |
> | `media_type` | `str` | Required |
> | `size_bytes` | `int` | Required |
> | `created_at` | `datetime` | Required |
> | `expires_at` | `datetime \| None` | `None` |
> | `metadata` | `AssetMediaMetadata \| None` | `None` |
>
> ```python theme={null}
> from harnest.assets import AssetRecord
>
> record = AssetRecord(
>     asset_id=...,
>     scope=...,
>     media_type=...,
>     size_bytes=...,
>     created_at=...,
> )
> ```

## AssetScope

Bind an asset to one authenticated user and session.

```python theme={null}
AssetScope(user_id: str, session_id: str) -> None
```

Fields (`—` means no declared default):

| Field | Type | Default |
| - | - | - |
| `user_id` | `str` | `—` |
| `session_id` | `str` | `—` |

> [accordion] Parameters and example
>
> | Parameter | Type | Default |
> | - | - | - |
> | `user_id` | `str` | Required |
> | `session_id` | `str` | Required |
>
> ```python theme={null}
> from harnest.assets import AssetScope
>
> scope = AssetScope(user_id=..., session_id=...)
> ```

## AssetStorage

Persist and retrieve binary assets behind scoped opaque references.

```python theme={null}
AssetStorage(*args, **kwargs)
```

> [accordion] Example
>
> ```python theme={null}
> from harnest.assets import AssetStorage
>
> class MyAssetStorage(AssetStorage):
>     ...
> ```

### AssetStorage.start

```python theme={null}
async AssetStorage.start() -> None
```

Initialize resources required by the asset store.

> [accordion] Example
>
> ```python theme={null}
> from harnest.assets import AssetStorage
>
> storage: AssetStorage
> await storage.start()
> ```

### AssetStorage.save

```python theme={null}
async AssetStorage.save(
    *,
    scope: AssetScope,
    media_type: str,
    chunks: AsyncIterable[bytes],
    metadata: AssetMediaMetadata | None = None,
    retention_seconds: float | None = None,
    path: str | None = None,
) -> AssetRecord
```

Persist streamed bytes and return their scoped asset record.

> [accordion] Parameters and example
>
> | Parameter | Type | Default |
> | - | - | - |
> | `scope` | `AssetScope` | Required |
> | `media_type` | `str` | Required |
> | `chunks` | `AsyncIterable[bytes]` | Required |
> | `metadata` | `AssetMediaMetadata \| None` | `None` |
> | `retention_seconds` | `float \| None` | `None` |
> | `path` | `str \| None` | `None` |
>
> ```python theme={null}
> from harnest.assets import AssetStorage
>
> storage: AssetStorage
> record = await storage.save(scope=..., media_type=..., chunks=...)
> ```

### AssetStorage.stat

```python theme={null}
async AssetStorage.stat(*, scope: AssetScope, asset_id: str) -> AssetRecord | None
```

Return metadata for an owned asset, or `None` when unavailable.

> [accordion] Parameters and example
>
> | Parameter | Type | Default |
> | - | - | - |
> | `scope` | `AssetScope` | Required |
> | `asset_id` | `str` | Required |
>
> ```python theme={null}
> from harnest.assets import AssetStorage
>
> storage: AssetStorage
> record = await storage.stat(scope=..., asset_id=...)
> ```

### AssetStorage.open

```python theme={null}
AssetStorage.open(*, scope: AssetScope, asset_id: str) -> AsyncIterator[bytes]
```

Stream the bytes for an asset owned by the supplied scope.

> [accordion] Parameters and example
>
> | Parameter | Type | Default |
> | - | - | - |
> | `scope` | `AssetScope` | Required |
> | `asset_id` | `str` | Required |
>
> ```python theme={null}
> from harnest.assets import AssetStorage
>
> storage: AssetStorage
> result = storage.open(scope=..., asset_id=...)
> ```

### AssetStorage.delete

```python theme={null}
async AssetStorage.delete(*, scope: AssetScope, asset_id: str) -> bool
```

Delete an owned asset and report whether one was removed.

> [accordion] Parameters and example
>
> | Parameter | Type | Default |
> | - | - | - |
> | `scope` | `AssetScope` | Required |
> | `asset_id` | `str` | Required |
>
> ```python theme={null}
> from harnest.assets import AssetStorage
>
> storage: AssetStorage
> result = await storage.delete(scope=..., asset_id=...)
> ```

### AssetStorage.delete\_scope

```python theme={null}
async AssetStorage.delete_scope(*, scope: AssetScope) -> int
```

Delete every asset in a scope and return the removal count.

> [accordion] Parameters and example
>
> | Parameter | Type | Default |
> | - | - | - |
> | `scope` | `AssetScope` | Required |
>
> ```python theme={null}
> from harnest.assets import AssetStorage
>
> storage: AssetStorage
> result = await storage.delete_scope(scope=...)
> ```

### AssetStorage.close

```python theme={null}
async AssetStorage.close() -> None
```

Release resources owned by the asset store.

> [accordion] Example
>
> ```python theme={null}
> from harnest.assets import AssetStorage
>
> storage: AssetStorage
> await storage.close()
> ```

## AssetStore

Persist and retrieve binary assets behind scoped opaque references.

```python theme={null}
AssetStore(*args, **kwargs)
```

> [accordion] Example
>
> ```python theme={null}
> from harnest.assets import AssetStore
>
> class MyAssetStore(AssetStore):
>     ...
> ```

### AssetStore.start

```python theme={null}
async AssetStore.start() -> None
```

Initialize resources required by the asset store.

> [accordion] Example
>
> ```python theme={null}
> from harnest.assets import AssetStore
>
> store: AssetStore
> await store.start()
> ```

### AssetStore.save

```python theme={null}
async AssetStore.save(
    *,
    scope: AssetScope,
    media_type: str,
    chunks: AsyncIterable[bytes],
    metadata: AssetMediaMetadata | None = None,
    retention_seconds: float | None = None,
    path: str | None = None,
) -> AssetRecord
```

Persist streamed bytes and return their scoped asset record.

> [accordion] Parameters and example
>
> | Parameter | Type | Default |
> | - | - | - |
> | `scope` | `AssetScope` | Required |
> | `media_type` | `str` | Required |
> | `chunks` | `AsyncIterable[bytes]` | Required |
> | `metadata` | `AssetMediaMetadata \| None` | `None` |
> | `retention_seconds` | `float \| None` | `None` |
> | `path` | `str \| None` | `None` |
>
> ```python theme={null}
> from harnest.assets import AssetStore
>
> store: AssetStore
> record = await store.save(scope=..., media_type=..., chunks=...)
> ```

### AssetStore.stat

```python theme={null}
async AssetStore.stat(*, scope: AssetScope, asset_id: str) -> AssetRecord | None
```

Return metadata for an owned asset, or `None` when unavailable.

> [accordion] Parameters and example
>
> | Parameter | Type | Default |
> | - | - | - |
> | `scope` | `AssetScope` | Required |
> | `asset_id` | `str` | Required |
>
> ```python theme={null}
> from harnest.assets import AssetStore
>
> store: AssetStore
> record = await store.stat(scope=..., asset_id=...)
> ```

### AssetStore.open

```python theme={null}
AssetStore.open(*, scope: AssetScope, asset_id: str) -> AsyncIterator[bytes]
```

Stream the bytes for an asset owned by the supplied scope.

> [accordion] Parameters and example
>
> | Parameter | Type | Default |
> | - | - | - |
> | `scope` | `AssetScope` | Required |
> | `asset_id` | `str` | Required |
>
> ```python theme={null}
> from harnest.assets import AssetStore
>
> store: AssetStore
> result = store.open(scope=..., asset_id=...)
> ```

### AssetStore.delete

```python theme={null}
async AssetStore.delete(*, scope: AssetScope, asset_id: str) -> bool
```

Delete an owned asset and report whether one was removed.

> [accordion] Parameters and example
>
> | Parameter | Type | Default |
> | - | - | - |
> | `scope` | `AssetScope` | Required |
> | `asset_id` | `str` | Required |
>
> ```python theme={null}
> from harnest.assets import AssetStore
>
> store: AssetStore
> result = await store.delete(scope=..., asset_id=...)
> ```

### AssetStore.delete\_scope

```python theme={null}
async AssetStore.delete_scope(*, scope: AssetScope) -> int
```

Delete every asset in a scope and return the removal count.

> [accordion] Parameters and example
>
> | Parameter | Type | Default |
> | - | - | - |
> | `scope` | `AssetScope` | Required |
>
> ```python theme={null}
> from harnest.assets import AssetStore
>
> store: AssetStore
> result = await store.delete_scope(scope=...)
> ```

### AssetStore.close

```python theme={null}
async AssetStore.close() -> None
```

Release resources owned by the asset store.

> [accordion] Example
>
> ```python theme={null}
> from harnest.assets import AssetStore
>
> store: AssetStore
> await store.close()
> ```

## AssetStoreError

Base error for asset-store operations without sensitive context.

> [accordion] Example
>
> ```python theme={null}
> from harnest.assets import AssetStoreError
>
> try:
>     ...
> except AssetStoreError as error:
>     ...
> ```

## AssetURLStorage

Optional capability for model-call-time temporary URL generation.

```python theme={null}
AssetURLStorage(*args, **kwargs)
```

> [accordion] Example
>
> ```python theme={null}
> from harnest.assets import AssetURLStorage
>
> class MyAssetURLStorage(AssetURLStorage):
>     ...
> ```

### AssetURLStorage.signed\_url

```python theme={null}
async AssetURLStorage.signed_url(*, scope: AssetScope, asset_id: str, expires_in: float) -> str
```

Create a short-lived URL for an asset owned by the supplied scope.

> [accordion] Parameters and example
>
> | Parameter | Type | Default |
> | - | - | - |
> | `scope` | `AssetScope` | Required |
> | `asset_id` | `str` | Required |
> | `expires_in` | `float` | Required |
>
> ```python theme={null}
> from harnest.assets import AssetURLStorage
>
> storage: AssetURLStorage
> result = await storage.signed_url(scope=..., asset_id=..., expires_in=...)
> ```

## AssetValidationError

Indicate malformed asset input without reflecting the rejected value.

> [accordion] Example
>
> ```python theme={null}
> from harnest.assets import AssetValidationError
>
> try:
>     ...
> except AssetValidationError as error:
>     ...
> ```

## DEFAULT\_MAX\_ASSET\_BYTES

```python theme={null}
DEFAULT_MAX_ASSET_BYTES = 10485760
```

> [accordion] Example
>
> ```python theme={null}
> from harnest.assets import DEFAULT_MAX_ASSET_BYTES
> ```

## DEFAULT\_MAX\_TOTAL\_ASSET\_BYTES

```python theme={null}
DEFAULT_MAX_TOTAL_ASSET_BYTES = 104857600
```

> [accordion] Example
>
> ```python theme={null}
> from harnest.assets import DEFAULT_MAX_TOTAL_ASSET_BYTES
> ```

## MemoryAssetStore

Bounded, process-local asset storage intended for development and tests.

```python theme={null}
MemoryAssetStore(
    *,
    max_asset_bytes: int = 10485760,
    max_total_bytes: int = 104857600,
    read_chunk_bytes: int = 65536,
    default_retention_seconds: float | None = None,
    clock: Callable[[], datetime] | None = None,
    token_factory: Callable[[], str] | None = None,
) -> None
```

> [accordion] Parameters and example
>
> | Parameter | Type | Default |
> | - | - | - |
> | `max_asset_bytes` | `int` | `10485760` |
> | `max_total_bytes` | `int` | `104857600` |
> | `read_chunk_bytes` | `int` | `65536` |
> | `default_retention_seconds` | `float \| None` | `None` |
> | `clock` | `Callable[[], datetime] \| None` | `None` |
> | `token_factory` | `Callable[[], str] \| None` | `None` |
>
> ```python theme={null}
> from harnest.assets import MemoryAssetStore
>
> store = MemoryAssetStore()
> ```

### MemoryAssetStore.total\_bytes

Report committed bytes for development diagnostics.

> [accordion] Example
>
> ```python theme={null}
> from harnest.assets import MemoryAssetStore
>
> store: MemoryAssetStore
> value = store.total_bytes
> ```

### MemoryAssetStore.start

```python theme={null}
async MemoryAssetStore.start() -> None
```

Satisfy lifecycle ownership without allocating external resources.

> [accordion] Example
>
> ```python theme={null}
> from harnest.assets import MemoryAssetStore
>
> store: MemoryAssetStore
> await store.start()
> ```

### MemoryAssetStore.save

```python theme={null}
async MemoryAssetStore.save(
    *,
    scope: AssetScope,
    media_type: str,
    chunks: AsyncIterable[bytes],
    metadata: AssetMediaMetadata | None = None,
    retention_seconds: float | None = None,
    path: str | None = None,
) -> AssetRecord
```

Stream an asset into reserved capacity and publish it atomically.

> [accordion] Parameters and example
>
> | Parameter | Type | Default |
> | - | - | - |
> | `scope` | `AssetScope` | Required |
> | `media_type` | `str` | Required |
> | `chunks` | `AsyncIterable[bytes]` | Required |
> | `metadata` | `AssetMediaMetadata \| None` | `None` |
> | `retention_seconds` | `float \| None` | `None` |
> | `path` | `str \| None` | `None` |
>
> ```python theme={null}
> from harnest.assets import MemoryAssetStore
>
> store: MemoryAssetStore
> record = await store.save(scope=..., media_type=..., chunks=...)
> ```

### MemoryAssetStore.stat

```python theme={null}
async MemoryAssetStore.stat(*, scope: AssetScope, asset_id: str) -> AssetRecord | None
```

Return metadata only when the caller owns an unexpired asset.

> [accordion] Parameters and example
>
> | Parameter | Type | Default |
> | - | - | - |
> | `scope` | `AssetScope` | Required |
> | `asset_id` | `str` | Required |
>
> ```python theme={null}
> from harnest.assets import MemoryAssetStore
>
> store: MemoryAssetStore
> record = await store.stat(scope=..., asset_id=...)
> ```

### MemoryAssetStore.open

```python theme={null}
MemoryAssetStore.open(*, scope: AssetScope, asset_id: str) -> AsyncIterator[bytes]
```

Yield a stable snapshot while later deletion blocks new readers.

> [accordion] Parameters and example
>
> | Parameter | Type | Default |
> | - | - | - |
> | `scope` | `AssetScope` | Required |
> | `asset_id` | `str` | Required |
>
> ```python theme={null}
> from harnest.assets import MemoryAssetStore
>
> store: MemoryAssetStore
> async for item in store.open(scope=..., asset_id=...):
>     ...
> ```

### MemoryAssetStore.delete

```python theme={null}
async MemoryAssetStore.delete(*, scope: AssetScope, asset_id: str) -> bool
```

Delete an owned asset without revealing cross-principal existence.

> [accordion] Parameters and example
>
> | Parameter | Type | Default |
> | - | - | - |
> | `scope` | `AssetScope` | Required |
> | `asset_id` | `str` | Required |
>
> ```python theme={null}
> from harnest.assets import MemoryAssetStore
>
> store: MemoryAssetStore
> result = await store.delete(scope=..., asset_id=...)
> ```

### MemoryAssetStore.delete\_scope

```python theme={null}
async MemoryAssetStore.delete_scope(*, scope: AssetScope) -> int
```

Remove all assets owned by a deleted session without cross-scope reads.

> [accordion] Parameters and example
>
> | Parameter | Type | Default |
> | - | - | - |
> | `scope` | `AssetScope` | Required |
>
> ```python theme={null}
> from harnest.assets import MemoryAssetStore
>
> store: MemoryAssetStore
> result = await store.delete_scope(scope=...)
> ```

### MemoryAssetStore.cleanup\_expired

```python theme={null}
async MemoryAssetStore.cleanup_expired() -> int
```

Synchronously remove expired assets and return the removal count.

> [accordion] Example
>
> ```python theme={null}
> from harnest.assets import MemoryAssetStore
>
> store: MemoryAssetStore
> result = await store.cleanup_expired()
> ```

### MemoryAssetStore.clear

```python theme={null}
async MemoryAssetStore.clear() -> None
```

Deterministically discard all development-store content.

> [accordion] Example
>
> ```python theme={null}
> from harnest.assets import MemoryAssetStore
>
> store: MemoryAssetStore
> await store.clear()
> ```

### MemoryAssetStore.close

```python theme={null}
async MemoryAssetStore.close() -> None
```

Discard process-local bytes when the owning application stops.

> [accordion] Example
>
> ```python theme={null}
> from harnest.assets import MemoryAssetStore
>
> store: MemoryAssetStore
> await store.close()
> ```

## Stored

Persist a media field using one explicitly named asset storage.

`expires_in` controls the model-facing URL lifetime. `retention`
controls stored-byte lifetime; the two durations are deliberately
independent.

```python theme={null}
Stored(
    store: str = 'default',
    path: str | None = None,
    expires_in: float = 60,
    retention: timedelta | None = None,
) -> None
```

Fields (`—` means no declared default):

| Field | Type | Default |
| - | - | - |
| `store` | `str` | `'default'` |
| `path` | `str \| None` | `None` |
| `expires_in` | `float` | `60` |
| `retention` | `timedelta \| None` | `None` |

> [accordion] Parameters and example
>
> | Parameter | Type | Default |
> | - | - | - |
> | `store` | `str` | `'default'` |
> | `path` | `str \| None` | `None` |
> | `expires_in` | `float` | `60` |
> | `retention` | `timedelta \| None` | `None` |
>
> ```python theme={null}
> from harnest.assets import Stored
>
> stored = Stored()
> ```

### Stored.retention\_seconds

Return the store contract's numeric retention representation.

> [accordion] Example
>
> ```python theme={null}
> from harnest.assets import Stored
>
> stored: Stored
> value = stored.retention_seconds
> ```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.