amazon-ads-mcp 0.2.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- amazon_ads_mcp/__init__.py +11 -0
- amazon_ads_mcp/auth/__init__.py +33 -0
- amazon_ads_mcp/auth/base.py +211 -0
- amazon_ads_mcp/auth/hooks.py +172 -0
- amazon_ads_mcp/auth/manager.py +791 -0
- amazon_ads_mcp/auth/oauth_state_store.py +277 -0
- amazon_ads_mcp/auth/providers/__init__.py +14 -0
- amazon_ads_mcp/auth/providers/direct.py +393 -0
- amazon_ads_mcp/auth/providers/example_auth0.py.example +216 -0
- amazon_ads_mcp/auth/providers/openbridge.py +512 -0
- amazon_ads_mcp/auth/registry.py +146 -0
- amazon_ads_mcp/auth/secure_token_store.py +297 -0
- amazon_ads_mcp/auth/token_store.py +723 -0
- amazon_ads_mcp/config/__init__.py +5 -0
- amazon_ads_mcp/config/sampling.py +111 -0
- amazon_ads_mcp/config/settings.py +366 -0
- amazon_ads_mcp/exceptions.py +314 -0
- amazon_ads_mcp/middleware/__init__.py +11 -0
- amazon_ads_mcp/middleware/authentication.py +1474 -0
- amazon_ads_mcp/middleware/caching.py +177 -0
- amazon_ads_mcp/middleware/oauth.py +175 -0
- amazon_ads_mcp/middleware/sampling.py +112 -0
- amazon_ads_mcp/models/__init__.py +320 -0
- amazon_ads_mcp/models/amc_models.py +837 -0
- amazon_ads_mcp/models/api_responses.py +847 -0
- amazon_ads_mcp/models/base_models.py +215 -0
- amazon_ads_mcp/models/builtin_responses.py +496 -0
- amazon_ads_mcp/models/dsp_models.py +556 -0
- amazon_ads_mcp/models/stores_brands.py +610 -0
- amazon_ads_mcp/server/__init__.py +6 -0
- amazon_ads_mcp/server/__main__.py +6 -0
- amazon_ads_mcp/server/builtin_prompts.py +269 -0
- amazon_ads_mcp/server/builtin_tools.py +962 -0
- amazon_ads_mcp/server/file_routes.py +547 -0
- amazon_ads_mcp/server/html_templates.py +149 -0
- amazon_ads_mcp/server/mcp_server.py +327 -0
- amazon_ads_mcp/server/openapi_utils.py +158 -0
- amazon_ads_mcp/server/sampling_handler.py +251 -0
- amazon_ads_mcp/server/server_builder.py +751 -0
- amazon_ads_mcp/server/sidecar_loader.py +178 -0
- amazon_ads_mcp/server/transform_executor.py +827 -0
- amazon_ads_mcp/tools/__init__.py +22 -0
- amazon_ads_mcp/tools/cache_management.py +105 -0
- amazon_ads_mcp/tools/download_tools.py +267 -0
- amazon_ads_mcp/tools/identity.py +236 -0
- amazon_ads_mcp/tools/oauth.py +598 -0
- amazon_ads_mcp/tools/profile.py +150 -0
- amazon_ads_mcp/tools/profile_listing.py +285 -0
- amazon_ads_mcp/tools/region.py +320 -0
- amazon_ads_mcp/tools/region_identity.py +175 -0
- amazon_ads_mcp/utils/__init__.py +6 -0
- amazon_ads_mcp/utils/async_compat.py +215 -0
- amazon_ads_mcp/utils/errors.py +452 -0
- amazon_ads_mcp/utils/export_content_type_resolver.py +249 -0
- amazon_ads_mcp/utils/export_download_handler.py +579 -0
- amazon_ads_mcp/utils/header_resolver.py +81 -0
- amazon_ads_mcp/utils/http/__init__.py +56 -0
- amazon_ads_mcp/utils/http/circuit_breaker.py +127 -0
- amazon_ads_mcp/utils/http/client_manager.py +329 -0
- amazon_ads_mcp/utils/http/request.py +207 -0
- amazon_ads_mcp/utils/http/resilience.py +512 -0
- amazon_ads_mcp/utils/http/resilient_client.py +195 -0
- amazon_ads_mcp/utils/http/retry.py +76 -0
- amazon_ads_mcp/utils/http_client.py +873 -0
- amazon_ads_mcp/utils/media/__init__.py +21 -0
- amazon_ads_mcp/utils/media/negotiator.py +243 -0
- amazon_ads_mcp/utils/media/types.py +199 -0
- amazon_ads_mcp/utils/openapi/__init__.py +16 -0
- amazon_ads_mcp/utils/openapi/json.py +55 -0
- amazon_ads_mcp/utils/openapi/loader.py +263 -0
- amazon_ads_mcp/utils/openapi/refs.py +46 -0
- amazon_ads_mcp/utils/region_config.py +200 -0
- amazon_ads_mcp/utils/response_wrapper.py +171 -0
- amazon_ads_mcp/utils/sampling_helpers.py +156 -0
- amazon_ads_mcp/utils/sampling_wrapper.py +173 -0
- amazon_ads_mcp/utils/security.py +630 -0
- amazon_ads_mcp/utils/tool_naming.py +137 -0
- amazon_ads_mcp-0.2.7.dist-info/METADATA +664 -0
- amazon_ads_mcp-0.2.7.dist-info/RECORD +82 -0
- amazon_ads_mcp-0.2.7.dist-info/WHEEL +4 -0
- amazon_ads_mcp-0.2.7.dist-info/entry_points.txt +3 -0
- amazon_ads_mcp-0.2.7.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""Retry decorator for async HTTP operations.
|
|
2
|
+
|
|
3
|
+
This module provides a retry decorator that can be applied to async
|
|
4
|
+
functions to automatically retry failed operations. It supports
|
|
5
|
+
configurable retry attempts, delays with exponential backoff, and
|
|
6
|
+
selective retry based on exception types and HTTP status codes.
|
|
7
|
+
|
|
8
|
+
The retry mechanism includes jitter to prevent thundering herd problems
|
|
9
|
+
and can be customized for different failure scenarios.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import asyncio
|
|
13
|
+
import random
|
|
14
|
+
from functools import wraps
|
|
15
|
+
from typing import Callable, Optional, Tuple, Type, TypeVar
|
|
16
|
+
|
|
17
|
+
import httpx
|
|
18
|
+
|
|
19
|
+
T = TypeVar("T")
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def async_retry(
|
|
23
|
+
max_attempts: int = 3,
|
|
24
|
+
delay: float = 1.0,
|
|
25
|
+
backoff: float = 2.0,
|
|
26
|
+
exceptions: Tuple[Type[Exception], ...] = (httpx.HTTPError,),
|
|
27
|
+
status_codes: Optional[Tuple[int, ...]] = (429, 502, 503, 504),
|
|
28
|
+
) -> Callable[[Callable[..., T]], Callable[..., T]]:
|
|
29
|
+
"""Create a retry decorator for async functions.
|
|
30
|
+
|
|
31
|
+
This decorator wraps an async function with retry logic that will
|
|
32
|
+
automatically retry failed operations based on the specified
|
|
33
|
+
configuration. It supports exponential backoff with jitter and
|
|
34
|
+
can selectively retry based on exception types and HTTP status codes.
|
|
35
|
+
|
|
36
|
+
:param max_attempts: Maximum number of retry attempts (including
|
|
37
|
+
the initial attempt)
|
|
38
|
+
:type max_attempts: int
|
|
39
|
+
:param delay: Initial delay between retries in seconds
|
|
40
|
+
:type delay: float
|
|
41
|
+
:param backoff: Multiplier for delay on each retry attempt
|
|
42
|
+
:type backoff: float
|
|
43
|
+
:param exceptions: Tuple of exception types that should trigger retries
|
|
44
|
+
:type exceptions: Tuple[Type[Exception], ...]
|
|
45
|
+
:param status_codes: Optional tuple of HTTP status codes that should
|
|
46
|
+
trigger retries (only applies to HTTPStatusError)
|
|
47
|
+
:type status_codes: Optional[Tuple[int, ...]]
|
|
48
|
+
:return: Decorator function that can be applied to async functions
|
|
49
|
+
:rtype: Callable[[Callable[..., T]], Callable[..., T]]
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
def decorator(func: Callable[..., T]) -> Callable[..., T]:
|
|
53
|
+
@wraps(func)
|
|
54
|
+
async def wrapper(*args, **kwargs) -> T:
|
|
55
|
+
current_delay = delay
|
|
56
|
+
last_exception: Optional[Exception] = None
|
|
57
|
+
for attempt in range(max_attempts):
|
|
58
|
+
try:
|
|
59
|
+
return await func(*args, **kwargs)
|
|
60
|
+
except exceptions as e:
|
|
61
|
+
last_exception = e
|
|
62
|
+
if isinstance(e, httpx.HTTPStatusError):
|
|
63
|
+
if status_codes and e.response.status_code not in status_codes:
|
|
64
|
+
raise
|
|
65
|
+
if attempt < max_attempts - 1:
|
|
66
|
+
jitter = random.uniform(0.8, 1.2)
|
|
67
|
+
await asyncio.sleep(current_delay * jitter)
|
|
68
|
+
current_delay *= backoff
|
|
69
|
+
else:
|
|
70
|
+
raise
|
|
71
|
+
assert last_exception is not None
|
|
72
|
+
raise last_exception
|
|
73
|
+
|
|
74
|
+
return wrapper
|
|
75
|
+
|
|
76
|
+
return decorator
|