kumiho.bundle

Bundle module for Kumiho asset management.

This module provides the Bundle class, which represents a special type of item that aggregates other items. Bundles are used to group related items together and maintain an audit trail of membership changes.

Bundles are unique in that:
  • The bundle kind is reserved and cannot be created manually.

  • Use Project.create_bundle() or Space.create_bundle().

  • Each membership change (add/remove) creates a new revision for audit trail.

  • Revision metadata is immutable, providing complete change history.

Example:

import kumiho

# Create a bundle from a project or space
project = kumiho.get_project("my-project")
bundle = project.create_bundle("asset-bundle")

# Add items to the bundle
hero_model = kumiho.get_item("kref://my-project/models/hero.model")
bundle.add_member(hero_model)

# Get all members
members = bundle.get_members()
for member in members:
    print(f"Item: {member.item_kref}")

# View history of changes (immutable audit trail)
for entry in bundle.get_history():
    print(f"v{entry.revision_number}: {entry.action} {entry.member_item_kref}")

See also

kumiho.bundle.RESERVED_KINDS = frozenset({'bundle'})

Item kinds that are reserved and cannot be created via create_item.

Currently includes:
  • bundle: Use Project.create_bundle() or Space.create_bundle() instead.

Type:

frozenset

exception kumiho.bundle.ReservedKindError[source]

Bases: Exception

Raised when attempting to create an item with a reserved kind.

This error is raised when calling Space.create_item() or the low-level client create_item with a reserved kind such as bundle.

Example:

import kumiho

space = project.get_space("assets")

# This will raise ReservedKindError
try:
    space.create_item("my-bundle", "bundle")
except kumiho.ReservedKindError as e:
    print(f"Error: {e}")
    # Use create_bundle instead
    bundle = space.create_bundle("my-bundle")
class kumiho.bundle.BundleMember[source]

Bases: object

An item that is a member of a bundle.

Represents the membership relationship between an item and a bundle, including metadata about when and by whom the item was added.

item_kref

The kref of the member item.

Type:

Kref

added_at

ISO timestamp when the item was added.

Type:

str

added_by

UUID of the user who added the item.

Type:

str

added_by_username

Display name of the user who added the item.

Type:

str

added_in_revision

The bundle revision when this item was added.

Type:

int

Example:

members = bundle.get_members()
for member in members:
    print(f"Item: {member.item_kref}")
    print(f"Added by: {member.added_by_username}")
    print(f"Added at: {member.added_at}")
    print(f"In revision: {member.added_in_revision}")
item_kref: Kref

The kref of the member item.

Type:

Kref

added_at: str

ISO timestamp when the item was added to the bundle.

Type:

str

added_by: str

UUID of the user who added the item.

Type:

str

added_by_username: str

Display name of the user who added the item.

Type:

str

added_in_revision: int

The bundle revision number when this item was added.

Type:

int

__init__(item_kref, added_at, added_by, added_by_username, added_in_revision)
Parameters:
  • item_kref (Kref)

  • added_at (str)

  • added_by (str)

  • added_by_username (str)

  • added_in_revision (int)

Return type:

None

class kumiho.bundle.BundleRevisionHistory[source]

Bases: object

A historical change to a bundle’s membership.

Each entry captures a single add or remove operation, providing an immutable audit trail of all membership changes. The metadata is immutable once created, ensuring complete traceability.

revision_number

The bundle revision number for this change.

Type:

int

action

The action performed: "CREATED", "ADDED", or "REMOVED".

Type:

str

member_item_kref

The item that was added/removed. None for the initial "CREATED" action.

Type:

Optional[Kref]

author

UUID of the user who made the change.

Type:

str

username

Display name of the user who made the change.

Type:

str

created_at

ISO timestamp of the change.

Type:

str

metadata

Immutable metadata captured at the time of change.

Type:

Dict[str, str]

Example:

history = bundle.get_history()
for entry in history:
    print(f"Revision {entry.revision_number}: {entry.action}")
    if entry.member_item_kref:
        print(f"  Item: {entry.member_item_kref}")
    print(f"  By: {entry.username} at {entry.created_at}")
revision_number: int

The bundle revision number for this change.

Type:

int

action: str

The action performed: "CREATED", "ADDED", or "REMOVED".

Type:

str

member_item_kref: Optional[Kref]

The item that was added/removed (None for CREATED).

Type:

Optional[Kref]

author: str

UUID of the user who made the change.

Type:

str

__init__(revision_number, action, member_item_kref, author, username, created_at, metadata)
Parameters:
Return type:

None

username: str

Display name of the user who made the change.

Type:

str

created_at: str

ISO timestamp of when the change was made.

Type:

str

metadata: Dict[str, str]

Immutable metadata captured at the time of the change.

Type:

Dict[str, str]

class kumiho.bundle.Bundle[source]

Bases: Item

A special item type that aggregates other items.

Bundles provide a way to group related items together. Unlike regular items, bundles cannot be created using the standard create_item method—the bundle kind is reserved.

Use Project.create_bundle() or Space.create_bundle() to create bundles.

Key features:
  • Aggregates items (not revisions) via COLLECTS relationships.

  • Each membership change creates a new revision for audit trail.

  • Revision metadata is immutable, providing complete history.

  • Cannot contain itself (self-reference protection).

kref

The unique identifier for this bundle.

Type:

Kref

name

The combined name (e.g., “my-bundle.bundle”).

Type:

str

item_name

The bundle name (e.g., “my-bundle”).

Type:

str

kind

Always “bundle”.

Type:

str

metadata

Custom metadata key-value pairs.

Type:

Dict[str, str]

created_at

ISO timestamp when the bundle was created.

Type:

str

author

The user ID who created the bundle.

Type:

str

username

Display name of the creator.

Type:

str

deprecated

Whether the bundle is deprecated.

Type:

bool

Example:

import kumiho

# Create a bundle from a project
project = kumiho.get_project("film-2024")
bundle = project.create_bundle("release-v1")

# Add items
model = kumiho.get_item("kref://film-2024/models/hero.model")
texture = kumiho.get_item("kref://film-2024/textures/hero.texture")
bundle.add_member(model)
bundle.add_member(texture)

# List current members
for member in bundle.get_members():
    print(f"{member.item_kref} added by {member.added_by_username}")

# Remove a member
bundle.remove_member(model)

# View complete audit history
for entry in bundle.get_history():
    print(f"v{entry.revision_number}: {entry.action}")

See also

Project.create_bundle(): Create a bundle in a project. Space.create_bundle(): Create a bundle in a space. BundleMember: Data class for member information. BundleRevisionHistory: Data class for audit entries.

__init__(pb, client)[source]

Initialize a Bundle from a protobuf response.

Parameters:
  • pb (ItemResponse) – The ItemResponse protobuf message.

  • client (_Client) – The client instance for making subsequent calls.

Raises:

ValueError – If the kind is not ‘bundle’.

Return type:

None

add_member(member, metadata=None)[source]

Add an item to this bundle.

Creates a new revision of the bundle to track the change. The revision metadata will include the action ("ADDED") and the member item kref for audit purposes.

Parameters:
  • member (Item) – The item to add to the bundle.

  • metadata (Optional[Dict[str, str]]) – Optional additional metadata to store in the revision. This metadata becomes part of the immutable audit trail.

Returns:

A tuple containing:
  • success: Whether the operation succeeded.

  • message: A status message.

  • new_revision: The new bundle revision created for this change.

Return type:

Tuple[bool, str, Optional[Revision]]

Raises:
  • ValueError – If trying to add the bundle to itself.

  • grpc.RpcError – If the member is already in the bundle (status code ALREADY_EXISTS).

Example:

hero_model = kumiho.get_item("kref://project/models/hero.model")

# Add with optional metadata
success, msg, revision = bundle.add_member(
    hero_model,
    metadata={"reason": "character bundle", "approved_by": "director"}
)

if success:
    print(f"Added in revision {revision.number}")
remove_member(member, metadata=None)[source]

Remove an item from this bundle.

Creates a new revision of the bundle to track the change. The revision metadata will include the action ("REMOVED") and the member item kref for audit purposes.

Parameters:
  • member (Item) – The item to remove from the bundle.

  • metadata (Optional[Dict[str, str]]) – Optional additional metadata to store in the revision. This metadata becomes part of the immutable audit trail.

Returns:

A tuple containing:
  • success: Whether the operation succeeded.

  • message: A status message.

  • new_revision: The new bundle revision created for this change.

Return type:

Tuple[bool, str, Optional[Revision]]

Raises:

grpc.RpcError – If the member is not in the bundle (status code NOT_FOUND).

Example:

# Remove an item from the bundle
success, msg, revision = bundle.remove_member(hero_model)

if success:
    print(f"Removed in revision {revision.number}")
get_members(revision_number=None)[source]

Get all items that are members of this bundle.

Returns information about each member item, including when it was added and by whom.

Parameters:

revision_number (Optional[int]) – Optional specific revision to query. If not provided, returns current membership.

Returns:

List of member information objects.

Return type:

List[BundleMember]

Example:

# Get current members
members = bundle.get_members()
for member in members:
    print(f"{member.item_kref}")
    print(f"  Added by: {member.added_by_username}")
    print(f"  In revision: {member.added_in_revision}")

# Get empty list if no members
if not members:
    print("Bundle is empty")
get_history()[source]

Get the full history of membership changes.

Returns all revisions with their associated actions, providing a complete and immutable audit trail of all adds and removes.

The history is ordered by revision number, starting with the initial "CREATED" action.

Returns:

List of history entries, ordered

by revision number (oldest first).

Return type:

List[BundleRevisionHistory]

Example:

history = bundle.get_history()

for entry in history:
    print(f"Revision {entry.revision_number}:")
    print(f"  Action: {entry.action}")
    print(f"  By: {entry.username}")
    print(f"  At: {entry.created_at}")
    if entry.member_item_kref:
        print(f"  Item: {entry.member_item_kref}")
__repr__()[source]

Return a string representation of the Bundle.

Return type:

str