cached_transport
cached_transport ¶
HTTP response caching with smart URL-based invalidation.
This module implements browser-style HTTP caching for Domo API requests with: - Automatic cache invalidation on mutations (POST/PUT/DELETE/PATCH) - Smart URL pattern matching to determine what to invalidate - Collection-level caching for paginated results (looper) - Configurable TTLs per endpoint pattern - Optional custom invalidation rules
Example
from crew_dcs.auth import DomoTokenAuth
Enable caching (default: SMART invalidation strategy)¶
auth = DomoTokenAuth( ... domo_instance="mycompany", ... domo_access_token="token", ... use_cache=True, ... )
Automatic caching and invalidation¶
user = await get_user(id="123") # Cached await update_user(id="123") # Auto-invalidates cache user = await get_user(id="123") # Fresh data (cache miss)
CacheEntry
dataclass
¶
CacheEntry(
response: Response,
cached_at: datetime,
ttl: int,
url: str,
)
Cache entry for a single HTTP response.
Attributes:
| Name | Type | Description |
|---|---|---|
response |
Response
|
The cached httpx.Response object |
cached_at |
datetime
|
Timestamp when response was cached |
ttl |
int
|
Time-to-live in seconds |
url |
str
|
Original request URL |
is_expired ¶
is_expired() -> bool
Check if cache entry has expired.
Source code in src/crew_dcs/client/cached_transport.py
70 71 72 73 | |
CachedAsyncHTTPTransport ¶
CachedAsyncHTTPTransport(
*args,
cache_size: int = 1000,
default_ttl: int = DEFAULT_TTL,
invalidation_strategy: InvalidationStrategy = SMART,
custom_invalidation_rules: (
dict[str, list[str]] | None
) = None,
collection_cache_size: int = 100,
collection_cache_max_records: int = 10000,
ttl_config: dict[str, int] | None = None,
collection_ttl_config: dict[str, int] | None = None,
**kwargs
)
Bases: AsyncHTTPTransport
HTTP transport with response caching and smart invalidation.
This transport layer adds caching to httpx AsyncHTTPTransport with: - Automatic cache invalidation on mutations - Smart URL pattern matching - Separate collection cache for paginated results - Configurable TTLs per endpoint
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cache_size
|
int
|
Maximum number of cached responses |
1000
|
default_ttl
|
int
|
Default TTL in seconds for cached responses |
DEFAULT_TTL
|
invalidation_strategy
|
InvalidationStrategy
|
Strategy for cache invalidation |
SMART
|
custom_invalidation_rules
|
dict[str, list[str]] | None
|
Optional custom rules for CUSTOM strategy |
None
|
collection_cache_size
|
int
|
Maximum number of cached collections |
100
|
collection_cache_max_records
|
int
|
Maximum records per collection cache entry |
10000
|
ttl_config
|
dict[str, int] | None
|
Optional TTL configuration by URL pattern |
None
|
collection_ttl_config
|
dict[str, int] | None
|
Optional collection TTL configuration |
None
|
**kwargs
|
Additional arguments passed to AsyncHTTPTransport |
{}
|
Example
transport = CachedAsyncHTTPTransport( ... cache_size=1000, ... default_ttl=300, ... invalidation_strategy=InvalidationStrategy.SMART, ... ) client = httpx.AsyncClient(transport=transport)
Source code in src/crew_dcs/client/cached_transport.py
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 | |
clear_cache ¶
clear_cache()
Clear all caches.
Source code in src/crew_dcs/client/cached_transport.py
684 685 686 687 688 689 690 691 692 693 694 695 | |
get_collection_cache
async
¶
get_collection_cache(
base_url: str, params: dict | None, auth_instance: str
) -> CollectionCacheEntry | None
Retrieve cached collection if not expired.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base_url
|
str
|
Base URL |
required |
params
|
dict | None
|
Query parameters |
required |
auth_instance
|
str
|
Authentication instance |
required |
Returns:
| Type | Description |
|---|---|
CollectionCacheEntry | None
|
Cached collection or None |
Source code in src/crew_dcs/client/cached_transport.py
603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 | |
get_collection_cache_key ¶
get_collection_cache_key(
base_url: str, params: dict | None, auth_instance: str
) -> str
Generate collection cache key (ignoring pagination params).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base_url
|
str
|
Base URL |
required |
params
|
dict | None
|
Query parameters |
required |
auth_instance
|
str
|
Authentication instance |
required |
Returns:
| Type | Description |
|---|---|
str
|
Collection cache key |
Source code in src/crew_dcs/client/cached_transport.py
572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 | |
get_stats ¶
get_stats() -> dict[str, Any]
Get cache statistics.
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
Dictionary with cache statistics |
Source code in src/crew_dcs/client/cached_transport.py
697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 | |
handle_async_request
async
¶
handle_async_request(request: Request) -> Response
Handle HTTP request with caching.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
Request
|
The HTTP request to handle |
required |
Returns:
| Type | Description |
|---|---|
Response
|
HTTP response (from cache or server) |
Source code in src/crew_dcs/client/cached_transport.py
321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 | |
store_collection_cache
async
¶
store_collection_cache(
base_url: str,
params: dict | None,
auth_instance: str,
data: list,
request_count: int,
ttl: int | None = None,
)
Store collection in cache.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base_url
|
str
|
Base URL |
required |
params
|
dict | None
|
Query parameters |
required |
auth_instance
|
str
|
Authentication instance |
required |
data
|
list
|
Collection data |
required |
request_count
|
int
|
Number of requests made to fetch collection |
required |
ttl
|
int | None
|
Optional TTL override |
None
|
Source code in src/crew_dcs/client/cached_transport.py
631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 | |
CollectionCacheEntry
dataclass
¶
CollectionCacheEntry(
data: list,
cached_at: datetime,
ttl: int,
total_records: int,
request_count: int,
)
Cache entry for complete paginated collections.
Attributes:
| Name | Type | Description |
|---|---|---|
data |
list
|
Complete aggregated result from looper |
cached_at |
datetime
|
Timestamp when collection was cached |
ttl |
int
|
Time-to-live in seconds |
total_records |
int
|
Number of records in collection |
request_count |
int
|
Number of HTTP requests made to fetch collection |
is_expired ¶
is_expired() -> bool
Check if cache entry has expired.
Source code in src/crew_dcs/client/cached_transport.py
94 95 96 97 | |
InvalidationStrategy ¶
Bases: Enum
Cache invalidation strategies.
Attributes:
| Name | Type | Description |
|---|---|---|
EXACT |
Only invalidate exact URL that was mutated |
|
SMART |
Invalidate exact URL + parent collections (DEFAULT) |
|
AGGRESSIVE |
Invalidate exact + parents + children |
|
CUSTOM |
Use custom invalidation rules only |
SmartInvalidator ¶
SmartInvalidator(
strategy: InvalidationStrategy = SMART,
custom_rules: dict[str, list[str]] | None = None,
)
Smart URL-based cache invalidation without manual rules.
Automatically determines what cache entries to invalidate based on the URL of a mutation request, using intelligent pattern matching.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
strategy
|
InvalidationStrategy
|
Invalidation strategy to use |
SMART
|
custom_rules
|
dict[str, list[str]] | None
|
Optional custom invalidation rules (only used with CUSTOM strategy) |
None
|
Example
invalidator = SmartInvalidator(strategy=InvalidationStrategy.SMART)
Mutation: PUT /api/content/v1/users/123¶
patterns = invalidator.get_invalidation_patterns( ... "https://domo.com/api/content/v1/users/123" ... )
Returns: ['/api/content/v1/users/123', '/api/content/v1/users', ...]¶
Source code in src/crew_dcs/client/cached_transport.py
120 121 122 123 124 125 126 | |
get_invalidation_patterns ¶
get_invalidation_patterns(mutation_url: str) -> set[str]
Generate cache invalidation patterns for a mutation URL.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mutation_url
|
str
|
Full URL of the mutation request |
required |
Returns:
| Type | Description |
|---|---|
set[str]
|
Set of regex patterns that should be invalidated |
Source code in src/crew_dcs/client/cached_transport.py
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | |