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
bundlekind is reserved and cannot be created manually.Use
Project.create_bundle()orSpace.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
BundleMember: Data class for bundle members.BundleRevisionHistory: Data class for audit trail entries.ReservedKindError: Error for reserved kind violations.
- kumiho.bundle.RESERVED_KINDS = frozenset({'bundle'})
Item kinds that are reserved and cannot be created via create_item.
- Currently includes:
bundle: UseProject.create_bundle()orSpace.create_bundle()instead.
- Type:
- exception kumiho.bundle.ReservedKindError[source]
Bases:
ExceptionRaised when attempting to create an item with a reserved kind.
This error is raised when calling
Space.create_item()or the low-level clientcreate_itemwith a reserved kind such asbundle.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:
objectAn 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:
- added_at
ISO timestamp when the item was added.
- Type:
- added_by
UUID of the user who added the item.
- Type:
- added_by_username
Display name of the user who added the item.
- Type:
- added_in_revision
The bundle revision when this item was added.
- Type:
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}")
- class kumiho.bundle.BundleRevisionHistory[source]
Bases:
objectA 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:
- action
The action performed:
"CREATED","ADDED", or"REMOVED".- Type:
- 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:
- username
Display name of the user who made the change.
- Type:
- created_at
ISO timestamp of the change.
- Type:
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}")
-
member_item_kref:
Optional[Kref] The item that was added/removed (None for CREATED).
- Type:
Optional[Kref]
- __init__(revision_number, action, member_item_kref, author, username, created_at, metadata)
- class kumiho.bundle.Bundle[source]
Bases:
ItemA 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_itemmethod—thebundlekind is reserved.Use
Project.create_bundle()orSpace.create_bundle()to create bundles.- Key features:
Aggregates items (not revisions) via
COLLECTSrelationships.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:
- name
The combined name (e.g., “my-bundle.bundle”).
- Type:
- item_name
The bundle name (e.g., “my-bundle”).
- Type:
- kind
Always “bundle”.
- Type:
- created_at
ISO timestamp when the bundle was created.
- Type:
- author
The user ID who created the bundle.
- Type:
- username
Display name of the creator.
- Type:
- deprecated
Whether the bundle is deprecated.
- Type:
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:
- 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:
- 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:
- 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:
- 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}")