Group Operations¶
Operations for managing groups (movies/collections).
Bases: StashClientProtocol
Mixin for group-related client methods.
Functions¶
find_group
async
¶
find_group(group_id: str) -> Group | None
Find a group by ID.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
group_id
|
str
|
Group ID to search for |
required |
Returns:
| Type | Description |
|---|---|
Group | None
|
Group object if found, None otherwise |
Examples:
group = await client.find_group("123")
if group:
print(f"Found group: {group.name}")
print(f"Duration: {group.duration} seconds")
print(f"Director: {group.director}")
Access group relationships:
group = await client.find_group("123")
if group:
# Get scene titles
scene_titles = [s.title for s in group.scenes]
# Get studio name
studio_name = group.studio.name if group.studio else None
# Get tag names
tags = [t.name for t in group.tags]
# Get sub-groups
sub_groups = [sg.group.name for sg in group.sub_groups]
find_groups
async
¶
find_groups(
filter_: dict[str, Any] | None = None,
group_filter: dict[str, Any] | None = None,
ids: list[str] | None = None,
q: str | None = None,
) -> FindGroupsResultType
Find groups matching the given filters.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filter_
|
dict[str, Any] | None
|
Optional general filter parameters: - q: str (search query) - direction: SortDirectionEnum (ASC/DESC) - page: int - per_page: int - sort: str (field to sort by) |
None
|
group_filter
|
dict[str, Any] | None
|
Optional group-specific filter: - name: StringCriterionInput - director: StringCriterionInput - synopsis: StringCriterionInput - duration: IntCriterionInput - rating100: IntCriterionInput - date: DateCriterionInput - url: StringCriterionInput - is_missing: str (what data is missing) - studios: HierarchicalMultiCriterionInput - tags: HierarchicalMultiCriterionInput |
None
|
ids
|
list[str] | None
|
Optional list of group IDs to filter by |
None
|
q
|
str | None
|
Optional search query (alternative to filter_["q"]) |
None
|
Returns:
| Type | Description |
|---|---|
FindGroupsResultType
|
FindGroupsResultType containing: - count: Total number of matching groups - groups: List of Group objects |
Examples:
Find all groups:
result = await client.find_groups()
print(f"Found {result.count} groups")
for group in result.groups:
print(f"- {group.name}")
Search by name:
result = await client.find_groups(q="Action")
print(f"Found {result.count} groups matching 'Action'")
Find groups by filter:
result = await client.find_groups(
group_filter={
"name": {
"value": "Series",
"modifier": "INCLUDES"
}
}
)
Find groups with specific tags:
result = await client.find_groups(
group_filter={
"tags": {
"value": ["tag1", "tag2"],
"modifier": "INCLUDES_ALL"
}
}
)
Find groups with high rating and sort by name:
result = await client.find_groups(
filter_={
"direction": "ASC",
"sort": "name",
},
group_filter={
"rating100": {
"value": 80,
"modifier": "GREATER_THAN"
}
}
)
Paginate results:
Find specific groups by IDs:
create_group
async
¶
Create a new group in Stash.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
group
|
Group
|
Group object with the data to create. Required fields: - name: Group name |
required |
Returns:
| Type | Description |
|---|---|
Group
|
Created Group object with ID and any server-generated fields |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the group data is invalid |
TransportError
|
If the request fails |
Examples:
Create a basic group:
group = Group(name="Test Series")
created = await client.create_group(group)
print(f"Created group with ID: {created.id}")
Create group with metadata:
group = Group(
name="Action Movie Series",
director="John Director",
synopsis="An action-packed series",
duration=7200,
date="2020-01-01",
rating100=85,
)
created = await client.create_group(group)
Create group with relationships:
from stash_graphql_client.types import Tag, Studio
# Fetch tags and studio
tag1 = await client.find_tag("tag1_id")
tag2 = await client.find_tag("tag2_id")
studio = await client.find_studio("studio_id")
group = Group(
name="Tagged Group",
tags=[tag1, tag2],
studio=studio,
)
created = await client.create_group(group)
update_group
async
¶
Update an existing group in Stash.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
group
|
Group
|
Group object with updated data. Must include ID field. |
required |
Returns:
| Type | Description |
|---|---|
Group
|
Updated Group object |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the group ID is missing or data is invalid |
TransportError
|
If the request fails |
Examples:
Update group name and director:
group = await client.find_group("123")
group.name = "Updated Name"
group.director = "New Director"
updated = await client.update_group(group)
Update group rating:
group = await client.find_group("123")
group.rating100 = 90
updated = await client.update_group(group)
Update group tags:
group_destroy
async
¶
Delete a group from Stash.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_data
|
GroupDestroyInput | dict[str, Any]
|
GroupDestroyInput or dict with: - id: Group ID to delete |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if deletion was successful |
Raises:
| Type | Description |
|---|---|
TransportError
|
If the request fails |
Examples:
Delete by ID using dict:
Delete using GroupDestroyInput:
groups_destroy
async
¶
Delete multiple groups from Stash.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ids
|
list[str]
|
List of group IDs to delete |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if deletion was successful |
Raises:
| Type | Description |
|---|---|
TransportError
|
If the request fails |
Examples:
bulk_group_update
async
¶
bulk_group_update(
input_data: BulkGroupUpdateInput | dict[str, Any],
) -> list[Group]
Bulk update multiple groups.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_data
|
BulkGroupUpdateInput | dict[str, Any]
|
BulkGroupUpdateInput or dict with: - ids: List of group IDs to update - rating100: Optional rating (1-100) - studio_id: Optional studio ID - director: Optional director name - urls: Optional list of URLs - tag_ids: Optional list of tag IDs - containing_groups: Optional groups that contain these groups - sub_groups: Optional sub-groups |
required |
Returns:
| Type | Description |
|---|---|
list[Group]
|
List of updated Group objects |
Raises:
| Type | Description |
|---|---|
TransportError
|
If the request fails |
Examples:
Update rating for multiple groups:
result = await client.bulk_group_update({
"ids": ["1", "2", "3"],
"rating100": 85
})
print(f"Updated {len(result)} groups")
Add tags to multiple groups:
from stash_graphql_client.types import BulkGroupUpdateInput
input_data = BulkGroupUpdateInput(
ids=["1", "2", "3"],
tag_ids=["tag1", "tag2"]
)
result = await client.bulk_group_update(input_data)
Set studio for multiple groups:
add_group_sub_groups
async
¶
Add sub-groups to a group.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_data
|
GroupSubGroupAddInput | dict[str, Any]
|
GroupSubGroupAddInput or dict with: - containing_group_id: ID of the parent group - sub_groups: List of GroupDescriptionInput dicts with group_id and optional description - insert_index: Optional index at which to insert (default: append to end) |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if successful |
Raises:
| Type | Description |
|---|---|
TransportError
|
If the request fails |
Examples:
Add sub-groups to end:
result = await client.add_group_sub_groups({
"containing_group_id": "parent_123",
"sub_groups": [
{"group_id": "child_456"},
{"group_id": "child_789", "description": "Episode 1"}
]
})
Insert sub-groups at specific index:
from stash_graphql_client.types import (
GroupSubGroupAddInput,
GroupDescriptionInput
)
input_data = GroupSubGroupAddInput(
containing_group_id="parent_123",
sub_groups=[
GroupDescriptionInput(group_id="child_456", description="Episode 2")
],
insert_index=1
)
result = await client.add_group_sub_groups(input_data)
remove_group_sub_groups
async
¶
Remove sub-groups from a group.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_data
|
GroupSubGroupRemoveInput | dict[str, Any]
|
GroupSubGroupRemoveInput or dict with: - containing_group_id: ID of the parent group - sub_group_ids: List of sub-group IDs to remove |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if successful |
Raises:
| Type | Description |
|---|---|
TransportError
|
If the request fails |
Examples:
Remove sub-groups:
result = await client.remove_group_sub_groups({
"containing_group_id": "parent_123",
"sub_group_ids": ["child_456", "child_789"]
})
Using typed input:
reorder_sub_groups
async
¶
Reorder sub-groups within a group.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_data
|
ReorderSubGroupsInput | dict[str, Any]
|
ReorderSubGroupsInput or dict with: - group_id: ID of the parent group - sub_group_ids: List of sub-group IDs to reorder (must be subset of existing) - insert_at_id: Sub-group ID at which to insert the reordered groups - insert_after: If True, insert after insert_at_id; if False, insert before |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if successful |
Raises:
| Type | Description |
|---|---|
TransportError
|
If the request fails |
Examples:
Reorder sub-groups:
result = await client.reorder_sub_groups({
"group_id": "parent_123",
"sub_group_ids": ["child_2", "child_3"],
"insert_at_id": "child_1",
"insert_after": True
})
Using typed input: