aioscaleway 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 (299) hide show
  1. aioscaleway/__init__.py +48 -0
  2. aioscaleway/_client.py +295 -0
  3. aioscaleway/_enums.py +15 -0
  4. aioscaleway/_errors.py +133 -0
  5. aioscaleway/_models.py +30 -0
  6. aioscaleway/_namespaces.py +167 -0
  7. aioscaleway/_objects.py +143 -0
  8. aioscaleway/_operations/__init__.py +1 -0
  9. aioscaleway/_operations/account/__init__.py +1 -0
  10. aioscaleway/_operations/account/v3/__init__.py +272 -0
  11. aioscaleway/_operations/account/v3/api.py +2199 -0
  12. aioscaleway/_operations/account/v3/models.py +1797 -0
  13. aioscaleway/_operations/annotations/__init__.py +1 -0
  14. aioscaleway/_operations/annotations/v1/__init__.py +38 -0
  15. aioscaleway/_operations/annotations/v1/api.py +527 -0
  16. aioscaleway/_operations/annotations/v1/models.py +223 -0
  17. aioscaleway/_operations/applesilicon/__init__.py +1 -0
  18. aioscaleway/_operations/applesilicon/v1alpha1/__init__.py +102 -0
  19. aioscaleway/_operations/applesilicon/v1alpha1/api.py +1120 -0
  20. aioscaleway/_operations/applesilicon/v1alpha1/models.py +630 -0
  21. aioscaleway/_operations/audit_trail/__init__.py +1 -0
  22. aioscaleway/_operations/audit_trail/v1alpha1/__init__.py +246 -0
  23. aioscaleway/_operations/audit_trail/v1alpha1/api.py +1014 -0
  24. aioscaleway/_operations/audit_trail/v1alpha1/models.py +3289 -0
  25. aioscaleway/_operations/autoscaling/__init__.py +1 -0
  26. aioscaleway/_operations/autoscaling/v1alpha2/__init__.py +62 -0
  27. aioscaleway/_operations/autoscaling/v1alpha2/api.py +334 -0
  28. aioscaleway/_operations/autoscaling/v1alpha2/models.py +476 -0
  29. aioscaleway/_operations/baremetal/__init__.py +1 -0
  30. aioscaleway/_operations/baremetal/v1/__init__.py +160 -0
  31. aioscaleway/_operations/baremetal/v1/api.py +1561 -0
  32. aioscaleway/_operations/baremetal/v1/models.py +1281 -0
  33. aioscaleway/_operations/baremetal/v3/__init__.py +20 -0
  34. aioscaleway/_operations/baremetal/v3/api.py +229 -0
  35. aioscaleway/_operations/baremetal/v3/models.py +80 -0
  36. aioscaleway/_operations/billing/__init__.py +1 -0
  37. aioscaleway/_operations/billing/v2beta1/__init__.py +62 -0
  38. aioscaleway/_operations/billing/v2beta1/api.py +609 -0
  39. aioscaleway/_operations/billing/v2beta1/models.py +464 -0
  40. aioscaleway/_operations/block/__init__.py +1 -0
  41. aioscaleway/_operations/block/v1/__init__.py +46 -0
  42. aioscaleway/_operations/block/v1/api.py +711 -0
  43. aioscaleway/_operations/block/v1/models.py +366 -0
  44. aioscaleway/_operations/block/v1alpha1/__init__.py +46 -0
  45. aioscaleway/_operations/block/v1alpha1/api.py +721 -0
  46. aioscaleway/_operations/block/v1alpha1/models.py +338 -0
  47. aioscaleway/_operations/cockpit/__init__.py +1 -0
  48. aioscaleway/_operations/cockpit/v1/__init__.py +106 -0
  49. aioscaleway/_operations/cockpit/v1/api.py +1772 -0
  50. aioscaleway/_operations/cockpit/v1/models.py +746 -0
  51. aioscaleway/_operations/container/__init__.py +1 -0
  52. aioscaleway/_operations/container/v1/__init__.py +96 -0
  53. aioscaleway/_operations/container/v1/api.py +1214 -0
  54. aioscaleway/_operations/container/v1/models.py +835 -0
  55. aioscaleway/_operations/container/v1beta1/__init__.py +90 -0
  56. aioscaleway/_operations/container/v1beta1/api.py +1569 -0
  57. aioscaleway/_operations/container/v1beta1/models.py +735 -0
  58. aioscaleway/_operations/datalab/__init__.py +1 -0
  59. aioscaleway/_operations/datalab/v1beta1/__init__.py +58 -0
  60. aioscaleway/_operations/datalab/v1beta1/api.py +536 -0
  61. aioscaleway/_operations/datalab/v1beta1/models.py +382 -0
  62. aioscaleway/_operations/datawarehouse/__init__.py +1 -0
  63. aioscaleway/_operations/datawarehouse/v1beta1/__init__.py +58 -0
  64. aioscaleway/_operations/datawarehouse/v1beta1/api.py +891 -0
  65. aioscaleway/_operations/datawarehouse/v1beta1/models.py +395 -0
  66. aioscaleway/_operations/dedibox/__init__.py +1 -0
  67. aioscaleway/_operations/dedibox/v1/__init__.py +192 -0
  68. aioscaleway/_operations/dedibox/v1/api.py +1840 -0
  69. aioscaleway/_operations/dedibox/v1/models.py +1491 -0
  70. aioscaleway/_operations/domain/__init__.py +1 -0
  71. aioscaleway/_operations/domain/v2beta1/__init__.py +254 -0
  72. aioscaleway/_operations/domain/v2beta1/api.py +2528 -0
  73. aioscaleway/_operations/domain/v2beta1/models.py +1715 -0
  74. aioscaleway/_operations/edge_services/__init__.py +1 -0
  75. aioscaleway/_operations/edge_services/v1beta1/__init__.py +148 -0
  76. aioscaleway/_operations/edge_services/v1beta1/api.py +2068 -0
  77. aioscaleway/_operations/edge_services/v1beta1/models.py +1088 -0
  78. aioscaleway/_operations/environmental_footprint/__init__.py +1 -0
  79. aioscaleway/_operations/environmental_footprint/v1alpha1/__init__.py +34 -0
  80. aioscaleway/_operations/environmental_footprint/v1alpha1/api.py +140 -0
  81. aioscaleway/_operations/environmental_footprint/v1alpha1/models.py +182 -0
  82. aioscaleway/_operations/file/__init__.py +1 -0
  83. aioscaleway/_operations/file/v1alpha1/__init__.py +42 -0
  84. aioscaleway/_operations/file/v1alpha1/api.py +719 -0
  85. aioscaleway/_operations/file/v1alpha1/models.py +297 -0
  86. aioscaleway/_operations/flexibleip/__init__.py +1 -0
  87. aioscaleway/_operations/flexibleip/v1alpha1/__init__.py +28 -0
  88. aioscaleway/_operations/flexibleip/v1alpha1/api.py +442 -0
  89. aioscaleway/_operations/flexibleip/v1alpha1/models.py +180 -0
  90. aioscaleway/_operations/function/__init__.py +1 -0
  91. aioscaleway/_operations/function/v1beta1/__init__.py +94 -0
  92. aioscaleway/_operations/function/v1beta1/api.py +1497 -0
  93. aioscaleway/_operations/function/v1beta1/models.py +752 -0
  94. aioscaleway/_operations/generative_apis/__init__.py +1 -0
  95. aioscaleway/_operations/generative_apis/v1/__init__.py +212 -0
  96. aioscaleway/_operations/generative_apis/v1/api.py +703 -0
  97. aioscaleway/_operations/generative_apis/v1/models.py +1574 -0
  98. aioscaleway/_operations/iam/__init__.py +1 -0
  99. aioscaleway/_operations/iam/v1alpha1/__init__.py +176 -0
  100. aioscaleway/_operations/iam/v1alpha1/api.py +3233 -0
  101. aioscaleway/_operations/iam/v1alpha1/models.py +1430 -0
  102. aioscaleway/_operations/inference/__init__.py +1 -0
  103. aioscaleway/_operations/inference/v1/__init__.py +56 -0
  104. aioscaleway/_operations/inference/v1/api.py +731 -0
  105. aioscaleway/_operations/inference/v1/models.py +415 -0
  106. aioscaleway/_operations/instance/__init__.py +1 -0
  107. aioscaleway/_operations/instance/v1/__init__.py +278 -0
  108. aioscaleway/_operations/instance/v1/api.py +3448 -0
  109. aioscaleway/_operations/instance/v1/models.py +1664 -0
  110. aioscaleway/_operations/instance/v2alpha1/__init__.py +172 -0
  111. aioscaleway/_operations/instance/v2alpha1/api.py +2553 -0
  112. aioscaleway/_operations/instance/v2alpha1/models.py +1648 -0
  113. aioscaleway/_operations/interlink/__init__.py +1 -0
  114. aioscaleway/_operations/interlink/v1beta1/__init__.py +56 -0
  115. aioscaleway/_operations/interlink/v1beta1/api.py +1290 -0
  116. aioscaleway/_operations/interlink/v1beta1/models.py +514 -0
  117. aioscaleway/_operations/iot/__init__.py +1 -0
  118. aioscaleway/_operations/iot/v1/__init__.py +112 -0
  119. aioscaleway/_operations/iot/v1/api.py +1468 -0
  120. aioscaleway/_operations/iot/v1/models.py +743 -0
  121. aioscaleway/_operations/ipam/__init__.py +1 -0
  122. aioscaleway/_operations/ipam/v1/__init__.py +26 -0
  123. aioscaleway/_operations/ipam/v1/api.py +509 -0
  124. aioscaleway/_operations/ipam/v1/models.py +206 -0
  125. aioscaleway/_operations/jobs/__init__.py +1 -0
  126. aioscaleway/_operations/jobs/v1alpha1/__init__.py +48 -0
  127. aioscaleway/_operations/jobs/v1alpha1/api.py +609 -0
  128. aioscaleway/_operations/jobs/v1alpha1/models.py +231 -0
  129. aioscaleway/_operations/jobs/v1alpha2/__init__.py +62 -0
  130. aioscaleway/_operations/jobs/v1alpha2/api.py +851 -0
  131. aioscaleway/_operations/jobs/v1alpha2/models.py +476 -0
  132. aioscaleway/_operations/k8s/__init__.py +1 -0
  133. aioscaleway/_operations/k8s/v1/__init__.py +118 -0
  134. aioscaleway/_operations/k8s/v1/api.py +1595 -0
  135. aioscaleway/_operations/k8s/v1/models.py +1354 -0
  136. aioscaleway/_operations/kafka/__init__.py +1 -0
  137. aioscaleway/_operations/kafka/v1alpha1/__init__.py +72 -0
  138. aioscaleway/_operations/kafka/v1alpha1/api.py +682 -0
  139. aioscaleway/_operations/kafka/v1alpha1/models.py +458 -0
  140. aioscaleway/_operations/key_manager/__init__.py +1 -0
  141. aioscaleway/_operations/key_manager/v1alpha1/__init__.py +78 -0
  142. aioscaleway/_operations/key_manager/v1alpha1/api.py +1019 -0
  143. aioscaleway/_operations/key_manager/v1alpha1/models.py +470 -0
  144. aioscaleway/_operations/lb/__init__.py +1 -0
  145. aioscaleway/_operations/lb/v1/__init__.py +152 -0
  146. aioscaleway/_operations/lb/v1/api.py +2790 -0
  147. aioscaleway/_operations/lb/v1/models.py +1335 -0
  148. aioscaleway/_operations/mailbox/__init__.py +1 -0
  149. aioscaleway/_operations/mailbox/v1alpha1/__init__.py +60 -0
  150. aioscaleway/_operations/mailbox/v1alpha1/api.py +853 -0
  151. aioscaleway/_operations/mailbox/v1alpha1/models.py +483 -0
  152. aioscaleway/_operations/marketplace/__init__.py +1 -0
  153. aioscaleway/_operations/marketplace/v2/__init__.py +48 -0
  154. aioscaleway/_operations/marketplace/v2/api.py +573 -0
  155. aioscaleway/_operations/marketplace/v2/models.py +268 -0
  156. aioscaleway/_operations/messageq/__init__.py +1 -0
  157. aioscaleway/_operations/messageq/v1alpha1/__init__.py +60 -0
  158. aioscaleway/_operations/messageq/v1alpha1/api.py +695 -0
  159. aioscaleway/_operations/messageq/v1alpha1/models.py +381 -0
  160. aioscaleway/_operations/mnq/__init__.py +1 -0
  161. aioscaleway/_operations/mnq/v1beta1/__init__.py +60 -0
  162. aioscaleway/_operations/mnq/v1beta1/api.py +1043 -0
  163. aioscaleway/_operations/mnq/v1beta1/models.py +410 -0
  164. aioscaleway/_operations/mongodb/__init__.py +1 -0
  165. aioscaleway/_operations/mongodb/v1/__init__.py +94 -0
  166. aioscaleway/_operations/mongodb/v1/api.py +1279 -0
  167. aioscaleway/_operations/mongodb/v1/models.py +634 -0
  168. aioscaleway/_operations/mongodb/v1alpha1/__init__.py +80 -0
  169. aioscaleway/_operations/mongodb/v1alpha1/api.py +1031 -0
  170. aioscaleway/_operations/mongodb/v1alpha1/models.py +557 -0
  171. aioscaleway/_operations/partner/__init__.py +1 -0
  172. aioscaleway/_operations/partner/v1/__init__.py +22 -0
  173. aioscaleway/_operations/partner/v1/api.py +297 -0
  174. aioscaleway/_operations/partner/v1/models.py +110 -0
  175. aioscaleway/_operations/product_catalog/__init__.py +1 -0
  176. aioscaleway/_operations/product_catalog/v2alpha1/__init__.py +182 -0
  177. aioscaleway/_operations/product_catalog/v2alpha1/api.py +151 -0
  178. aioscaleway/_operations/product_catalog/v2alpha1/models.py +1379 -0
  179. aioscaleway/_operations/qaas/__init__.py +1 -0
  180. aioscaleway/_operations/qaas/v1alpha1/__init__.py +100 -0
  181. aioscaleway/_operations/qaas/v1alpha1/api.py +1441 -0
  182. aioscaleway/_operations/qaas/v1alpha1/models.py +834 -0
  183. aioscaleway/_operations/rdb/__init__.py +1 -0
  184. aioscaleway/_operations/rdb/v1/__init__.py +186 -0
  185. aioscaleway/_operations/rdb/v1/api.py +2610 -0
  186. aioscaleway/_operations/rdb/v1/models.py +1277 -0
  187. aioscaleway/_operations/redis/__init__.py +1 -0
  188. aioscaleway/_operations/redis/v1/__init__.py +74 -0
  189. aioscaleway/_operations/redis/v1/api.py +988 -0
  190. aioscaleway/_operations/redis/v1/models.py +473 -0
  191. aioscaleway/_operations/registry/__init__.py +1 -0
  192. aioscaleway/_operations/registry/v1/__init__.py +36 -0
  193. aioscaleway/_operations/registry/v1/api.py +627 -0
  194. aioscaleway/_operations/registry/v1/models.py +245 -0
  195. aioscaleway/_operations/reseller/__init__.py +1 -0
  196. aioscaleway/_operations/reseller/v1/__init__.py +34 -0
  197. aioscaleway/_operations/reseller/v1/api.py +396 -0
  198. aioscaleway/_operations/reseller/v1/models.py +262 -0
  199. aioscaleway/_operations/s2s_vpn/__init__.py +1 -0
  200. aioscaleway/_operations/s2s_vpn/v1alpha1/__init__.py +84 -0
  201. aioscaleway/_operations/s2s_vpn/v1alpha1/api.py +1409 -0
  202. aioscaleway/_operations/s2s_vpn/v1alpha1/models.py +650 -0
  203. aioscaleway/_operations/search/__init__.py +1 -0
  204. aioscaleway/_operations/search/v1alpha1/__init__.py +36 -0
  205. aioscaleway/_operations/search/v1alpha1/api.py +79 -0
  206. aioscaleway/_operations/search/v1alpha1/models.py +272 -0
  207. aioscaleway/_operations/searchdb/__init__.py +1 -0
  208. aioscaleway/_operations/searchdb/v1alpha1/__init__.py +60 -0
  209. aioscaleway/_operations/searchdb/v1alpha1/api.py +703 -0
  210. aioscaleway/_operations/searchdb/v1alpha1/models.py +388 -0
  211. aioscaleway/_operations/secret/__init__.py +1 -0
  212. aioscaleway/_operations/secret/v1beta1/__init__.py +38 -0
  213. aioscaleway/_operations/secret/v1beta1/api.py +831 -0
  214. aioscaleway/_operations/secret/v1beta1/models.py +304 -0
  215. aioscaleway/_operations/serverless_sqldb/__init__.py +1 -0
  216. aioscaleway/_operations/serverless_sqldb/v1alpha1/__init__.py +30 -0
  217. aioscaleway/_operations/serverless_sqldb/v1alpha1/api.py +515 -0
  218. aioscaleway/_operations/serverless_sqldb/v1alpha1/models.py +221 -0
  219. aioscaleway/_operations/tem/__init__.py +1 -0
  220. aioscaleway/_operations/tem/v1alpha1/__init__.py +126 -0
  221. aioscaleway/_operations/tem/v1alpha1/api.py +1494 -0
  222. aioscaleway/_operations/tem/v1alpha1/models.py +1058 -0
  223. aioscaleway/_operations/test/__init__.py +1 -0
  224. aioscaleway/_operations/test/v1/__init__.py +38 -0
  225. aioscaleway/_operations/test/v1/api.py +290 -0
  226. aioscaleway/_operations/test/v1/models.py +112 -0
  227. aioscaleway/_operations/vpc/__init__.py +1 -0
  228. aioscaleway/_operations/vpc/v2/__init__.py +96 -0
  229. aioscaleway/_operations/vpc/v2/api.py +2018 -0
  230. aioscaleway/_operations/vpc/v2/models.py +679 -0
  231. aioscaleway/_operations/vpcgw/__init__.py +1 -0
  232. aioscaleway/_operations/vpcgw/v2/__init__.py +52 -0
  233. aioscaleway/_operations/vpcgw/v2/api.py +1242 -0
  234. aioscaleway/_operations/vpcgw/v2/models.py +430 -0
  235. aioscaleway/_operations/webhosting/__init__.py +1 -0
  236. aioscaleway/_operations/webhosting/v1/__init__.py +198 -0
  237. aioscaleway/_operations/webhosting/v1/api.py +2337 -0
  238. aioscaleway/_operations/webhosting/v1/models.py +1260 -0
  239. aioscaleway/_root.py +68 -0
  240. aioscaleway/_settings.py +22 -0
  241. aioscaleway/account/__init__.py +98 -0
  242. aioscaleway/account/resources.py +2542 -0
  243. aioscaleway/account/types.py +354 -0
  244. aioscaleway/ai/__init__.py +82 -0
  245. aioscaleway/ai/resources.py +1978 -0
  246. aioscaleway/ai/types.py +340 -0
  247. aioscaleway/analytics/__init__.py +20 -0
  248. aioscaleway/analytics/resources.py +364 -0
  249. aioscaleway/analytics/types.py +52 -0
  250. aioscaleway/billing/__init__.py +22 -0
  251. aioscaleway/billing/resources.py +474 -0
  252. aioscaleway/billing/types.py +88 -0
  253. aioscaleway/compute/__init__.py +256 -0
  254. aioscaleway/compute/resources.py +6331 -0
  255. aioscaleway/compute/types.py +866 -0
  256. aioscaleway/databases/__init__.py +198 -0
  257. aioscaleway/databases/resources.py +4970 -0
  258. aioscaleway/databases/types.py +604 -0
  259. aioscaleway/domains/__init__.py +66 -0
  260. aioscaleway/domains/resources.py +1740 -0
  261. aioscaleway/domains/types.py +244 -0
  262. aioscaleway/email/__init__.py +68 -0
  263. aioscaleway/email/resources.py +1619 -0
  264. aioscaleway/email/types.py +172 -0
  265. aioscaleway/iam/__init__.py +128 -0
  266. aioscaleway/iam/resources.py +3613 -0
  267. aioscaleway/iam/types.py +256 -0
  268. aioscaleway/iot/__init__.py +44 -0
  269. aioscaleway/iot/resources.py +1000 -0
  270. aioscaleway/iot/types.py +96 -0
  271. aioscaleway/kubernetes/__init__.py +70 -0
  272. aioscaleway/kubernetes/resources.py +1569 -0
  273. aioscaleway/kubernetes/types.py +124 -0
  274. aioscaleway/messaging/__init__.py +76 -0
  275. aioscaleway/messaging/resources.py +1800 -0
  276. aioscaleway/messaging/types.py +208 -0
  277. aioscaleway/network/__init__.py +284 -0
  278. aioscaleway/network/resources.py +7895 -0
  279. aioscaleway/network/types.py +534 -0
  280. aioscaleway/observability/__init__.py +70 -0
  281. aioscaleway/observability/resources.py +1949 -0
  282. aioscaleway/observability/types.py +342 -0
  283. aioscaleway/orders/__init__.py +10 -0
  284. aioscaleway/orders/resources.py +82 -0
  285. aioscaleway/orders/types.py +180 -0
  286. aioscaleway/py.typed +0 -0
  287. aioscaleway/serverless/__init__.py +94 -0
  288. aioscaleway/serverless/resources.py +2551 -0
  289. aioscaleway/serverless/types.py +258 -0
  290. aioscaleway/storage/__init__.py +38 -0
  291. aioscaleway/storage/resources.py +933 -0
  292. aioscaleway/storage/types.py +84 -0
  293. aioscaleway/web_hosting/__init__.py +78 -0
  294. aioscaleway/web_hosting/resources.py +1673 -0
  295. aioscaleway/web_hosting/types.py +166 -0
  296. aioscaleway-0.1.0.dist-info/METADATA +205 -0
  297. aioscaleway-0.1.0.dist-info/RECORD +299 -0
  298. aioscaleway-0.1.0.dist-info/WHEEL +4 -0
  299. aioscaleway-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,48 @@
1
+ from aioscaleway._client import ScalewayClient
2
+ from aioscaleway._enums import OpenStrEnum
3
+ from aioscaleway._errors import (
4
+ ConflictError,
5
+ DeniedAuthenticationError,
6
+ InvalidArgumentsError,
7
+ OutOfStockError,
8
+ PermissionsDeniedError,
9
+ PreconditionFailedError,
10
+ QuotasExceededError,
11
+ ResourceExpiredError,
12
+ ResourceNotFoundError,
13
+ ScalewayAPIError,
14
+ ScalewayConfigurationError,
15
+ ScalewayError,
16
+ ScalewayTransportError,
17
+ ServerError,
18
+ TooManyRequestsError,
19
+ TransientStateError,
20
+ )
21
+ from aioscaleway._models import Money, ScalewayModel
22
+ from aioscaleway._root import Scaleway
23
+ from aioscaleway._settings import ScalewaySettings
24
+
25
+ __all__ = [
26
+ "ConflictError",
27
+ "DeniedAuthenticationError",
28
+ "InvalidArgumentsError",
29
+ "Money",
30
+ "OpenStrEnum",
31
+ "OutOfStockError",
32
+ "PermissionsDeniedError",
33
+ "PreconditionFailedError",
34
+ "QuotasExceededError",
35
+ "ResourceExpiredError",
36
+ "ResourceNotFoundError",
37
+ "Scaleway",
38
+ "ScalewayAPIError",
39
+ "ScalewayClient",
40
+ "ScalewayModel",
41
+ "ScalewayConfigurationError",
42
+ "ScalewayError",
43
+ "ScalewaySettings",
44
+ "ScalewayTransportError",
45
+ "ServerError",
46
+ "TooManyRequestsError",
47
+ "TransientStateError",
48
+ ]
aioscaleway/_client.py ADDED
@@ -0,0 +1,295 @@
1
+ from collections.abc import AsyncIterator, Awaitable, Callable, Mapping
2
+ from enum import Enum
3
+ from http import HTTPStatus
4
+ from types import TracebackType
5
+ from typing import Any, Self
6
+ from urllib.parse import quote
7
+
8
+ from httpx2 import (
9
+ AsyncBaseTransport,
10
+ AsyncClient,
11
+ ConnectError,
12
+ ConnectTimeout,
13
+ Response,
14
+ TransportError,
15
+ )
16
+ from pydantic import BaseModel
17
+ from stamina import retry_context
18
+ from whenever import Date, Instant
19
+
20
+ from aioscaleway._errors import (
21
+ ScalewayAPIError,
22
+ ScalewayConfigurationError,
23
+ ScalewayTransportError,
24
+ api_error,
25
+ )
26
+ from aioscaleway._settings import ScalewaySettings
27
+
28
+ IDEMPOTENT_METHODS = frozenset({"GET", "HEAD", "OPTIONS", "PUT", "DELETE"})
29
+ RETRYABLE_STATUSES = frozenset(
30
+ {
31
+ HTTPStatus.TOO_MANY_REQUESTS,
32
+ HTTPStatus.BAD_GATEWAY,
33
+ HTTPStatus.SERVICE_UNAVAILABLE,
34
+ HTTPStatus.GATEWAY_TIMEOUT,
35
+ }
36
+ )
37
+ NEVER_PROCESSED_STATUSES = frozenset(
38
+ {HTTPStatus.TOO_MANY_REQUESTS, HTTPStatus.SERVICE_UNAVAILABLE}
39
+ )
40
+ type QueryValue = str | int | float | bool | Enum | Instant | Date | None
41
+ type Query = Mapping[str, QueryValue | list[Any]]
42
+ type QueryPairs = list[tuple[str, str | int | float | bool | None]]
43
+
44
+
45
+ def retry_decision(method: str, error: Exception) -> bool | float:
46
+ """Tell stamina whether to retry, waiting Retry-After seconds when given."""
47
+ if isinstance(error, ScalewayAPIError):
48
+ if error.status_code not in RETRYABLE_STATUSES:
49
+ return False
50
+ if method not in IDEMPOTENT_METHODS and (
51
+ error.status_code not in NEVER_PROCESSED_STATUSES
52
+ ):
53
+ return False
54
+ retry_after = error.headers.get("retry-after", "")
55
+ return float(retry_after) if retry_after.isdigit() else True
56
+ if isinstance(error, ScalewayTransportError):
57
+ return method in IDEMPOTENT_METHODS or isinstance(
58
+ error.__cause__, ConnectError | ConnectTimeout
59
+ )
60
+ return False
61
+
62
+
63
+ def query_value(value: Any) -> str:
64
+ if isinstance(value, bool):
65
+ return "true" if value else "false"
66
+ if isinstance(value, Enum):
67
+ return str(value.value)
68
+ if isinstance(value, Instant | Date):
69
+ return value.format_iso()
70
+ return str(value)
71
+
72
+
73
+ def encode_query(params: Query | None) -> QueryPairs:
74
+ pairs: QueryPairs = []
75
+ for name, value in (params or {}).items():
76
+ if value is None:
77
+ continue
78
+ values = value if isinstance(value, list) else [value]
79
+ pairs.extend((name, query_value(item)) for item in values if item is not None)
80
+ return pairs
81
+
82
+
83
+ def encode_body(value: Any) -> Any:
84
+ if isinstance(value, BaseModel):
85
+ return value.model_dump(mode="json", by_alias=True, exclude_unset=True)
86
+ if isinstance(value, Enum):
87
+ return value.value
88
+ if isinstance(value, Instant | Date):
89
+ return value.format_iso()
90
+ if isinstance(value, dict):
91
+ return {
92
+ key: encode_body(item) for key, item in value.items() if item is not None
93
+ }
94
+ if isinstance(value, list | tuple):
95
+ return [encode_body(item) for item in value]
96
+ return value
97
+
98
+
99
+ class ScalewayClient:
100
+ """Authenticated, retrying HTTP access to the Scaleway API (`Scaleway().raw`)."""
101
+
102
+ def __init__(
103
+ self,
104
+ settings: ScalewaySettings | None = None,
105
+ *,
106
+ transport: AsyncBaseTransport | None = None,
107
+ http_client: AsyncClient | None = None,
108
+ ) -> None:
109
+ self.settings = ScalewaySettings() if settings is None else settings
110
+ self._owns_http_client = http_client is None
111
+ self._http = http_client or AsyncClient(
112
+ base_url=self.settings.api_url,
113
+ transport=transport,
114
+ timeout=self.settings.timeout,
115
+ )
116
+
117
+ @property
118
+ def http_client(self) -> AsyncClient:
119
+ return self._http
120
+
121
+ async def __aenter__(self) -> Self:
122
+ return self
123
+
124
+ async def __aexit__(
125
+ self,
126
+ exc_type: type[BaseException] | None,
127
+ exc: BaseException | None,
128
+ traceback: TracebackType | None,
129
+ ) -> None:
130
+ await self.aclose()
131
+
132
+ async def aclose(self) -> None:
133
+ if self._owns_http_client:
134
+ await self._http.aclose()
135
+
136
+ def region(self, region: str | None) -> str:
137
+ value = region or self.settings.default_region
138
+ if not value:
139
+ raise ScalewayConfigurationError(
140
+ "No region given and no default_region configured (SCW_DEFAULT_REGION)."
141
+ )
142
+ return value
143
+
144
+ def zone(self, zone: str | None) -> str:
145
+ value = zone or self.settings.default_zone
146
+ if not value:
147
+ raise ScalewayConfigurationError(
148
+ "No zone given and no default_zone configured (SCW_DEFAULT_ZONE)."
149
+ )
150
+ return value
151
+
152
+ def project_id(self, project_id: str | None) -> str | None:
153
+ return project_id or self.settings.default_project_id
154
+
155
+ def organization_id(self, organization_id: str | None) -> str | None:
156
+ return organization_id or self.settings.default_organization_id
157
+
158
+ def owner(
159
+ self,
160
+ *,
161
+ project_id: str | None,
162
+ organization_id: str | None,
163
+ keys: tuple[str, str] = ("project_id", "organization_id"),
164
+ ) -> dict[str, str]:
165
+ """Pick the project or the organization a resource belongs to."""
166
+ project_key, organization_key = keys
167
+ if project_id:
168
+ return {project_key: project_id}
169
+ if organization_id:
170
+ return {organization_key: organization_id}
171
+ if self.settings.default_project_id:
172
+ return {project_key: self.settings.default_project_id}
173
+ if self.settings.default_organization_id:
174
+ return {organization_key: self.settings.default_organization_id}
175
+ return {}
176
+
177
+ @staticmethod
178
+ def path(template: str, **values: Any) -> str:
179
+ if any(value is None or value == "" for value in values.values()):
180
+ missing = [name for name, value in values.items() if value in (None, "")]
181
+ raise ScalewayConfigurationError(
182
+ f"Empty path parameter: {', '.join(missing)}."
183
+ )
184
+ return template.format(
185
+ **{
186
+ name: quote(query_value(value), safe="")
187
+ for name, value in values.items()
188
+ }
189
+ )
190
+
191
+ def _headers(self, extra: Mapping[str, str] | None) -> dict[str, str]:
192
+ headers = {"User-Agent": self.settings.user_agent}
193
+ if self.settings.secret_key is not None:
194
+ headers["X-Auth-Token"] = self.settings.secret_key.get_secret_value()
195
+ headers.update(extra or {})
196
+ return headers
197
+
198
+ async def request(
199
+ self,
200
+ method: str,
201
+ path: str,
202
+ *,
203
+ params: Query | None = None,
204
+ body: Any = None,
205
+ content: bytes | None = None,
206
+ headers: Mapping[str, str] | None = None,
207
+ ) -> Response:
208
+ """Send one request, retried on throttling and transient failures."""
209
+ method = method.upper()
210
+ query = encode_query(params)
211
+ json_body = None if body is None else encode_body(body)
212
+ request_headers = self._headers(headers)
213
+ async for attempt in retry_context(
214
+ on=lambda error: retry_decision(method, error),
215
+ attempts=self.settings.retry_attempts,
216
+ timeout=self.settings.retry_timeout,
217
+ wait_initial=self.settings.retry_wait_initial,
218
+ wait_max=self.settings.retry_wait_max,
219
+ ):
220
+ with attempt:
221
+ return await self._send(
222
+ method, path, query, json_body, content, request_headers
223
+ )
224
+ raise AssertionError("unreachable: stamina either returns or raises")
225
+
226
+ async def _send(
227
+ self,
228
+ method: str,
229
+ path: str,
230
+ query: QueryPairs,
231
+ json_body: Any,
232
+ content: bytes | None,
233
+ headers: dict[str, str],
234
+ ) -> Response:
235
+ try:
236
+ response = await self._http.request(
237
+ method,
238
+ path,
239
+ params=query,
240
+ json=json_body,
241
+ content=content,
242
+ headers=headers,
243
+ )
244
+ except TransportError as error:
245
+ raise ScalewayTransportError(method, path, repr(error)) from error
246
+ if response.is_error:
247
+ try:
248
+ error_body: Any = response.json()
249
+ except ValueError:
250
+ error_body = response.text
251
+ raise api_error(
252
+ method,
253
+ str(response.url),
254
+ response.status_code,
255
+ error_body,
256
+ dict(response.headers),
257
+ )
258
+ return response
259
+
260
+ async def request_json(
261
+ self,
262
+ method: str,
263
+ path: str,
264
+ *,
265
+ params: Query | None = None,
266
+ body: Any = None,
267
+ content: bytes | None = None,
268
+ headers: Mapping[str, str] | None = None,
269
+ ) -> Any:
270
+ response = await self.request(
271
+ method, path, params=params, body=body, content=content, headers=headers
272
+ )
273
+ if response.status_code == HTTPStatus.NO_CONTENT or not response.content:
274
+ return None
275
+ return response.json()
276
+
277
+
278
+ async def paginate[Page, Item](
279
+ fetch: Callable[[int], Awaitable[Page]],
280
+ items: Callable[[Page], list[Item]],
281
+ total: Callable[[Page], int | None],
282
+ ) -> AsyncIterator[Item]:
283
+ """Walk the `page` / `page_size` pagination until `total_count` items are read."""
284
+ page_number = 1
285
+ seen = 0
286
+ while True:
287
+ page = await fetch(page_number)
288
+ batch = items(page)
289
+ for item in batch:
290
+ yield item
291
+ seen += len(batch)
292
+ expected = total(page)
293
+ if not batch or (expected is not None and seen >= expected):
294
+ return
295
+ page_number += 1
aioscaleway/_enums.py ADDED
@@ -0,0 +1,15 @@
1
+ from enum import StrEnum
2
+ from typing import Self
3
+
4
+
5
+ class OpenStrEnum(StrEnum):
6
+ """A string enum that accepts values added to the API after generation."""
7
+
8
+ @classmethod
9
+ def _missing_(cls, value: object) -> Self | None:
10
+ if not isinstance(value, str):
11
+ return None
12
+ member = str.__new__(cls, value)
13
+ member._name_ = value.upper()
14
+ member._value_ = value
15
+ return member
aioscaleway/_errors.py ADDED
@@ -0,0 +1,133 @@
1
+ from http import HTTPStatus
2
+ from typing import Any
3
+
4
+
5
+ class ScalewayError(Exception):
6
+ """Base class of every error raised by aioscaleway."""
7
+
8
+
9
+ class ScalewayConfigurationError(ScalewayError):
10
+ """A value the request needs is neither given nor configured."""
11
+
12
+
13
+ class ScalewayTransportError(ScalewayError):
14
+ """The API could not be reached, or the connection broke."""
15
+
16
+ def __init__(self, method: str, url: str, reason: str) -> None:
17
+ super().__init__(f"{method} {url} failed: {reason}")
18
+ self.method = method
19
+ self.url = url
20
+
21
+
22
+ class ScalewayAPIError(ScalewayError):
23
+ """The API answered with an error status."""
24
+
25
+ def __init__(
26
+ self,
27
+ method: str,
28
+ url: str,
29
+ status_code: int,
30
+ body: Any,
31
+ headers: dict[str, str] | None = None,
32
+ ) -> None:
33
+ self.method = method
34
+ self.url = url
35
+ self.status_code = status_code
36
+ self.body = body
37
+ self.headers = headers or {}
38
+ details = body if isinstance(body, dict) else {}
39
+ self.type: str | None = details.get("type")
40
+ self.message: str = str(details.get("message") or body or "")
41
+ self.details: Any = details.get("details")
42
+ super().__init__(f"{method} {url} answered {status_code}: {self.message}")
43
+
44
+
45
+ class InvalidArgumentsError(ScalewayAPIError):
46
+ pass
47
+
48
+
49
+ class DeniedAuthenticationError(ScalewayAPIError):
50
+ pass
51
+
52
+
53
+ class PermissionsDeniedError(ScalewayAPIError):
54
+ pass
55
+
56
+
57
+ class QuotasExceededError(ScalewayAPIError):
58
+ pass
59
+
60
+
61
+ class ResourceNotFoundError(ScalewayAPIError):
62
+ pass
63
+
64
+
65
+ class ConflictError(ScalewayAPIError):
66
+ pass
67
+
68
+
69
+ class TransientStateError(ConflictError):
70
+ pass
71
+
72
+
73
+ class PreconditionFailedError(ScalewayAPIError):
74
+ pass
75
+
76
+
77
+ class ResourceExpiredError(ScalewayAPIError):
78
+ pass
79
+
80
+
81
+ class OutOfStockError(ScalewayAPIError):
82
+ pass
83
+
84
+
85
+ class TooManyRequestsError(ScalewayAPIError):
86
+ pass
87
+
88
+
89
+ class ServerError(ScalewayAPIError):
90
+ pass
91
+
92
+
93
+ ERRORS_BY_TYPE: dict[str, type[ScalewayAPIError]] = {
94
+ "invalid_arguments": InvalidArgumentsError,
95
+ "denied_authentication": DeniedAuthenticationError,
96
+ "permissions_denied": PermissionsDeniedError,
97
+ "quotas_exceeded": QuotasExceededError,
98
+ "not_found": ResourceNotFoundError,
99
+ "unknown_resource": ResourceNotFoundError,
100
+ "conflict": ConflictError,
101
+ "transient_state": TransientStateError,
102
+ "precondition_failed": PreconditionFailedError,
103
+ "resource_expired": ResourceExpiredError,
104
+ "out_of_stock": OutOfStockError,
105
+ }
106
+
107
+ ERRORS_BY_STATUS: dict[int, type[ScalewayAPIError]] = {
108
+ HTTPStatus.BAD_REQUEST: InvalidArgumentsError,
109
+ HTTPStatus.UNAUTHORIZED: DeniedAuthenticationError,
110
+ HTTPStatus.FORBIDDEN: PermissionsDeniedError,
111
+ HTTPStatus.NOT_FOUND: ResourceNotFoundError,
112
+ HTTPStatus.CONFLICT: ConflictError,
113
+ HTTPStatus.GONE: ResourceExpiredError,
114
+ HTTPStatus.PRECONDITION_FAILED: PreconditionFailedError,
115
+ HTTPStatus.TOO_MANY_REQUESTS: TooManyRequestsError,
116
+ }
117
+
118
+
119
+ def api_error(
120
+ method: str,
121
+ url: str,
122
+ status_code: int,
123
+ body: Any,
124
+ headers: dict[str, str] | None = None,
125
+ ) -> ScalewayAPIError:
126
+ error_type = body.get("type") if isinstance(body, dict) else None
127
+ error_class = ERRORS_BY_TYPE.get(str(error_type)) or ERRORS_BY_STATUS.get(
128
+ status_code,
129
+ ServerError
130
+ if status_code >= HTTPStatus.INTERNAL_SERVER_ERROR
131
+ else ScalewayAPIError,
132
+ )
133
+ return error_class(method, url, status_code, body, headers)
aioscaleway/_models.py ADDED
@@ -0,0 +1,30 @@
1
+ from decimal import Decimal
2
+ from typing import Any
3
+
4
+ from pydantic import BaseModel, ConfigDict, PrivateAttr
5
+
6
+
7
+ class ScalewayModel(BaseModel):
8
+ """Base of every generated model: unknown fields are kept, not rejected."""
9
+
10
+ model_config = ConfigDict(
11
+ extra="allow",
12
+ populate_by_name=True,
13
+ serialize_by_alias=True,
14
+ use_enum_values=False,
15
+ protected_namespaces=(),
16
+ )
17
+
18
+ _session: Any = PrivateAttr(default=None)
19
+ _key: dict[str, str | None] = PrivateAttr(default_factory=dict)
20
+
21
+
22
+ class Money(ScalewayModel):
23
+ """An amount of money, as `google.type.Money`: whole units plus nanos."""
24
+
25
+ currency_code: str = ""
26
+ units: int = 0
27
+ nanos: int = 0
28
+
29
+ def to_decimal(self) -> Decimal:
30
+ return Decimal(self.units) + Decimal(self.nanos).scaleb(-9)
@@ -0,0 +1,167 @@
1
+ # Generated by scripts/generate.py from specs/, do not edit.
2
+ from functools import cached_property
3
+ from typing import TYPE_CHECKING
4
+
5
+ from aioscaleway._objects import Session
6
+
7
+ if TYPE_CHECKING:
8
+ from aioscaleway.account import AccountNamespace
9
+ from aioscaleway.ai import AiNamespace
10
+ from aioscaleway.analytics import AnalyticsNamespace
11
+ from aioscaleway.billing import BillingNamespace
12
+ from aioscaleway.compute import ComputeNamespace
13
+ from aioscaleway.databases import DatabasesNamespace
14
+ from aioscaleway.domains import DomainsNamespace
15
+ from aioscaleway.email import EmailNamespace
16
+ from aioscaleway.iam import IamNamespace
17
+ from aioscaleway.iot import IotNamespace
18
+ from aioscaleway.kubernetes import KubernetesNamespace
19
+ from aioscaleway.messaging import MessagingNamespace
20
+ from aioscaleway.network import NetworkNamespace
21
+ from aioscaleway.observability import ObservabilityNamespace
22
+ from aioscaleway.orders import OrdersNamespace
23
+ from aioscaleway.serverless import ServerlessNamespace
24
+ from aioscaleway.storage import StorageNamespace
25
+ from aioscaleway.web_hosting import WebHostingNamespace
26
+
27
+
28
+ class Namespaces:
29
+ """Every business area, as an attribute of the client."""
30
+
31
+ _session: Session
32
+
33
+ @cached_property
34
+ def account(self) -> "AccountNamespace":
35
+ from aioscaleway.account import (
36
+ AccountNamespace, # lazy: an area is slow to import
37
+ )
38
+
39
+ return AccountNamespace(self._session)
40
+
41
+ @cached_property
42
+ def ai(self) -> "AiNamespace":
43
+ from aioscaleway.ai import AiNamespace # lazy: an area is slow to import
44
+
45
+ return AiNamespace(self._session)
46
+
47
+ @cached_property
48
+ def analytics(self) -> "AnalyticsNamespace":
49
+ from aioscaleway.analytics import (
50
+ AnalyticsNamespace, # lazy: an area is slow to import
51
+ )
52
+
53
+ return AnalyticsNamespace(self._session)
54
+
55
+ @cached_property
56
+ def billing(self) -> "BillingNamespace":
57
+ from aioscaleway.billing import (
58
+ BillingNamespace, # lazy: an area is slow to import
59
+ )
60
+
61
+ return BillingNamespace(self._session)
62
+
63
+ @cached_property
64
+ def compute(self) -> "ComputeNamespace":
65
+ from aioscaleway.compute import (
66
+ ComputeNamespace, # lazy: an area is slow to import
67
+ )
68
+
69
+ return ComputeNamespace(self._session)
70
+
71
+ @cached_property
72
+ def databases(self) -> "DatabasesNamespace":
73
+ from aioscaleway.databases import (
74
+ DatabasesNamespace, # lazy: an area is slow to import
75
+ )
76
+
77
+ return DatabasesNamespace(self._session)
78
+
79
+ @cached_property
80
+ def domains(self) -> "DomainsNamespace":
81
+ from aioscaleway.domains import (
82
+ DomainsNamespace, # lazy: an area is slow to import
83
+ )
84
+
85
+ return DomainsNamespace(self._session)
86
+
87
+ @cached_property
88
+ def email(self) -> "EmailNamespace":
89
+ from aioscaleway.email import EmailNamespace # lazy: an area is slow to import
90
+
91
+ return EmailNamespace(self._session)
92
+
93
+ @cached_property
94
+ def iam(self) -> "IamNamespace":
95
+ from aioscaleway.iam import IamNamespace # lazy: an area is slow to import
96
+
97
+ return IamNamespace(self._session)
98
+
99
+ @cached_property
100
+ def iot(self) -> "IotNamespace":
101
+ from aioscaleway.iot import IotNamespace # lazy: an area is slow to import
102
+
103
+ return IotNamespace(self._session)
104
+
105
+ @cached_property
106
+ def kubernetes(self) -> "KubernetesNamespace":
107
+ from aioscaleway.kubernetes import (
108
+ KubernetesNamespace, # lazy: an area is slow to import
109
+ )
110
+
111
+ return KubernetesNamespace(self._session)
112
+
113
+ @cached_property
114
+ def messaging(self) -> "MessagingNamespace":
115
+ from aioscaleway.messaging import (
116
+ MessagingNamespace, # lazy: an area is slow to import
117
+ )
118
+
119
+ return MessagingNamespace(self._session)
120
+
121
+ @cached_property
122
+ def network(self) -> "NetworkNamespace":
123
+ from aioscaleway.network import (
124
+ NetworkNamespace, # lazy: an area is slow to import
125
+ )
126
+
127
+ return NetworkNamespace(self._session)
128
+
129
+ @cached_property
130
+ def observability(self) -> "ObservabilityNamespace":
131
+ from aioscaleway.observability import (
132
+ ObservabilityNamespace, # lazy: an area is slow to import
133
+ )
134
+
135
+ return ObservabilityNamespace(self._session)
136
+
137
+ @cached_property
138
+ def orders(self) -> "OrdersNamespace":
139
+ from aioscaleway.orders import (
140
+ OrdersNamespace, # lazy: an area is slow to import
141
+ )
142
+
143
+ return OrdersNamespace(self._session)
144
+
145
+ @cached_property
146
+ def serverless(self) -> "ServerlessNamespace":
147
+ from aioscaleway.serverless import (
148
+ ServerlessNamespace, # lazy: an area is slow to import
149
+ )
150
+
151
+ return ServerlessNamespace(self._session)
152
+
153
+ @cached_property
154
+ def storage(self) -> "StorageNamespace":
155
+ from aioscaleway.storage import (
156
+ StorageNamespace, # lazy: an area is slow to import
157
+ )
158
+
159
+ return StorageNamespace(self._session)
160
+
161
+ @cached_property
162
+ def web_hosting(self) -> "WebHostingNamespace":
163
+ from aioscaleway.web_hosting import (
164
+ WebHostingNamespace, # lazy: an area is slow to import
165
+ )
166
+
167
+ return WebHostingNamespace(self._session)