capo-codecatalyst 0.1.0__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.
Files changed (233) hide show
  1. capo_codecatalyst/__init__.py +51 -0
  2. capo_codecatalyst/_async.py +25 -0
  3. capo_codecatalyst/_auth/_identity.py +14 -0
  4. capo_codecatalyst/_auth/_providers.py +154 -0
  5. capo_codecatalyst/_auth/_signers.py +43 -0
  6. capo_codecatalyst/_auth/_sigv4.py +434 -0
  7. capo_codecatalyst/_auth/_zapros_handler.py +80 -0
  8. capo_codecatalyst/_iter.py +113 -0
  9. capo_codecatalyst/_operations/code_catalyst/create_access_token.py +153 -0
  10. capo_codecatalyst/_operations/code_catalyst/create_dev_environment.py +165 -0
  11. capo_codecatalyst/_operations/code_catalyst/create_project.py +158 -0
  12. capo_codecatalyst/_operations/code_catalyst/create_source_repository.py +159 -0
  13. capo_codecatalyst/_operations/code_catalyst/create_source_repository_branch.py +165 -0
  14. capo_codecatalyst/_operations/code_catalyst/delete_access_token.py +146 -0
  15. capo_codecatalyst/_operations/code_catalyst/delete_dev_environment.py +159 -0
  16. capo_codecatalyst/_operations/code_catalyst/delete_project.py +155 -0
  17. capo_codecatalyst/_operations/code_catalyst/delete_source_repository.py +155 -0
  18. capo_codecatalyst/_operations/code_catalyst/delete_space.py +152 -0
  19. capo_codecatalyst/_operations/code_catalyst/get_dev_environment.py +159 -0
  20. capo_codecatalyst/_operations/code_catalyst/get_project.py +153 -0
  21. capo_codecatalyst/_operations/code_catalyst/get_source_repository.py +156 -0
  22. capo_codecatalyst/_operations/code_catalyst/get_source_repository_clone_urls.py +157 -0
  23. capo_codecatalyst/_operations/code_catalyst/get_space.py +152 -0
  24. capo_codecatalyst/_operations/code_catalyst/get_subscription.py +155 -0
  25. capo_codecatalyst/_operations/code_catalyst/get_user_details.py +157 -0
  26. capo_codecatalyst/_operations/code_catalyst/get_workflow.py +159 -0
  27. capo_codecatalyst/_operations/code_catalyst/get_workflow_run.py +161 -0
  28. capo_codecatalyst/_operations/code_catalyst/list_access_tokens.py +153 -0
  29. capo_codecatalyst/_operations/code_catalyst/list_dev_environment_sessions.py +164 -0
  30. capo_codecatalyst/_operations/code_catalyst/list_dev_environments.py +156 -0
  31. capo_codecatalyst/_operations/code_catalyst/list_event_logs.py +160 -0
  32. capo_codecatalyst/_operations/code_catalyst/list_projects.py +158 -0
  33. capo_codecatalyst/_operations/code_catalyst/list_source_repositories.py +159 -0
  34. capo_codecatalyst/_operations/code_catalyst/list_source_repository_branches.py +164 -0
  35. capo_codecatalyst/_operations/code_catalyst/list_spaces.py +155 -0
  36. capo_codecatalyst/_operations/code_catalyst/list_workflow_runs.py +166 -0
  37. capo_codecatalyst/_operations/code_catalyst/list_workflows.py +168 -0
  38. capo_codecatalyst/_operations/code_catalyst/start_dev_environment.py +160 -0
  39. capo_codecatalyst/_operations/code_catalyst/start_dev_environment_session.py +163 -0
  40. capo_codecatalyst/_operations/code_catalyst/start_workflow_run.py +160 -0
  41. capo_codecatalyst/_operations/code_catalyst/stop_dev_environment.py +155 -0
  42. capo_codecatalyst/_operations/code_catalyst/stop_dev_environment_session.py +156 -0
  43. capo_codecatalyst/_operations/code_catalyst/update_dev_environment.py +164 -0
  44. capo_codecatalyst/_operations/code_catalyst/update_project.py +159 -0
  45. capo_codecatalyst/_operations/code_catalyst/update_space.py +156 -0
  46. capo_codecatalyst/_operations/code_catalyst/verify_session.py +146 -0
  47. capo_codecatalyst/_pagination.py +21 -0
  48. capo_codecatalyst/_protocol/__init__.py +1 -0
  49. capo_codecatalyst/_protocol/errors.py +93 -0
  50. capo_codecatalyst/_protocol/eventstream.py +238 -0
  51. capo_codecatalyst/_protocol/serialize.py +47 -0
  52. capo_codecatalyst/_protocol/xml.py +33 -0
  53. capo_codecatalyst/_resources/code_catalyst/access_token.py +359 -0
  54. capo_codecatalyst/_resources/code_catalyst/space.py +578 -0
  55. capo_codecatalyst/_rule_engine/__init__.py +0 -0
  56. capo_codecatalyst/_rule_engine/_aws_partition.py +160 -0
  57. capo_codecatalyst/_rule_engine/_endpoint_rule_set.py +98 -0
  58. capo_codecatalyst/_rule_engine/_endpoint_runtime.py +389 -0
  59. capo_codecatalyst/_services/_aws_config.py +156 -0
  60. capo_codecatalyst/_services/_pipeline.py +195 -0
  61. capo_codecatalyst/_services/async_code_catalyst.py +214 -0
  62. capo_codecatalyst/_services/code_catalyst.py +212 -0
  63. capo_codecatalyst/errors/__init__.py +33 -0
  64. capo_codecatalyst/errors/_base.py +94 -0
  65. capo_codecatalyst/errors/access_denied_exception.py +47 -0
  66. capo_codecatalyst/errors/conflict_exception.py +45 -0
  67. capo_codecatalyst/errors/resource_not_found_exception.py +47 -0
  68. capo_codecatalyst/errors/service_quota_exceeded_exception.py +49 -0
  69. capo_codecatalyst/errors/throttling_exception.py +45 -0
  70. capo_codecatalyst/errors/validation_exception.py +45 -0
  71. capo_codecatalyst/py.typed +0 -0
  72. capo_codecatalyst/types/_prelude/blob.py +12 -0
  73. capo_codecatalyst/types/_prelude/timestamp.py +17 -0
  74. capo_codecatalyst/types/access_token_id.py +5 -0
  75. capo_codecatalyst/types/access_token_name.py +5 -0
  76. capo_codecatalyst/types/access_token_secret.py +5 -0
  77. capo_codecatalyst/types/access_token_summaries.py +31 -0
  78. capo_codecatalyst/types/access_token_summary.py +54 -0
  79. capo_codecatalyst/types/client_token.py +5 -0
  80. capo_codecatalyst/types/comparison_operator.py +5 -0
  81. capo_codecatalyst/types/create_access_token_request.py +46 -0
  82. capo_codecatalyst/types/create_access_token_response.py +63 -0
  83. capo_codecatalyst/types/create_dev_environment_request.py +123 -0
  84. capo_codecatalyst/types/create_dev_environment_response.py +52 -0
  85. capo_codecatalyst/types/create_project_request.py +43 -0
  86. capo_codecatalyst/types/create_project_response.py +49 -0
  87. capo_codecatalyst/types/create_source_repository_branch_request.py +38 -0
  88. capo_codecatalyst/types/create_source_repository_branch_response.py +60 -0
  89. capo_codecatalyst/types/create_source_repository_request.py +38 -0
  90. capo_codecatalyst/types/create_source_repository_response.py +57 -0
  91. capo_codecatalyst/types/delete_access_token_request.py +24 -0
  92. capo_codecatalyst/types/delete_access_token_response.py +18 -0
  93. capo_codecatalyst/types/delete_dev_environment_request.py +29 -0
  94. capo_codecatalyst/types/delete_dev_environment_response.py +46 -0
  95. capo_codecatalyst/types/delete_project_request.py +26 -0
  96. capo_codecatalyst/types/delete_project_response.py +44 -0
  97. capo_codecatalyst/types/delete_source_repository_request.py +29 -0
  98. capo_codecatalyst/types/delete_source_repository_response.py +48 -0
  99. capo_codecatalyst/types/delete_space_request.py +24 -0
  100. capo_codecatalyst/types/delete_space_response.py +37 -0
  101. capo_codecatalyst/types/dev_environment_access_details.py +38 -0
  102. capo_codecatalyst/types/dev_environment_repository_summaries.py +39 -0
  103. capo_codecatalyst/types/dev_environment_repository_summary.py +42 -0
  104. capo_codecatalyst/types/dev_environment_session_configuration.py +56 -0
  105. capo_codecatalyst/types/dev_environment_session_summary.py +71 -0
  106. capo_codecatalyst/types/dev_environment_session_type.py +5 -0
  107. capo_codecatalyst/types/dev_environment_sessions_summary_list.py +37 -0
  108. capo_codecatalyst/types/dev_environment_status.py +5 -0
  109. capo_codecatalyst/types/dev_environment_summary.py +163 -0
  110. capo_codecatalyst/types/dev_environment_summary_list.py +33 -0
  111. capo_codecatalyst/types/email_address.py +29 -0
  112. capo_codecatalyst/types/event_log_entries.py +31 -0
  113. capo_codecatalyst/types/event_log_entry.py +174 -0
  114. capo_codecatalyst/types/event_payload.py +29 -0
  115. capo_codecatalyst/types/execute_command_session_configuration.py +53 -0
  116. capo_codecatalyst/types/execute_command_session_configuration_arguments.py +14 -0
  117. capo_codecatalyst/types/filter.py +50 -0
  118. capo_codecatalyst/types/filter_key.py +5 -0
  119. capo_codecatalyst/types/filters.py +29 -0
  120. capo_codecatalyst/types/get_dev_environment_request.py +29 -0
  121. capo_codecatalyst/types/get_dev_environment_response.py +169 -0
  122. capo_codecatalyst/types/get_project_request.py +26 -0
  123. capo_codecatalyst/types/get_project_response.py +49 -0
  124. capo_codecatalyst/types/get_source_repository_clone_urls_request.py +29 -0
  125. capo_codecatalyst/types/get_source_repository_clone_urls_response.py +28 -0
  126. capo_codecatalyst/types/get_source_repository_request.py +29 -0
  127. capo_codecatalyst/types/get_source_repository_response.py +88 -0
  128. capo_codecatalyst/types/get_space_request.py +24 -0
  129. capo_codecatalyst/types/get_space_response.py +51 -0
  130. capo_codecatalyst/types/get_subscription_request.py +24 -0
  131. capo_codecatalyst/types/get_subscription_response.py +59 -0
  132. capo_codecatalyst/types/get_user_details_request.py +21 -0
  133. capo_codecatalyst/types/get_user_details_response.py +60 -0
  134. capo_codecatalyst/types/get_workflow_request.py +29 -0
  135. capo_codecatalyst/types/get_workflow_response.py +136 -0
  136. capo_codecatalyst/types/get_workflow_run_request.py +29 -0
  137. capo_codecatalyst/types/get_workflow_run_response.py +127 -0
  138. capo_codecatalyst/types/ide.py +29 -0
  139. capo_codecatalyst/types/ide_configuration.py +29 -0
  140. capo_codecatalyst/types/ide_configuration_list.py +31 -0
  141. capo_codecatalyst/types/ides.py +29 -0
  142. capo_codecatalyst/types/inactivity_timeout_minutes.py +5 -0
  143. capo_codecatalyst/types/instance_type.py +5 -0
  144. capo_codecatalyst/types/list_access_tokens_request.py +29 -0
  145. capo_codecatalyst/types/list_access_tokens_response.py +45 -0
  146. capo_codecatalyst/types/list_dev_environment_sessions_request.py +41 -0
  147. capo_codecatalyst/types/list_dev_environment_sessions_response.py +49 -0
  148. capo_codecatalyst/types/list_dev_environments_request.py +57 -0
  149. capo_codecatalyst/types/list_dev_environments_response.py +49 -0
  150. capo_codecatalyst/types/list_event_logs_request.py +75 -0
  151. capo_codecatalyst/types/list_event_logs_response.py +45 -0
  152. capo_codecatalyst/types/list_projects_request.py +53 -0
  153. capo_codecatalyst/types/list_projects_response.py +42 -0
  154. capo_codecatalyst/types/list_source_repositories_item.py +81 -0
  155. capo_codecatalyst/types/list_source_repositories_items.py +35 -0
  156. capo_codecatalyst/types/list_source_repositories_request.py +38 -0
  157. capo_codecatalyst/types/list_source_repositories_response.py +48 -0
  158. capo_codecatalyst/types/list_source_repository_branches_item.py +60 -0
  159. capo_codecatalyst/types/list_source_repository_branches_items.py +39 -0
  160. capo_codecatalyst/types/list_source_repository_branches_request.py +41 -0
  161. capo_codecatalyst/types/list_source_repository_branches_response.py +51 -0
  162. capo_codecatalyst/types/list_spaces_request.py +23 -0
  163. capo_codecatalyst/types/list_spaces_response.py +42 -0
  164. capo_codecatalyst/types/list_workflow_runs_request.py +54 -0
  165. capo_codecatalyst/types/list_workflow_runs_response.py +44 -0
  166. capo_codecatalyst/types/list_workflows_request.py +51 -0
  167. capo_codecatalyst/types/list_workflows_response.py +42 -0
  168. capo_codecatalyst/types/name_string.py +5 -0
  169. capo_codecatalyst/types/operation_type.py +5 -0
  170. capo_codecatalyst/types/persistent_storage.py +26 -0
  171. capo_codecatalyst/types/persistent_storage_configuration.py +28 -0
  172. capo_codecatalyst/types/project_description.py +5 -0
  173. capo_codecatalyst/types/project_display_name.py +5 -0
  174. capo_codecatalyst/types/project_information.py +29 -0
  175. capo_codecatalyst/types/project_list_filter.py +54 -0
  176. capo_codecatalyst/types/project_list_filters.py +31 -0
  177. capo_codecatalyst/types/project_summaries.py +31 -0
  178. capo_codecatalyst/types/project_summary.py +38 -0
  179. capo_codecatalyst/types/region_string.py +5 -0
  180. capo_codecatalyst/types/repositories_input.py +31 -0
  181. capo_codecatalyst/types/repository_input.py +40 -0
  182. capo_codecatalyst/types/sensitive_string.py +5 -0
  183. capo_codecatalyst/types/source_repository_branch_ref_string.py +5 -0
  184. capo_codecatalyst/types/source_repository_branch_string.py +5 -0
  185. capo_codecatalyst/types/source_repository_description_string.py +5 -0
  186. capo_codecatalyst/types/source_repository_id_string.py +5 -0
  187. capo_codecatalyst/types/source_repository_name_string.py +5 -0
  188. capo_codecatalyst/types/space_description.py +5 -0
  189. capo_codecatalyst/types/space_summaries.py +29 -0
  190. capo_codecatalyst/types/space_summary.py +51 -0
  191. capo_codecatalyst/types/start_dev_environment_request.py +63 -0
  192. capo_codecatalyst/types/start_dev_environment_response.py +54 -0
  193. capo_codecatalyst/types/start_dev_environment_session_request.py +52 -0
  194. capo_codecatalyst/types/start_dev_environment_session_response.py +77 -0
  195. capo_codecatalyst/types/start_workflow_run_request.py +35 -0
  196. capo_codecatalyst/types/start_workflow_run_response.py +53 -0
  197. capo_codecatalyst/types/status_reason.py +5 -0
  198. capo_codecatalyst/types/stop_dev_environment_request.py +29 -0
  199. capo_codecatalyst/types/stop_dev_environment_response.py +54 -0
  200. capo_codecatalyst/types/stop_dev_environment_session_request.py +31 -0
  201. capo_codecatalyst/types/stop_dev_environment_session_response.py +59 -0
  202. capo_codecatalyst/types/string_list.py +14 -0
  203. capo_codecatalyst/types/timestamp.py +20 -0
  204. capo_codecatalyst/types/update_dev_environment_request.py +76 -0
  205. capo_codecatalyst/types/update_dev_environment_response.py +93 -0
  206. capo_codecatalyst/types/update_project_request.py +35 -0
  207. capo_codecatalyst/types/update_project_response.py +46 -0
  208. capo_codecatalyst/types/update_space_request.py +33 -0
  209. capo_codecatalyst/types/update_space_response.py +40 -0
  210. capo_codecatalyst/types/user_identity.py +50 -0
  211. capo_codecatalyst/types/user_type.py +5 -0
  212. capo_codecatalyst/types/uuid.py +5 -0
  213. capo_codecatalyst/types/verify_session_response.py +23 -0
  214. capo_codecatalyst/types/workflow_definition.py +26 -0
  215. capo_codecatalyst/types/workflow_definition_summary.py +26 -0
  216. capo_codecatalyst/types/workflow_run_mode.py +5 -0
  217. capo_codecatalyst/types/workflow_run_sort_criteria.py +18 -0
  218. capo_codecatalyst/types/workflow_run_sort_criteria_list.py +35 -0
  219. capo_codecatalyst/types/workflow_run_status.py +5 -0
  220. capo_codecatalyst/types/workflow_run_status_reason.py +18 -0
  221. capo_codecatalyst/types/workflow_run_status_reasons.py +35 -0
  222. capo_codecatalyst/types/workflow_run_summaries.py +31 -0
  223. capo_codecatalyst/types/workflow_run_summary.py +119 -0
  224. capo_codecatalyst/types/workflow_sort_criteria.py +18 -0
  225. capo_codecatalyst/types/workflow_sort_criteria_list.py +33 -0
  226. capo_codecatalyst/types/workflow_status.py +5 -0
  227. capo_codecatalyst/types/workflow_summaries.py +31 -0
  228. capo_codecatalyst/types/workflow_summary.py +123 -0
  229. capo_codecatalyst-0.1.0.dist-info/METADATA +82 -0
  230. capo_codecatalyst-0.1.0.dist-info/RECORD +233 -0
  231. capo_codecatalyst-0.1.0.dist-info/WHEEL +5 -0
  232. capo_codecatalyst-0.1.0.dist-info/licenses/LICENSE +21 -0
  233. capo_codecatalyst-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,156 @@
1
+ from __future__ import annotations
2
+
3
+ import configparser
4
+ import functools
5
+ import os
6
+ from dataclasses import dataclass
7
+ from pathlib import Path
8
+ from typing import TypeVar
9
+
10
+ from capo_codecatalyst._services._pipeline import (
11
+ AsyncInterceptor,
12
+ AsyncNextFn,
13
+ AsyncOperationRequest,
14
+ AsyncOperationResponse,
15
+ Interceptor,
16
+ NextFn,
17
+ OperationRequest,
18
+ OperationResponse,
19
+ )
20
+
21
+ ENDPOINT_ENV_VAR = "AWS_ENDPOINT_URL_CODE_CATALYST"
22
+ SERVICE_ID = "code_catalyst"
23
+ TInput = TypeVar("TInput")
24
+ TOutput = TypeVar("TOutput")
25
+
26
+
27
+ @dataclass(frozen=True)
28
+ class AwsSettings:
29
+ region: str | None
30
+ endpoint: str | None
31
+ use_fips: bool
32
+ use_dual_stack: bool
33
+ max_attempts: int
34
+
35
+
36
+ def _env_bool(name: str) -> bool | None:
37
+ val = os.environ.get(name)
38
+ if val is None:
39
+ return None
40
+ return val.strip().lower() in ("true", "1")
41
+
42
+
43
+ def _profile_bool(section: dict[str, str], key: str) -> bool | None:
44
+ val = section.get(key)
45
+ if val is None:
46
+ return None
47
+ return val.strip().lower() in ("true", "1")
48
+
49
+
50
+ def config_file() -> Path:
51
+ raw_cfg = os.environ.get("AWS_CONFIG_FILE")
52
+ return Path(raw_cfg).expanduser() if raw_cfg else Path.home() / ".aws" / "config"
53
+
54
+
55
+ def active_profile() -> str:
56
+ return (
57
+ os.environ.get("AWS_PROFILE")
58
+ or os.environ.get("AWS_DEFAULT_PROFILE")
59
+ or "default"
60
+ )
61
+
62
+
63
+ def _load_profile(
64
+ profile: str | None = None,
65
+ ) -> tuple[dict[str, str], dict[str, dict[str, str]]]:
66
+ profile = profile or active_profile()
67
+ cfg_file = config_file()
68
+ merged: dict[str, str] = {}
69
+ services: dict[str, dict[str, str]] = {}
70
+ if cfg_file.is_file():
71
+ cfg = configparser.ConfigParser(interpolation=None)
72
+ cfg.read(cfg_file)
73
+ key = "default" if profile == "default" else f"profile {profile}"
74
+ if cfg.has_section(key):
75
+ merged.update(dict(cfg.items(key)))
76
+ services_name = merged.get("services")
77
+ if services_name and cfg.has_section(f"services {services_name}"):
78
+ raw = dict(cfg.items(f"services {services_name}"))
79
+ for svc, block in raw.items():
80
+ parsed: dict[str, str] = {}
81
+ for line in block.splitlines():
82
+ stripped = line.strip()
83
+ if "=" in stripped:
84
+ k, _, val = stripped.partition("=")
85
+ parsed[k.strip()] = val.strip()
86
+ services[svc] = parsed
87
+ return merged, services
88
+
89
+
90
+ @functools.cache
91
+ def load_aws_settings() -> AwsSettings:
92
+ profile, services = _load_profile()
93
+ region = os.environ.get("AWS_REGION") or profile.get("region")
94
+ endpoint = (
95
+ os.environ.get(ENDPOINT_ENV_VAR)
96
+ or os.environ.get("AWS_ENDPOINT_URL")
97
+ or services.get(SERVICE_ID, {}).get("endpoint_url")
98
+ or profile.get("endpoint_url")
99
+ )
100
+ use_fips: bool | None = _env_bool("AWS_USE_FIPS_ENDPOINT")
101
+ if use_fips is None:
102
+ use_fips = _profile_bool(profile, "use_fips_endpoint")
103
+ if use_fips is None:
104
+ use_fips = False
105
+ use_dual_stack: bool | None = _env_bool("AWS_USE_DUALSTACK_ENDPOINT")
106
+ if use_dual_stack is None:
107
+ use_dual_stack = _profile_bool(profile, "use_dualstack_endpoint")
108
+ if use_dual_stack is None:
109
+ use_dual_stack = False
110
+ max_attempts_raw = os.environ.get("AWS_MAX_ATTEMPTS") or profile.get("max_attempts")
111
+ max_attempts = int(max_attempts_raw) if max_attempts_raw else 3
112
+ return AwsSettings(
113
+ region=region,
114
+ endpoint=endpoint,
115
+ use_fips=use_fips,
116
+ use_dual_stack=use_dual_stack,
117
+ max_attempts=max_attempts,
118
+ )
119
+
120
+
121
+ def aws_config() -> Interceptor[TInput, TOutput]:
122
+ def interceptor(
123
+ request: OperationRequest[TInput], next: NextFn[TInput, TOutput]
124
+ ) -> OperationResponse[TOutput]:
125
+ settings = load_aws_settings()
126
+ options = request.options
127
+ if options.region is None:
128
+ options.region = settings.region
129
+ if options.endpoint is None:
130
+ options.endpoint = settings.endpoint
131
+ if options.use_fips is None:
132
+ options.use_fips = settings.use_fips
133
+ if options.retry_max_attempts is None:
134
+ options.retry_max_attempts = settings.max_attempts
135
+ return next(request)
136
+
137
+ return interceptor
138
+
139
+
140
+ def aaws_config() -> AsyncInterceptor[TInput, TOutput]:
141
+ async def interceptor(
142
+ request: AsyncOperationRequest[TInput], next: AsyncNextFn[TInput, TOutput]
143
+ ) -> AsyncOperationResponse[TOutput]:
144
+ settings = load_aws_settings()
145
+ options = request.options
146
+ if options.region is None:
147
+ options.region = settings.region
148
+ if options.endpoint is None:
149
+ options.endpoint = settings.endpoint
150
+ if options.use_fips is None:
151
+ options.use_fips = settings.use_fips
152
+ if options.retry_max_attempts is None:
153
+ options.retry_max_attempts = settings.max_attempts
154
+ return await next(request)
155
+
156
+ return interceptor
@@ -0,0 +1,195 @@
1
+ from __future__ import annotations
2
+
3
+ import random
4
+ import time
5
+ from collections.abc import Sequence
6
+ from dataclasses import dataclass
7
+ from typing import TYPE_CHECKING, Awaitable, Callable, Generic, TypeVar
8
+
9
+ from zapros import (
10
+ AsyncClient,
11
+ Client,
12
+ ConnectionError,
13
+ Response,
14
+ SSLError,
15
+ TimeoutError,
16
+ )
17
+
18
+ from capo_codecatalyst._async import anysleep
19
+ from capo_codecatalyst.errors import ServiceError
20
+
21
+ if TYPE_CHECKING:
22
+ from capo_codecatalyst._auth._providers import BearerTokenProvider
23
+
24
+ TInput = TypeVar("TInput")
25
+ TOutput = TypeVar("TOutput")
26
+
27
+
28
+ @dataclass
29
+ class OperationOptions:
30
+ client: Client
31
+ use_fips: bool | None = None
32
+ region: str | None = None
33
+ endpoint: str | None = None
34
+ retry_max_attempts: int | None = None
35
+ bearer_provider: BearerTokenProvider | None = None
36
+
37
+
38
+ @dataclass
39
+ class AsyncOperationOptions:
40
+ client: AsyncClient
41
+ use_fips: bool | None = None
42
+ region: str | None = None
43
+ endpoint: str | None = None
44
+ retry_max_attempts: int | None = None
45
+ bearer_provider: BearerTokenProvider | None = None
46
+
47
+
48
+ @dataclass
49
+ class OperationRequest(Generic[TInput]):
50
+ input: TInput
51
+ options: OperationOptions
52
+
53
+
54
+ @dataclass
55
+ class AsyncOperationRequest(Generic[TInput]):
56
+ input: TInput
57
+ options: AsyncOperationOptions
58
+
59
+
60
+ @dataclass
61
+ class OperationResponse(Generic[TOutput]):
62
+ output: TOutput
63
+ response: Response
64
+
65
+
66
+ @dataclass
67
+ class AsyncOperationResponse(Generic[TOutput]):
68
+ output: TOutput
69
+ response: Response
70
+
71
+
72
+ NextFn = Callable[
73
+ [OperationRequest[TInput]],
74
+ OperationResponse[TOutput],
75
+ ]
76
+
77
+ AsyncNextFn = Callable[
78
+ [AsyncOperationRequest[TInput]],
79
+ Awaitable[AsyncOperationResponse[TOutput]],
80
+ ]
81
+
82
+ Interceptor = Callable[
83
+ [OperationRequest[TInput], NextFn[TInput, TOutput]],
84
+ OperationResponse[TOutput],
85
+ ]
86
+
87
+ AsyncInterceptor = Callable[
88
+ [AsyncOperationRequest[TInput], AsyncNextFn[TInput, TOutput]],
89
+ Awaitable[AsyncOperationResponse[TOutput]],
90
+ ]
91
+
92
+
93
+ def execute_pipeline(
94
+ request: OperationRequest[TInput],
95
+ handler: NextFn[TInput, TOutput],
96
+ interceptors: Sequence[Interceptor[TInput, TOutput]],
97
+ ) -> OperationResponse[TOutput]:
98
+ def make_chain(index: int) -> NextFn[TInput, TOutput]:
99
+ if index < len(interceptors):
100
+ interceptor = interceptors[index]
101
+
102
+ def next_fn(req: OperationRequest[TInput]) -> OperationResponse[TOutput]:
103
+ return interceptor(req, make_chain(index + 1))
104
+
105
+ return next_fn
106
+ return handler
107
+
108
+ return make_chain(0)(request)
109
+
110
+
111
+ async def aexecute_pipeline(
112
+ request: AsyncOperationRequest[TInput],
113
+ handler: AsyncNextFn[TInput, TOutput],
114
+ interceptors: Sequence[AsyncInterceptor[TInput, TOutput]],
115
+ ) -> AsyncOperationResponse[TOutput]:
116
+ def make_chain(index: int) -> AsyncNextFn[TInput, TOutput]:
117
+ if index < len(interceptors):
118
+ interceptor = interceptors[index]
119
+
120
+ async def next_fn(
121
+ req: AsyncOperationRequest[TInput],
122
+ ) -> AsyncOperationResponse[TOutput]:
123
+ return await interceptor(req, make_chain(index + 1))
124
+
125
+ return next_fn
126
+ return handler
127
+
128
+ return await make_chain(0)(request)
129
+
130
+
131
+ def _is_retryable(exc: Exception) -> bool:
132
+ if isinstance(exc, ServiceError):
133
+ return exc.is_retryable
134
+ if isinstance(exc, SSLError):
135
+ return False
136
+ if isinstance(exc, (ConnectionError, TimeoutError)):
137
+ return True
138
+ return False
139
+
140
+
141
+ def _retry_delay(attempt: int, is_throttling: bool) -> float:
142
+ base = 1.0 if is_throttling else 0.5
143
+ delay = base * (2.0 ** min(attempt - 1, 10))
144
+ delay = min(20.0, delay)
145
+ return random.uniform(0.0, delay)
146
+
147
+
148
+ def retry() -> Interceptor[TInput, TOutput]:
149
+ def interceptor(
150
+ request: OperationRequest[TInput], next: NextFn[TInput, TOutput]
151
+ ) -> OperationResponse[TOutput]:
152
+ max_attempts = request.options.retry_max_attempts or 3
153
+ last_exc: Exception | None = None
154
+ for attempt in range(1, max_attempts + 1):
155
+ try:
156
+ return next(request)
157
+ except Exception as exc:
158
+ if not _is_retryable(exc):
159
+ raise
160
+ last_exc = exc
161
+ if attempt < max_attempts:
162
+ is_throttling = (
163
+ isinstance(exc, ServiceError) and exc.is_throttling_error
164
+ )
165
+ time.sleep(_retry_delay(attempt, is_throttling))
166
+
167
+ assert last_exc
168
+ raise last_exc
169
+
170
+ return interceptor
171
+
172
+
173
+ def aretry() -> AsyncInterceptor[TInput, TOutput]:
174
+ async def interceptor(
175
+ request: AsyncOperationRequest[TInput], next: AsyncNextFn[TInput, TOutput]
176
+ ) -> AsyncOperationResponse[TOutput]:
177
+ max_attempts = request.options.retry_max_attempts or 3
178
+ last_exc: Exception | None = None
179
+ for attempt in range(1, max_attempts + 1):
180
+ try:
181
+ return await next(request)
182
+ except Exception as exc:
183
+ if not _is_retryable(exc):
184
+ raise
185
+ last_exc = exc
186
+ if attempt < max_attempts:
187
+ is_throttling = (
188
+ isinstance(exc, ServiceError) and exc.is_throttling_error
189
+ )
190
+ await anysleep(_retry_delay(attempt, is_throttling))
191
+
192
+ assert last_exc
193
+ raise last_exc
194
+
195
+ return interceptor
@@ -0,0 +1,214 @@
1
+ """Generated from Smithy shape ``com.amazonaws.codecatalyst#CodeCatalyst``."""
2
+
3
+ import warnings
4
+ from typing import TYPE_CHECKING, Any, Iterable, Optional
5
+
6
+ from typing_extensions import Self, TypedDict
7
+ from zapros import AsyncBaseHandler, AsyncClient
8
+
9
+ import capo_codecatalyst._auth._signers
10
+ import capo_codecatalyst._auth._sigv4
11
+ from capo_codecatalyst._auth._providers import (
12
+ BearerTokenProvider,
13
+ StaticBearerTokenProvider,
14
+ )
15
+ from capo_codecatalyst._auth._zapros_handler import AuthMiddleware
16
+ from capo_codecatalyst._resources.code_catalyst.access_token import AsyncAccessToken
17
+ from capo_codecatalyst._resources.code_catalyst.space import AsyncSpace
18
+ from capo_codecatalyst._services._aws_config import aaws_config
19
+ from capo_codecatalyst._services._pipeline import (
20
+ AsyncInterceptor,
21
+ AsyncOperationOptions,
22
+ AsyncOperationRequest,
23
+ AsyncOperationResponse,
24
+ aexecute_pipeline,
25
+ aretry,
26
+ )
27
+
28
+ if TYPE_CHECKING:
29
+ import capo_codecatalyst.types.get_user_details_request
30
+ import capo_codecatalyst.types.get_user_details_response
31
+ import capo_codecatalyst.types.verify_session_response
32
+
33
+
34
+ class AsyncCodeCatalystClientConfig(TypedDict, total=False, closed=True):
35
+ operation_interceptors: Iterable[AsyncInterceptor[Any, Any]]
36
+ retry_max_attempts: int | None
37
+ use_fips: bool | None
38
+ region: str | None
39
+ endpoint: str | None
40
+ bearer_provider: BearerTokenProvider | None
41
+
42
+
43
+ class AsyncCodeCatalystClient:
44
+ """A client for the ``CodeCatalyst`` service.
45
+
46
+ Args:
47
+ http_handler: HTTP handler for sending requests. If not provided, creates a default handler.
48
+ operation_interceptors: Interceptors that wrap every operation call. If not provided, defaults to an empty list.
49
+ retry_max_attempts: Maximum number of times to retry a failed operation. Defaults to 3.
50
+ use_fips: The value of the ``AWS::UseFIPS`` endpoint parameter.
51
+ region: The value of the ``AWS::Region`` endpoint parameter.
52
+ endpoint: The value of the ``SDK::Endpoint`` endpoint parameter.
53
+ bearer: Bearer token for authentication.
54
+ bearer_provider: Provider that resolves bearer tokens. Takes precedence over ``bearer``.
55
+ """
56
+
57
+ def __init__(
58
+ self,
59
+ http_handler: AsyncBaseHandler | None = None,
60
+ operation_interceptors: Iterable[AsyncInterceptor[Any, Any]] | None = None,
61
+ retry_max_attempts: int | None = None,
62
+ use_fips: bool | None = None,
63
+ region: str | None = None,
64
+ endpoint: str | None = None,
65
+ bearer: str | None = None,
66
+ bearer_provider: BearerTokenProvider | None = None,
67
+ ):
68
+ self._client = AsyncClient(http_handler).wrap_with_middleware(
69
+ lambda next: AuthMiddleware(next)
70
+ )
71
+ if bearer is not None and bearer_provider is not None:
72
+ warnings.warn(
73
+ "Both bearer and bearer_provider given; provider takes precedence"
74
+ )
75
+ if bearer_provider is None and bearer is not None:
76
+ bearer_provider = StaticBearerTokenProvider(bearer)
77
+ self._config = AsyncCodeCatalystClientConfig(
78
+ {
79
+ "operation_interceptors": operation_interceptors or [],
80
+ "retry_max_attempts": retry_max_attempts,
81
+ "use_fips": use_fips,
82
+ "region": region,
83
+ "endpoint": endpoint,
84
+ "bearer_provider": bearer_provider,
85
+ }
86
+ )
87
+
88
+ # resources
89
+ self.access_token = AsyncAccessToken(self)
90
+ self.space = AsyncSpace(self)
91
+
92
+ def operation_options(
93
+ self, config_overrides: Optional[AsyncCodeCatalystClientConfig] = None
94
+ ) -> tuple[Iterable[AsyncInterceptor[Any, Any]], AsyncOperationOptions]:
95
+ overrides: AsyncCodeCatalystClientConfig = config_overrides or {}
96
+ interceptors_: list[AsyncInterceptor[Any, Any]] = [
97
+ *overrides.get(
98
+ "operation_interceptors", self._config.get("operation_interceptors", [])
99
+ ),
100
+ aaws_config(),
101
+ aretry(),
102
+ ]
103
+ options_: AsyncOperationOptions = AsyncOperationOptions(
104
+ client=self._client,
105
+ retry_max_attempts=overrides.get(
106
+ "retry_max_attempts", self._config.get("retry_max_attempts")
107
+ ),
108
+ use_fips=overrides.get("use_fips", self._config.get("use_fips")),
109
+ region=overrides.get("region", self._config.get("region")),
110
+ endpoint=overrides.get("endpoint", self._config.get("endpoint")),
111
+ bearer_provider=overrides.get(
112
+ "bearer_provider", self._config.get("bearer_provider")
113
+ ),
114
+ )
115
+ return interceptors_, options_
116
+
117
+ async def get_user_details(
118
+ self,
119
+ *,
120
+ config_overrides: Optional[AsyncCodeCatalystClientConfig] = None,
121
+ id: Optional[str] = None,
122
+ user_name: Optional[str] = None,
123
+ ) -> "capo_codecatalyst.types.get_user_details_response.GetUserDetailsResponse":
124
+ """<p>Returns information about a user. </p>
125
+
126
+ Args:
127
+ id: <p>The system-generated unique ID of the user. </p>
128
+ user_name: <p>The name of the user as displayed in Amazon CodeCatalyst.</p>
129
+
130
+ Raises:
131
+ capo_codecatalyst.errors.access_denied_exception.AccessDeniedException: <p>The request was denied because you don't have sufficient access to perform this action. Verify that you are a member of a role that allows this action.</p>
132
+ capo_codecatalyst.errors.conflict_exception.ConflictException: <p>The request was denied because the requested operation would cause a conflict with the current state of a service resource associated with the request. Another user might have updated the resource. Reload, make sure you have the latest data, and then try again.</p>
133
+ capo_codecatalyst.errors.resource_not_found_exception.ResourceNotFoundException: <p>The request was denied because the specified resource was not found. Verify that the spelling is correct and that you have access to the resource.</p>
134
+ capo_codecatalyst.errors.service_quota_exceeded_exception.ServiceQuotaExceededException: <p>The request was denied because one or more resources has reached its limits for the tier the space belongs to. Either reduce the number of resources, or change the tier if applicable.</p>
135
+ capo_codecatalyst.errors.throttling_exception.ThrottlingException: <p>The request was denied due to request throttling.</p>
136
+ capo_codecatalyst.errors.validation_exception.ValidationException: <p>The request was denied because an input failed to satisfy the constraints specified by the service. Check the spelling and input requirements, and then try again.</p>
137
+ capo_codecatalyst.errors.UnknownServiceError: The service returned an error code this client does not model.
138
+ """
139
+
140
+ async def _handler(
141
+ req: "AsyncOperationRequest[capo_codecatalyst.types.get_user_details_request.GetUserDetailsRequest]",
142
+ ) -> AsyncOperationResponse[
143
+ "capo_codecatalyst.types.get_user_details_response.GetUserDetailsResponse"
144
+ ]:
145
+ import capo_codecatalyst._operations.code_catalyst.get_user_details
146
+
147
+ (
148
+ output,
149
+ http_response,
150
+ ) = await capo_codecatalyst._operations.code_catalyst.get_user_details.async_get_user_details(
151
+ req.options, req.input
152
+ )
153
+ return AsyncOperationResponse(output=output, response=http_response)
154
+
155
+ interceptors_, options_ = self.operation_options(config_overrides)
156
+ input_: capo_codecatalyst.types.get_user_details_request.GetUserDetailsRequest = {}
157
+ if id is not None:
158
+ input_["id"] = id
159
+ if user_name is not None:
160
+ input_["user_name"] = user_name
161
+
162
+ response = await aexecute_pipeline(
163
+ AsyncOperationRequest(input=input_, options=options_),
164
+ handler=_handler,
165
+ interceptors=list(interceptors_),
166
+ )
167
+ await response.response.aclose()
168
+ return response.output
169
+
170
+ async def verify_session(
171
+ self, *, config_overrides: Optional[AsyncCodeCatalystClientConfig] = None
172
+ ) -> "capo_codecatalyst.types.verify_session_response.VerifySessionResponse":
173
+ """<p>Verifies whether the calling user has a valid Amazon CodeCatalyst login and session. If successful, this returns the ID of the user in Amazon CodeCatalyst.</p>
174
+
175
+ Raises:
176
+ capo_codecatalyst.errors.access_denied_exception.AccessDeniedException: <p>The request was denied because you don't have sufficient access to perform this action. Verify that you are a member of a role that allows this action.</p>
177
+ capo_codecatalyst.errors.conflict_exception.ConflictException: <p>The request was denied because the requested operation would cause a conflict with the current state of a service resource associated with the request. Another user might have updated the resource. Reload, make sure you have the latest data, and then try again.</p>
178
+ capo_codecatalyst.errors.resource_not_found_exception.ResourceNotFoundException: <p>The request was denied because the specified resource was not found. Verify that the spelling is correct and that you have access to the resource.</p>
179
+ capo_codecatalyst.errors.service_quota_exceeded_exception.ServiceQuotaExceededException: <p>The request was denied because one or more resources has reached its limits for the tier the space belongs to. Either reduce the number of resources, or change the tier if applicable.</p>
180
+ capo_codecatalyst.errors.throttling_exception.ThrottlingException: <p>The request was denied due to request throttling.</p>
181
+ capo_codecatalyst.errors.validation_exception.ValidationException: <p>The request was denied because an input failed to satisfy the constraints specified by the service. Check the spelling and input requirements, and then try again.</p>
182
+ capo_codecatalyst.errors.UnknownServiceError: The service returned an error code this client does not model.
183
+ """
184
+
185
+ async def _handler(
186
+ req: "AsyncOperationRequest[None]",
187
+ ) -> AsyncOperationResponse[
188
+ "capo_codecatalyst.types.verify_session_response.VerifySessionResponse"
189
+ ]:
190
+ import capo_codecatalyst._operations.code_catalyst.verify_session
191
+
192
+ (
193
+ output,
194
+ http_response,
195
+ ) = await capo_codecatalyst._operations.code_catalyst.verify_session.async_verify_session(
196
+ req.options
197
+ )
198
+ return AsyncOperationResponse(output=output, response=http_response)
199
+
200
+ interceptors_, options_ = self.operation_options(config_overrides)
201
+
202
+ response = await aexecute_pipeline(
203
+ AsyncOperationRequest(input=None, options=options_),
204
+ handler=_handler,
205
+ interceptors=list(interceptors_),
206
+ )
207
+ await response.response.aclose()
208
+ return response.output
209
+
210
+ async def __aenter__(self) -> Self:
211
+ return self
212
+
213
+ async def __aexit__(self, exc_type: Any, exc: Any, tb: Any):
214
+ await self._client.aclose()