Skip to main content
This guide shows common patterns for working with stash-graphql-client. These patterns are designed to be clear for both human developers and LLM agents reading the documentation.

Pattern 1: Basic CRUD Operations

Creating Entities

Key points:
  • New entities get automatic UUID4 IDs (32-char hex strings)
  • .save(client) executes the appropriate GraphQL mutation
  • Server-assigned ID replaces the UUID4 after save
  • Use entity.is_new() to check if entity has been saved

Reading/Querying Entities

Key points:
  • find_X(id) methods return single entity or None
  • find_Xs(filter) methods return result objects with count and items
  • Result objects have entity-specific list names (e.g., scenes, performers)
  • Pagination handled via page and per_page parameters

Updating Entities

Key points:
  • Only modified fields are sent in update mutations
  • Use UNSET to explicitly not modify a field
  • get_changed_fields() shows what will be sent
  • Entity .save() automatically chooses create vs update mutation

Deleting Entities

Key points:
  • .delete(client) available on entity types with __destroy_input_type__
  • Client also has X_destroy({"id": ...}) methods
  • Deletion is permanent - no undo

Pattern 2: Working with Relationships

Setting Single Relationships (Many-to-One)

Key points:
  • Set relationship by assigning entity object
  • Bidirectional sync happens automatically
  • Save the entity to persist the relationship
  • Inverse field only synced if it was loaded

Setting Many-to-Many Relationships

Key points:
  • Many-to-many relationships are lists
  • Can assign entire list or use add_X() / remove_X() helpers
  • Helper methods automatically sync inverse relationships
  • Changes persist only after .save(client)
Key points:
  • Always check for UNSET before accessing relationships using is_set()
  • Related entities automatically cached in identity map
  • Same entity ID = same object reference everywhere

Pattern 3: Using the Entity Store

Basic Store Operations

Key points:
  • get() fetches from server if not in cache
  • get_cached() only checks cache, never queries
  • Store methods wrap client methods with caching
  • TTL optional (None = never expire)

Django-Style Filtering

Supported modifiers:
  • __exact - Exact match
  • __contains - String contains
  • __regex - Regular expression match
  • __gte, __gt - Greater than (or equal)
  • __lte, __lt - Less than (or equal)
  • __between - Range (tuple of min/max)
  • __null - Null check (boolean)
  • __in - List membership

Field-Aware Population

Key points:
  • _received_fields tracks which fields were loaded
  • missing_fields() returns set of fields not yet loaded
  • populate() fetches only missing fields
  • Use force_refetch=True to invalidate cache and reload

Lazy Iteration for Large Result Sets

Key points:
  • find_iter() yields items one at a time
  • Pages fetched on demand (not all upfront)
  • Can break early to save network requests
  • query_batch controls page size (default 40)

Pattern 4: Advanced Queries

Using Raw GraphQL Filters

Key points:
  • Raw filters give full control over GraphQL query
  • Use when Django-style syntax is insufficient
  • Filter structure matches Stash’s GraphQL schema
  • See API reference for available modifiers

Pagination

Key points:
  • page is 1-indexed (first page = 1)
  • per_page defaults to 40 (max typically 1000)
  • Check len(result.items) < per_page to detect last page
  • Result object includes .count for total items

Pattern 5: Bulk Operations

Concurrent Fetches

Concurrent Updates

Key points:
  • Use asyncio.gather() for concurrent operations
  • Be mindful of rate limits (don’t send 1000 concurrent requests)
  • Consider batching (process 10-50 at a time)

Batch Processing with Progress Tracking

Pattern 6: Job Management

Starting and Monitoring Jobs

Polling Job Status

Using Subscriptions for Real-Time Updates

Key points:
  • metadata_scan(), metadata_generate() return job IDs
  • wait_for_job() blocks until completion (with timeout)
  • Manual polling gives more control over progress updates
  • Subscriptions provide real-time updates via WebSocket

Pattern 7: ID Mapping and Utilities

Converting Names to IDs (with Auto-Create)

Available mapping methods:
  • map_performer_ids(items, create=False)
  • map_studio_ids(items, create=False)
  • map_tag_ids(items, create=False)
Key points:
  • Pass list of strings (names) or entity objects
  • create=True creates missing entities
  • Returns list of IDs in same order as input
  • Mixed types supported (strings and objects)

Studio Hierarchy Navigation

Pattern 8: Error Handling

Handling GraphQL Errors

Handling Validation Errors

Handling Connection Errors

Next Steps