celitech-sdk 2.0.4__tar.gz → 2.0.6__tar.gz

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 (84) hide show
  1. {celitech_sdk-2.0.4/src/celitech_sdk.egg-info → celitech_sdk-2.0.6}/PKG-INFO +5 -5
  2. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/PyPI_README.md +4 -4
  3. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/README.md +4 -4
  4. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/pyproject.toml +1 -1
  5. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/models/bad_request.py +2 -0
  6. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/models/create_purchase_ok_response.py +2 -0
  7. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/models/create_purchase_request.py +4 -2
  8. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/models/create_purchase_v2_ok_response.py +2 -0
  9. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/models/create_purchase_v2_request.py +6 -4
  10. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/models/edit_purchase_ok_response.py +2 -0
  11. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/models/edit_purchase_request.py +2 -0
  12. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/models/get_esim_device_ok_response.py +2 -0
  13. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/models/get_esim_history_ok_response.py +2 -0
  14. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/models/get_esim_ok_response.py +2 -0
  15. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/models/get_purchase_consumption_ok_response.py +6 -4
  16. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/models/grant_type.py +2 -0
  17. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/models/list_destinations_ok_response.py +2 -0
  18. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/models/list_packages_ok_response.py +6 -4
  19. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/models/list_purchases_ok_response.py +8 -6
  20. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/models/o_auth_token_request.py +1 -0
  21. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/models/o_auth_token_response.py +2 -0
  22. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/models/token_ok_response.py +2 -0
  23. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/models/top_up_esim_ok_response.py +2 -0
  24. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/models/top_up_esim_request.py +6 -4
  25. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/models/unauthorized.py +2 -0
  26. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/models/utils/base_model.py +8 -0
  27. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/net/request_chain/handlers/http_handler.py +14 -0
  28. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/net/transport/serializer.py +1 -1
  29. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/net/transport/utils.py +3 -0
  30. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/services/async_/destinations.py +1 -1
  31. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/services/async_/e_sim.py +1 -1
  32. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/services/async_/i_frame.py +1 -1
  33. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/services/async_/o_auth.py +1 -1
  34. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/services/async_/packages.py +5 -1
  35. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/services/async_/purchases.py +1 -1
  36. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/services/destinations.py +5 -1
  37. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/services/e_sim.py +15 -3
  38. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/services/i_frame.py +3 -1
  39. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/services/o_auth.py +5 -1
  40. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/services/packages.py +15 -1
  41. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/services/purchases.py +29 -6
  42. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/services/utils/validator.py +38 -3
  43. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6/src/celitech_sdk.egg-info}/PKG-INFO +5 -5
  44. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/LICENSE +0 -0
  45. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/setup.cfg +0 -0
  46. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/__init__.py +0 -0
  47. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/models/__init__.py +0 -0
  48. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/models/utils/__init__.py +0 -0
  49. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/models/utils/base_error.py +0 -0
  50. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/models/utils/cast_models.py +0 -0
  51. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/models/utils/json_map.py +0 -0
  52. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/models/utils/one_of_base_model.py +0 -0
  53. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/models/utils/sentinel.py +0 -0
  54. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/net/__init__.py +0 -0
  55. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/net/environment/__init__.py +0 -0
  56. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/net/environment/environment.py +0 -0
  57. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/net/headers/__init__.py +0 -0
  58. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/net/headers/base_header.py +0 -0
  59. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/net/oauth/token_manager.py +0 -0
  60. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/net/request_chain/__init__.py +0 -0
  61. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/net/request_chain/handlers/__init__.py +0 -0
  62. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/net/request_chain/handlers/base_handler.py +0 -0
  63. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/net/request_chain/handlers/oauth_handler.py +0 -0
  64. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/net/request_chain/handlers/retry_handler.py +0 -0
  65. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/net/request_chain/request_chain.py +0 -0
  66. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/net/sdk_config.py +0 -0
  67. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/net/transport/__init__.py +0 -0
  68. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/net/transport/api_error.py +0 -0
  69. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/net/transport/request.py +0 -0
  70. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/net/transport/request_error.py +0 -0
  71. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/net/transport/response.py +0 -0
  72. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/sdk.py +0 -0
  73. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/sdk_async.py +0 -0
  74. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/services/__init__.py +0 -0
  75. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/services/async_/__init__.py +0 -0
  76. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/services/async_/utils/__init__.py +0 -0
  77. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/services/async_/utils/to_async.py +0 -0
  78. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/services/utils/__init__.py +0 -0
  79. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/services/utils/base_service.py +0 -0
  80. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech/services/utils/default_headers.py +0 -0
  81. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech_sdk.egg-info/SOURCES.txt +0 -0
  82. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech_sdk.egg-info/dependency_links.txt +0 -0
  83. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech_sdk.egg-info/requires.txt +0 -0
  84. {celitech_sdk-2.0.4 → celitech_sdk-2.0.6}/src/celitech_sdk.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: celitech-sdk
3
- Version: 2.0.4
3
+ Version: 2.0.6
4
4
  Summary: Welcome to the CELITECH API documentation!
5
5
  License: MIT
6
6
  Project-URL: Repository, https://github.com/Celitech/CelitechSDKPython
@@ -11,14 +11,14 @@ Requires-Dist: requests>=2.31.0
11
11
  Requires-Dist: pydantic<3.0.0,>=2.0.0
12
12
  Dynamic: license-file
13
13
 
14
- # Celitech Python SDK 2.0.4<a id="celitech-python-sdk-204"></a>
14
+ # Celitech Python SDK 2.0.6<a id="celitech-python-sdk-206"></a>
15
15
 
16
16
  Welcome to the Celitech SDK documentation. This guide will help you get started with integrating and using the Celitech SDK in your project.
17
17
 
18
18
  ## Versions<a id="versions"></a>
19
19
 
20
- - API version: `2.0.4`
21
- - SDK version: `2.0.4`
20
+ - API version: `2.0.6`
21
+ - SDK version: `2.0.6`
22
22
 
23
23
  ## About the API<a id="about-the-api"></a>
24
24
 
@@ -44,7 +44,7 @@ Useful links: [Homepage](https://www.celitech.com) | [Support email](mailto:supp
44
44
 
45
45
  ## Supported Language Versions<a id="supported-language-versions"></a>
46
46
 
47
- This SDK is compatible with the following versions: `Python >= 3.7`
47
+ This SDK is compatible with the following versions: `Python >= 3.9`
48
48
 
49
49
  ## Installation<a id="installation"></a>
50
50
 
@@ -1,11 +1,11 @@
1
- # Celitech Python SDK 2.0.4<a id="celitech-python-sdk-204"></a>
1
+ # Celitech Python SDK 2.0.6<a id="celitech-python-sdk-206"></a>
2
2
 
3
3
  Welcome to the Celitech SDK documentation. This guide will help you get started with integrating and using the Celitech SDK in your project.
4
4
 
5
5
  ## Versions<a id="versions"></a>
6
6
 
7
- - API version: `2.0.4`
8
- - SDK version: `2.0.4`
7
+ - API version: `2.0.6`
8
+ - SDK version: `2.0.6`
9
9
 
10
10
  ## About the API<a id="about-the-api"></a>
11
11
 
@@ -31,7 +31,7 @@ Useful links: [Homepage](https://www.celitech.com) | [Support email](mailto:supp
31
31
 
32
32
  ## Supported Language Versions<a id="supported-language-versions"></a>
33
33
 
34
- This SDK is compatible with the following versions: `Python >= 3.7`
34
+ This SDK is compatible with the following versions: `Python >= 3.9`
35
35
 
36
36
  ## Installation<a id="installation"></a>
37
37
 
@@ -1,11 +1,11 @@
1
- # Celitech Python SDK 2.0.4
1
+ # Celitech Python SDK 2.0.6
2
2
 
3
3
  Welcome to the Celitech SDK documentation. This guide will help you get started with integrating and using the Celitech SDK in your project.
4
4
 
5
5
  ## Versions
6
6
 
7
- - API version: `2.0.4`
8
- - SDK version: `2.0.4`
7
+ - API version: `2.0.6`
8
+ - SDK version: `2.0.6`
9
9
 
10
10
  ## About the API
11
11
 
@@ -32,7 +32,7 @@ Useful links: [Homepage](https://www.celitech.com) | [Support email](mailto:supp
32
32
 
33
33
  ## Supported Language Versions
34
34
 
35
- This SDK is compatible with the following versions: `Python >= 3.7`
35
+ This SDK is compatible with the following versions: `Python >= 3.9`
36
36
 
37
37
  ## Installation
38
38
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "celitech-sdk"
7
- version = "2.0.4"
7
+ version = "2.0.6"
8
8
  license = { text = "MIT" }
9
9
  description = """Welcome to the CELITECH API documentation!\n\nUseful links: [Homepage](https://www.celitech.com) | [Support email](mailto:support@celitech.com) | [Blog](https://www.celitech.com/blog/)\n"""
10
10
  readme = "PyPI_README.md"
@@ -1,5 +1,7 @@
1
+ from __future__ import annotations
1
2
  from pydantic import Field
2
3
  from typing import Optional
4
+ from typing import Any
3
5
  from .utils.base_error import BaseError
4
6
  from .utils.base_model import BaseModel
5
7
 
@@ -1,5 +1,7 @@
1
+ from __future__ import annotations
1
2
  from pydantic import Field
2
3
  from typing import Optional
4
+ from typing import Any
3
5
  from typing import Union
4
6
  from .utils.base_model import BaseModel
5
7
 
@@ -1,6 +1,8 @@
1
+ from __future__ import annotations
1
2
  from enum import Enum
2
3
  from pydantic import Field
3
4
  from typing import Optional
5
+ from typing import Any
4
6
  from .utils.base_model import BaseModel
5
7
 
6
8
 
@@ -42,7 +44,7 @@ class CreatePurchaseRequest(BaseModel):
42
44
 
43
45
  :param destination: ISO representation of the package's destination. Supports both ISO2 (e.g., 'FR') and ISO3 (e.g., 'FRA') country codes.
44
46
  :type destination: str
45
- :param data_limit_in_gb: Size of the package in GB. The available options are 0.5, 1, 2, 3, 5, 8, 20, 50GB
47
+ :param data_limit_in_gb: Size of the package in GB. The available options are 0.5, 1, 2, 3, 5, 8, 20, 50GB. Use `-1` to purchase an unlimited (date-based) package — provide `startDate`/`endDate` spanning 3 to 30 days.
46
48
  :type data_limit_in_gb: float
47
49
  :param start_date: Start date of the package's validity in the format 'yyyy-MM-dd'. This date can be set to the current day or any day within the next 12 months.
48
50
  :type start_date: str
@@ -70,7 +72,7 @@ class CreatePurchaseRequest(BaseModel):
70
72
  data_limit_in_gb: float = Field(
71
73
  alias="dataLimitInGB",
72
74
  serialization_alias="dataLimitInGB",
73
- description="Size of the package in GB. The available options are 0.5, 1, 2, 3, 5, 8, 20, 50GB",
75
+ description="Size of the package in GB. The available options are 0.5, 1, 2, 3, 5, 8, 20, 50GB. Use `-1` to purchase an unlimited (date-based) package — provide `startDate`/`endDate` spanning 3 to 30 days.",
74
76
  )
75
77
  start_date: str = Field(
76
78
  alias="startDate",
@@ -1,5 +1,7 @@
1
+ from __future__ import annotations
1
2
  from pydantic import Field
2
3
  from typing import Optional
4
+ from typing import Any
3
5
  from .utils.base_model import BaseModel
4
6
 
5
7
 
@@ -1,6 +1,8 @@
1
+ from __future__ import annotations
1
2
  from enum import Enum
2
3
  from pydantic import Field
3
4
  from typing import Optional
5
+ from typing import Any
4
6
  from .utils.base_model import BaseModel
5
7
 
6
8
 
@@ -44,13 +46,13 @@ class CreatePurchaseV2Request(BaseModel):
44
46
 
45
47
  :param destination: ISO representation of the package's destination. Supports both ISO2 (e.g., 'FR') and ISO3 (e.g., 'FRA') country codes.
46
48
  :type destination: str
47
- :param data_limit_in_gb: Size of the package in GB. The available options are 0.5, 1, 2, 3, 5, 8, 20, 50GB
49
+ :param data_limit_in_gb: Size of the package in GB. The available options are 0.5, 1, 2, 3, 5, 8, 20, 50GB. Use `-1` to purchase an unlimited (date-based) package — provide `startDate`/`endDate` spanning 3 to 30 days (`duration` is not supported for unlimited packages).
48
50
  :type data_limit_in_gb: float
49
51
  :param start_date: Start date of the package's validity in the format 'yyyy-MM-dd'. This date can be set to the current day or any day within the next 12 months., defaults to None
50
52
  :type start_date: str, optional
51
53
  :param end_date: End date of the package's validity in the format 'yyyy-MM-dd'. End date can be maximum 90 days after Start date., defaults to None
52
54
  :type end_date: str, optional
53
- :param duration: Duration of the package in days. Available values are 1, 2, 7, 14, 30, or 90. Either provide startDate/endDate or duration., defaults to None
55
+ :param duration: Duration of the package in days. Available values are 1, 2, 7, 14, 30, or 90. Either provide startDate/endDate or duration. Not supported for unlimited packages (`dataLimitInGB` = -1), which are date-based — provide startDate/endDate instead., defaults to None
54
56
  :type duration: float, optional
55
57
  :param quantity: Number of eSIMs to purchase.
56
58
  :type quantity: float
@@ -72,7 +74,7 @@ class CreatePurchaseV2Request(BaseModel):
72
74
  data_limit_in_gb: float = Field(
73
75
  alias="dataLimitInGB",
74
76
  serialization_alias="dataLimitInGB",
75
- description="Size of the package in GB. The available options are 0.5, 1, 2, 3, 5, 8, 20, 50GB",
77
+ description="Size of the package in GB. The available options are 0.5, 1, 2, 3, 5, 8, 20, 50GB. Use `-1` to purchase an unlimited (date-based) package — provide `startDate`/`endDate` spanning 3 to 30 days (`duration` is not supported for unlimited packages).",
76
78
  )
77
79
  start_date: Optional[str] = Field(
78
80
  alias="startDate",
@@ -88,7 +90,7 @@ class CreatePurchaseV2Request(BaseModel):
88
90
  )
89
91
  duration: Optional[float] = Field(
90
92
  default=None,
91
- description="Duration of the package in days. Available values are 1, 2, 7, 14, 30, or 90. Either provide startDate/endDate or duration.",
93
+ description="Duration of the package in days. Available values are 1, 2, 7, 14, 30, or 90. Either provide startDate/endDate or duration. Not supported for unlimited packages (`dataLimitInGB` = -1), which are date-based — provide startDate/endDate instead.",
92
94
  )
93
95
  quantity: float = Field(description="Number of eSIMs to purchase.", ge=1, le=5)
94
96
  email: Optional[str] = Field(
@@ -1,5 +1,7 @@
1
+ from __future__ import annotations
1
2
  from pydantic import Field
2
3
  from typing import Optional
4
+ from typing import Any
3
5
  from typing import Union
4
6
  from .utils.base_model import BaseModel
5
7
 
@@ -1,5 +1,7 @@
1
+ from __future__ import annotations
1
2
  from pydantic import Field
2
3
  from typing import Optional
4
+ from typing import Any
3
5
  from .utils.base_model import BaseModel
4
6
 
5
7
 
@@ -1,5 +1,7 @@
1
+ from __future__ import annotations
1
2
  from pydantic import Field
2
3
  from typing import Optional
4
+ from typing import Any
3
5
  from .utils.base_model import BaseModel
4
6
 
5
7
 
@@ -1,6 +1,8 @@
1
+ from __future__ import annotations
1
2
  from typing import List
2
3
  from pydantic import Field
3
4
  from typing import Optional
5
+ from typing import Any
4
6
  from .utils.base_model import BaseModel
5
7
 
6
8
 
@@ -1,5 +1,7 @@
1
+ from __future__ import annotations
1
2
  from pydantic import Field
2
3
  from typing import Optional
4
+ from typing import Any
3
5
  from .utils.base_model import BaseModel
4
6
 
5
7
 
@@ -1,14 +1,16 @@
1
+ from __future__ import annotations
1
2
  from pydantic import Field
2
3
  from typing import Optional
4
+ from typing import Any
3
5
  from .utils.base_model import BaseModel
4
6
 
5
7
 
6
8
  class GetPurchaseConsumptionOkResponse(BaseModel):
7
9
  """GetPurchaseConsumptionOkResponse
8
10
 
9
- :param data_usage_remaining_in_bytes: Remaining balance of the package in bytes
11
+ :param data_usage_remaining_in_bytes: Remaining balance of the package in bytes. Returns `-1` for unlimited packages.
10
12
  :type data_usage_remaining_in_bytes: float
11
- :param data_usage_remaining_in_gb: Remaining balance of the package in GB
13
+ :param data_usage_remaining_in_gb: Remaining balance of the package in GB. Returns `-1` for unlimited packages.
12
14
  :type data_usage_remaining_in_gb: float
13
15
  :param status: Status of the connectivity, possible values are 'ACTIVE' or 'NOT_ACTIVE'
14
16
  :type status: str
@@ -17,12 +19,12 @@ class GetPurchaseConsumptionOkResponse(BaseModel):
17
19
  data_usage_remaining_in_bytes: float = Field(
18
20
  alias="dataUsageRemainingInBytes",
19
21
  serialization_alias="dataUsageRemainingInBytes",
20
- description="Remaining balance of the package in bytes",
22
+ description="Remaining balance of the package in bytes. Returns `-1` for unlimited packages.",
21
23
  )
22
24
  data_usage_remaining_in_gb: float = Field(
23
25
  alias="dataUsageRemainingInGB",
24
26
  serialization_alias="dataUsageRemainingInGB",
25
- description="Remaining balance of the package in GB",
27
+ description="Remaining balance of the package in GB. Returns `-1` for unlimited packages.",
26
28
  )
27
29
  status: str = Field(
28
30
  description="Status of the connectivity, possible values are 'ACTIVE' or 'NOT_ACTIVE'"
@@ -1,4 +1,6 @@
1
+ from __future__ import annotations
1
2
  from enum import Enum
3
+ from typing import Any
2
4
 
3
5
 
4
6
  class GrantType(str, Enum):
@@ -1,6 +1,8 @@
1
+ from __future__ import annotations
1
2
  from typing import List
2
3
  from pydantic import Field
3
4
  from typing import Optional
5
+ from typing import Any
4
6
  from .utils.base_model import BaseModel
5
7
 
6
8
 
@@ -1,6 +1,8 @@
1
+ from __future__ import annotations
1
2
  from typing import List
2
3
  from pydantic import Field
3
4
  from typing import Optional
5
+ from typing import Any
4
6
  from typing import Union
5
7
  from .utils.base_model import BaseModel
6
8
 
@@ -14,9 +16,9 @@ class Packages(BaseModel):
14
16
  :type destination: str
15
17
  :param destination_iso2: ISO2 representation of the package's destination.
16
18
  :type destination_iso2: str
17
- :param data_limit_in_bytes: Size of the package in Bytes
19
+ :param data_limit_in_bytes: Size of the package in Bytes. A value of `-1` indicates an unlimited package.
18
20
  :type data_limit_in_bytes: float
19
- :param data_limit_in_gb: Size of the package in GB
21
+ :param data_limit_in_gb: Size of the package in GB. A value of `-1` indicates an unlimited (date-based) package.
20
22
  :type data_limit_in_gb: float
21
23
  :param min_days: Min number of days for the package
22
24
  :type min_days: float
@@ -40,12 +42,12 @@ class Packages(BaseModel):
40
42
  data_limit_in_bytes: float = Field(
41
43
  alias="dataLimitInBytes",
42
44
  serialization_alias="dataLimitInBytes",
43
- description="Size of the package in Bytes",
45
+ description="Size of the package in Bytes. A value of `-1` indicates an unlimited package.",
44
46
  )
45
47
  data_limit_in_gb: float = Field(
46
48
  alias="dataLimitInGB",
47
49
  serialization_alias="dataLimitInGB",
48
- description="Size of the package in GB",
50
+ description="Size of the package in GB. A value of `-1` indicates an unlimited (date-based) package.",
49
51
  )
50
52
  min_days: float = Field(
51
53
  alias="minDays",
@@ -1,6 +1,8 @@
1
+ from __future__ import annotations
1
2
  from typing import List
2
3
  from pydantic import Field
3
4
  from typing import Optional
5
+ from typing import Any
4
6
  from typing import Union
5
7
  from .utils.base_model import BaseModel
6
8
 
@@ -10,9 +12,9 @@ class Package(BaseModel):
10
12
 
11
13
  :param id_: ID of the package
12
14
  :type id_: str
13
- :param data_limit_in_bytes: Size of the package in Bytes
15
+ :param data_limit_in_bytes: Size of the package in Bytes. A value of `-1` indicates an unlimited package.
14
16
  :type data_limit_in_bytes: float
15
- :param data_limit_in_gb: Size of the package in GB
17
+ :param data_limit_in_gb: Size of the package in GB. A value of `-1` indicates an unlimited (date-based) package.
16
18
  :type data_limit_in_gb: float
17
19
  :param destination: ISO3 representation of the package's destination.
18
20
  :type destination: str
@@ -30,12 +32,12 @@ class Package(BaseModel):
30
32
  data_limit_in_bytes: float = Field(
31
33
  alias="dataLimitInBytes",
32
34
  serialization_alias="dataLimitInBytes",
33
- description="Size of the package in Bytes",
35
+ description="Size of the package in Bytes. A value of `-1` indicates an unlimited package.",
34
36
  )
35
37
  data_limit_in_gb: float = Field(
36
38
  alias="dataLimitInGB",
37
39
  serialization_alias="dataLimitInGB",
38
- description="Size of the package in GB",
40
+ description="Size of the package in GB. A value of `-1` indicates an unlimited (date-based) package.",
39
41
  )
40
42
  destination: str = Field(
41
43
  description="ISO3 representation of the package's destination."
@@ -76,7 +78,7 @@ class Purchases(BaseModel):
76
78
  :type start_date: str
77
79
  :param end_date: End date of the package's validity in the format 'yyyy-MM-ddThh:mm:ssZZ'
78
80
  :type end_date: str
79
- :param duration: Duration of the package in days. Possible values are 1, 2, 7, 14, 30, or 90., defaults to None
81
+ :param duration: Duration of the package in days. Possible values are 1, 2, 7, 14, 30, or 90. `null` for unlimited (date-based) packages., defaults to None
80
82
  :type duration: float, optional
81
83
  :param created_date: Creation date of the purchase in the format 'yyyy-MM-ddThh:mm:ssZZ'
82
84
  :type created_date: str
@@ -113,7 +115,7 @@ class Purchases(BaseModel):
113
115
  )
114
116
  duration: Optional[float] = Field(
115
117
  default=None,
116
- description="Duration of the package in days. Possible values are 1, 2, 7, 14, 30, or 90.",
118
+ description="Duration of the package in days. Possible values are 1, 2, 7, 14, 30, or 90. `null` for unlimited (date-based) packages.",
117
119
  )
118
120
  created_date: str = Field(
119
121
  alias="createdDate",
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
  from pydantic import Field
3
3
  from typing import Optional
4
+ from typing import Any
4
5
  from .utils.base_model import BaseModel
5
6
  from .grant_type import GrantType
6
7
 
@@ -1,5 +1,7 @@
1
+ from __future__ import annotations
1
2
  from pydantic import Field
2
3
  from typing import Optional
4
+ from typing import Any
3
5
  from typing import Union
4
6
  from .utils.base_model import BaseModel
5
7
 
@@ -1,5 +1,7 @@
1
+ from __future__ import annotations
1
2
  from pydantic import Field
2
3
  from typing import Optional
4
+ from typing import Any
3
5
  from .utils.base_model import BaseModel
4
6
 
5
7
 
@@ -1,5 +1,7 @@
1
+ from __future__ import annotations
1
2
  from pydantic import Field
2
3
  from typing import Optional
4
+ from typing import Any
3
5
  from typing import Union
4
6
  from .utils.base_model import BaseModel
5
7
 
@@ -1,5 +1,7 @@
1
+ from __future__ import annotations
1
2
  from pydantic import Field
2
3
  from typing import Optional
4
+ from typing import Any
3
5
  from .utils.base_model import BaseModel
4
6
 
5
7
 
@@ -8,13 +10,13 @@ class TopUpEsimRequest(BaseModel):
8
10
 
9
11
  :param iccid: ID of the eSIM
10
12
  :type iccid: str
11
- :param data_limit_in_gb: Size of the package in GB. The available options are 0.5, 1, 2, 3, 5, 8, 20, 50GB
13
+ :param data_limit_in_gb: Size of the package in GB. The available options are 0.5, 1, 2, 3, 5, 8, 20, 50GB. Use `-1` to top up with an unlimited (date-based) package — provide `startDate`/`endDate` spanning 3 to 30 days (`duration` is not supported for unlimited packages).
12
14
  :type data_limit_in_gb: float
13
15
  :param start_date: Start date of the package's validity in the format 'yyyy-MM-dd'. This date can be set to the current day or any day within the next 12 months., defaults to None
14
16
  :type start_date: str, optional
15
17
  :param end_date: End date of the package's validity in the format 'yyyy-MM-dd'. End date can be maximum 90 days after Start date., defaults to None
16
18
  :type end_date: str, optional
17
- :param duration: Duration of the package in days. Available values are 1, 2, 7, 14, 30, or 90. Either provide startDate/endDate or duration., defaults to None
19
+ :param duration: Duration of the package in days. Available values are 1, 2, 7, 14, 30, or 90. Either provide startDate/endDate or duration. Not supported for unlimited packages (`dataLimitInGB` = -1), which are date-based — provide startDate/endDate instead., defaults to None
18
20
  :type duration: float, optional
19
21
  :param email: Email address where the purchase confirmation email will be sent (excluding QR Code & activation steps)., defaults to None
20
22
  :type email: str, optional
@@ -32,7 +34,7 @@ class TopUpEsimRequest(BaseModel):
32
34
  data_limit_in_gb: float = Field(
33
35
  alias="dataLimitInGB",
34
36
  serialization_alias="dataLimitInGB",
35
- description="Size of the package in GB. The available options are 0.5, 1, 2, 3, 5, 8, 20, 50GB",
37
+ description="Size of the package in GB. The available options are 0.5, 1, 2, 3, 5, 8, 20, 50GB. Use `-1` to top up with an unlimited (date-based) package — provide `startDate`/`endDate` spanning 3 to 30 days (`duration` is not supported for unlimited packages).",
36
38
  )
37
39
  start_date: Optional[str] = Field(
38
40
  alias="startDate",
@@ -48,7 +50,7 @@ class TopUpEsimRequest(BaseModel):
48
50
  )
49
51
  duration: Optional[float] = Field(
50
52
  default=None,
51
- description="Duration of the package in days. Available values are 1, 2, 7, 14, 30, or 90. Either provide startDate/endDate or duration.",
53
+ description="Duration of the package in days. Available values are 1, 2, 7, 14, 30, or 90. Either provide startDate/endDate or duration. Not supported for unlimited packages (`dataLimitInGB` = -1), which are date-based — provide startDate/endDate instead.",
52
54
  )
53
55
  email: Optional[str] = Field(
54
56
  default=None,
@@ -1,5 +1,7 @@
1
+ from __future__ import annotations
1
2
  from pydantic import Field
2
3
  from typing import Optional
4
+ from typing import Any
3
5
  from .utils.base_error import BaseError
4
6
  from .utils.base_model import BaseModel
5
7
 
@@ -24,6 +24,14 @@ class BaseModel(PydanticBaseModel):
24
24
  populate_by_name=True,
25
25
  # Arbitrary types allowed (for flexibility with custom types)
26
26
  arbitrary_types_allowed=False,
27
+ # Validate `Field(pattern=...)` constraints with Python's `re` engine
28
+ # instead of Pydantic's default Rust `regex` engine. The Rust engine
29
+ # rejects ALL look-around (`(?=…)`, `(?!…)`, `(?<=…)`, `(?<!…)`) with
30
+ # `SchemaError: regex parse error … look-around … is not supported`,
31
+ # crashing model import. OpenAPI `pattern`s frequently use look-ahead;
32
+ # Python's `re` supports it. Patterns are already normalised for `re`
33
+ # compatibility by translateRegexForPython at generation time.
34
+ regex_engine="python-re",
27
35
  )
28
36
 
29
37
  def model_dump_original(self, **kwargs: Any) -> Dict[str, Any]:
@@ -147,12 +147,26 @@ class HttpHandler(BaseHandler):
147
147
  :rtype: dict
148
148
  """
149
149
  headers = request.headers or {}
150
+
151
+ # No body was set on the request (the operation declares no requestBody).
152
+ # Sending an empty JSON payload would force a Content-Type the endpoint
153
+ # never advertises, which strict servers reject with HTTP 415.
154
+ if request.body is None:
155
+ return {}
156
+
150
157
  data = request.body or {}
151
158
  content_type = headers.get("Content-Type", "application/json")
152
159
 
153
160
  if request.method == "GET" and not data:
154
161
  return {}
155
162
 
163
+ # Raw binary bodies (e.g. application/octet-stream, file uploads) must be
164
+ # sent as-is. Routing them through `json=` crashes with
165
+ # "TypeError: Object of type bytes is not JSON serializable", regardless
166
+ # of what Content-Type the request defaulted to.
167
+ if isinstance(data, (bytes, bytearray)):
168
+ return {"data": data}
169
+
156
170
  if content_type.startswith("application/") and "json" in content_type:
157
171
  return {"json": data}
158
172
 
@@ -45,7 +45,7 @@ class Serializer:
45
45
  self.errors: dict[int, ApiError] = {}
46
46
  self.config: Optional["SdkConfig"] = config
47
47
 
48
- self.headers["User-Agent"] = "postman-codegen/1.5.0 celitech-sdk/2.0.4 (python)"
48
+ self.headers["User-Agent"] = "postman-codegen/1.7.0 celitech-sdk/2.0.6 (python)"
49
49
 
50
50
  # Apply default headers
51
51
  for header in default_headers:
@@ -32,6 +32,9 @@ def extract_original_data(data: Any) -> Any:
32
32
  if issubclass(data_type, Enum):
33
33
  return data.value
34
34
 
35
+ if issubclass(data_type, dict):
36
+ return {key: extract_original_data(value) for key, value in data.items()}
37
+
35
38
  if issubclass(data_type, list):
36
39
  return [extract_original_data(item) for item in data]
37
40
 
@@ -1,4 +1,4 @@
1
- from typing import Awaitable, Optional, Union
1
+ from typing import Awaitable, Optional, Any, Union
2
2
  from .utils.to_async import to_async
3
3
  from ..destinations import DestinationsService
4
4
  from ...net.sdk_config import SdkConfig
@@ -1,4 +1,4 @@
1
- from typing import Awaitable, Optional, Union
1
+ from typing import Awaitable, Optional, Any, Union
2
2
  from .utils.to_async import to_async
3
3
  from ..e_sim import ESimService
4
4
  from ...net.sdk_config import SdkConfig
@@ -1,4 +1,4 @@
1
- from typing import Awaitable, Optional, Union
1
+ from typing import Awaitable, Optional, Any, Union
2
2
  from .utils.to_async import to_async
3
3
  from ..i_frame import IFrameService
4
4
  from ...net.sdk_config import SdkConfig
@@ -1,4 +1,4 @@
1
- from typing import Awaitable, Optional
1
+ from typing import Awaitable, Optional, Any
2
2
  from .utils.to_async import to_async
3
3
  from ..o_auth import OAuthService
4
4
  from ...net.sdk_config import SdkConfig
@@ -1,4 +1,4 @@
1
- from typing import Awaitable, Optional, Union
1
+ from typing import Awaitable, Optional, Any, Union
2
2
  from .utils.to_async import to_async
3
3
  from ..packages import PackagesService
4
4
  from ...net.sdk_config import SdkConfig
@@ -14,22 +14,26 @@ class PackagesServiceAsync(PackagesService):
14
14
  def list_packages(
15
15
  self,
16
16
  destination: str = SENTINEL,
17
+ data_limit_in_gb: float = SENTINEL,
17
18
  start_date: str = SENTINEL,
18
19
  end_date: str = SENTINEL,
19
20
  after_cursor: str = SENTINEL,
20
21
  limit: float = SENTINEL,
21
22
  start_time: int = SENTINEL,
22
23
  end_time: int = SENTINEL,
24
+ include_unlimited: bool = SENTINEL,
23
25
  *,
24
26
  request_config: Optional[SdkConfig] = None,
25
27
  ) -> Awaitable[ListPackagesOkResponse]:
26
28
  return to_async(super().list_packages)(
27
29
  destination,
30
+ data_limit_in_gb,
28
31
  start_date,
29
32
  end_date,
30
33
  after_cursor,
31
34
  limit,
32
35
  start_time,
33
36
  end_time,
37
+ include_unlimited,
34
38
  request_config=request_config,
35
39
  )
@@ -1,4 +1,4 @@
1
- from typing import Awaitable, Optional, List, Union
1
+ from typing import Awaitable, Optional, Any, List, Union
2
2
  from .utils.to_async import to_async
3
3
  from ..purchases import PurchasesService
4
4
  from ...net.sdk_config import SdkConfig
@@ -61,4 +61,8 @@ class DestinationsService(BaseService):
61
61
  )
62
62
 
63
63
  response, status, _ = self.send_request(serialized_request)
64
- return ListDestinationsOkResponse.model_validate(response)
64
+ return (
65
+ None
66
+ if response in (b"", "")
67
+ else ListDestinationsOkResponse.model_validate(response)
68
+ )
@@ -94,7 +94,11 @@ class ESimService(BaseService):
94
94
  )
95
95
 
96
96
  response, status, _ = self.send_request(serialized_request)
97
- return GetEsimOkResponse.model_validate(response)
97
+ return (
98
+ None
99
+ if response in (b"", "")
100
+ else GetEsimOkResponse.model_validate(response)
101
+ )
98
102
 
99
103
  @cast_models
100
104
  def get_esim_device(
@@ -132,7 +136,11 @@ class ESimService(BaseService):
132
136
  )
133
137
 
134
138
  response, status, _ = self.send_request(serialized_request)
135
- return GetEsimDeviceOkResponse.model_validate(response)
139
+ return (
140
+ None
141
+ if response in (b"", "")
142
+ else GetEsimDeviceOkResponse.model_validate(response)
143
+ )
136
144
 
137
145
  @cast_models
138
146
  def get_esim_history(
@@ -170,4 +178,8 @@ class ESimService(BaseService):
170
178
  )
171
179
 
172
180
  response, status, _ = self.send_request(serialized_request)
173
- return GetEsimHistoryOkResponse.model_validate(response)
181
+ return (
182
+ None
183
+ if response in (b"", "")
184
+ else GetEsimHistoryOkResponse.model_validate(response)
185
+ )
@@ -57,4 +57,6 @@ class IFrameService(BaseService):
57
57
  )
58
58
 
59
59
  response, status, _ = self.send_request(serialized_request)
60
- return TokenOkResponse.model_validate(response)
60
+ return (
61
+ None if response in (b"", "") else TokenOkResponse.model_validate(response)
62
+ )
@@ -66,4 +66,8 @@ class OAuthService(BaseService):
66
66
  )
67
67
 
68
68
  response, _, _ = self.send_request(serialized_request)
69
- return OAuthTokenResponse.model_validate(response)
69
+ return (
70
+ None
71
+ if response in (b"", "")
72
+ else OAuthTokenResponse.model_validate(response)
73
+ )
@@ -35,12 +35,14 @@ class PackagesService(BaseService):
35
35
  def list_packages(
36
36
  self,
37
37
  destination: str = SENTINEL,
38
+ data_limit_in_gb: float = SENTINEL,
38
39
  start_date: str = SENTINEL,
39
40
  end_date: str = SENTINEL,
40
41
  after_cursor: str = SENTINEL,
41
42
  limit: float = SENTINEL,
42
43
  start_time: int = SENTINEL,
43
44
  end_time: int = SENTINEL,
45
+ include_unlimited: bool = SENTINEL,
44
46
  *,
45
47
  request_config: Optional[SdkConfig] = None,
46
48
  ) -> ListPackagesOkResponse:
@@ -48,6 +50,8 @@ class PackagesService(BaseService):
48
50
 
49
51
  :param destination: ISO representation of the package's destination. Supports both ISO2 (e.g., 'FR') and ISO3 (e.g., 'FRA') country codes., defaults to None
50
52
  :type destination: str, optional
53
+ :param data_limit_in_gb: Filter packages by data limit in GB. When provided, only packages with this exact data limit are returned. Use `-1` together with `includeUnlimited=true` to return only unlimited packages. A value of `0` is ignored., defaults to None
54
+ :type data_limit_in_gb: float, optional
51
55
  :param start_date: Start date of the package's validity in the format 'yyyy-MM-dd'. This date can be set to the current day or any day within the next 12 months., defaults to None
52
56
  :type start_date: str, optional
53
57
  :param end_date: End date of the package's validity in the format 'yyyy-MM-dd'. End date can be maximum 90 days after Start date., defaults to None
@@ -60,6 +64,8 @@ class PackagesService(BaseService):
60
64
  :type start_time: int, optional
61
65
  :param end_time: Epoch value representing the end time of the package's validity. End time can be maximum 90 days after Start time, defaults to None
62
66
  :type end_time: int, optional
67
+ :param include_unlimited: Whether to include unlimited (date-based) packages in the results. Unlimited packages are excluded by default; set this to `true` to include them. An unlimited package has `dataLimitInGB` and `dataLimitInBytes` equal to `-1`, and is offered for 3 to 30 days with `minDays` equal to `maxDays`., defaults to None
68
+ :type include_unlimited: bool, optional
63
69
  ...
64
70
  :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
65
71
  ...
@@ -68,12 +74,14 @@ class PackagesService(BaseService):
68
74
  """
69
75
 
70
76
  Validator(str).is_optional().validate(destination)
77
+ Validator(float).is_optional().validate(data_limit_in_gb)
71
78
  Validator(str).is_optional().validate(start_date)
72
79
  Validator(str).is_optional().validate(end_date)
73
80
  Validator(str).is_optional().validate(after_cursor)
74
81
  Validator(float).is_optional().validate(limit)
75
82
  Validator(int).is_optional().validate(start_time)
76
83
  Validator(int).is_optional().validate(end_time)
84
+ Validator(bool).is_optional().validate(include_unlimited)
77
85
 
78
86
  resolved_config = self._get_resolved_config(
79
87
  self._list_packages_config, request_config
@@ -86,12 +94,14 @@ class PackagesService(BaseService):
86
94
  resolved_config,
87
95
  )
88
96
  .add_query("destination", destination)
97
+ .add_query("dataLimitInGB", data_limit_in_gb)
89
98
  .add_query("startDate", start_date)
90
99
  .add_query("endDate", end_date)
91
100
  .add_query("afterCursor", after_cursor)
92
101
  .add_query("limit", limit)
93
102
  .add_query("startTime", start_time)
94
103
  .add_query("endTime", end_time)
104
+ .add_query("includeUnlimited", include_unlimited)
95
105
  .add_error(400, BadRequest)
96
106
  .add_error(401, Unauthorized)
97
107
  .serialize()
@@ -100,4 +110,8 @@ class PackagesService(BaseService):
100
110
  )
101
111
 
102
112
  response, status, _ = self.send_request(serialized_request)
103
- return ListPackagesOkResponse.model_validate(response)
113
+ return (
114
+ None
115
+ if response in (b"", "")
116
+ else ListPackagesOkResponse.model_validate(response)
117
+ )
@@ -138,7 +138,10 @@ class PurchasesService(BaseService):
138
138
  )
139
139
 
140
140
  response, status, _ = self.send_request(serialized_request)
141
- return [CreatePurchaseV2OkResponse.model_validate(item) for item in response]
141
+ return [
142
+ CreatePurchaseV2OkResponse.model_validate(item)
143
+ for item in (response if isinstance(response, list) else [])
144
+ ]
142
145
 
143
146
  @cast_models
144
147
  def list_purchases(
@@ -224,7 +227,11 @@ class PurchasesService(BaseService):
224
227
  )
225
228
 
226
229
  response, status, _ = self.send_request(serialized_request)
227
- return ListPurchasesOkResponse.model_validate(response)
230
+ return (
231
+ None
232
+ if response in (b"", "")
233
+ else ListPurchasesOkResponse.model_validate(response)
234
+ )
228
235
 
229
236
  @cast_models
230
237
  def create_purchase(
@@ -265,7 +272,11 @@ class PurchasesService(BaseService):
265
272
  )
266
273
 
267
274
  response, status, _ = self.send_request(serialized_request)
268
- return CreatePurchaseOkResponse.model_validate(response)
275
+ return (
276
+ None
277
+ if response in (b"", "")
278
+ else CreatePurchaseOkResponse.model_validate(response)
279
+ )
269
280
 
270
281
  @cast_models
271
282
  def top_up_esim(
@@ -306,7 +317,11 @@ class PurchasesService(BaseService):
306
317
  )
307
318
 
308
319
  response, status, _ = self.send_request(serialized_request)
309
- return TopUpEsimOkResponse.model_validate(response)
320
+ return (
321
+ None
322
+ if response in (b"", "")
323
+ else TopUpEsimOkResponse.model_validate(response)
324
+ )
310
325
 
311
326
  @cast_models
312
327
  def edit_purchase(
@@ -347,7 +362,11 @@ class PurchasesService(BaseService):
347
362
  )
348
363
 
349
364
  response, status, _ = self.send_request(serialized_request)
350
- return EditPurchaseOkResponse.model_validate(response)
365
+ return (
366
+ None
367
+ if response in (b"", "")
368
+ else EditPurchaseOkResponse.model_validate(response)
369
+ )
351
370
 
352
371
  @cast_models
353
372
  def get_purchase_consumption(
@@ -385,4 +404,8 @@ class PurchasesService(BaseService):
385
404
  )
386
405
 
387
406
  response, status, _ = self.send_request(serialized_request)
388
- return GetPurchaseConsumptionOkResponse.model_validate(response)
407
+ return (
408
+ None
409
+ if response in (b"", "")
410
+ else GetPurchaseConsumptionOkResponse.model_validate(response)
411
+ )
@@ -1,6 +1,8 @@
1
1
  import re
2
2
  import operator
3
- from typing import Union, Any, Type, Pattern, get_args
3
+ from enum import Enum
4
+ from inspect import isclass
5
+ from typing import Union, Any, Type, Pattern, get_args, get_origin
4
6
  from ...models.utils.sentinel import was_value_set
5
7
  from ...models.utils.one_of_base_model import OneOfBaseModel
6
8
 
@@ -194,8 +196,41 @@ class Validator:
194
196
  :param Any value: The input that needs to be checked
195
197
  :raises ValueError: If the value does not match the expected type.
196
198
  """
197
- is_numeric = self._type is float and isinstance(value, int)
198
- if isinstance(value, self._type) or is_numeric:
199
+ # `Any` is a typing special form, not a runtime class — passing it
200
+ # to isinstance() raises TypeError. Treat Any-typed fields as
201
+ # "always match" so models with `field: Any` validate without
202
+ # crashing on every snippet that touches them.
203
+ if self._type is Any:
204
+ return True
205
+ # Subscripted generics (e.g. List[str], Dict[str, int]) cannot be passed
206
+ # to isinstance() — it raises "TypeError: Subscripted generics cannot be
207
+ # used with class and instance checks". Fall back to the runtime origin
208
+ # class (list, dict, ...) for the check.
209
+ check_type = get_origin(self._type) or self._type
210
+ if check_type is Any:
211
+ return True
212
+ # A subscripted Union (e.g. a list of `Union[str, int]`) reaches here as
213
+ # `typing.Union`, which also can't be passed to isinstance(). Match the
214
+ # value against any of the union's member types instead.
215
+ if check_type is Union:
216
+ return any(
217
+ Validator(arg)._match_type(value) for arg in get_args(self._type)
218
+ )
219
+ # Enum-typed fields accept either an enum member or any of the enum's
220
+ # underlying values (e.g. the raw string a snippet passes), so a plain
221
+ # value isn't rejected with "Invalid type: Expected <enum ...>".
222
+ if isclass(check_type) and issubclass(check_type, Enum):
223
+ if isinstance(value, check_type):
224
+ return True
225
+ try:
226
+ check_type(value)
227
+ return True
228
+ except (ValueError, TypeError):
229
+ # ValueError: not a valid enum value. TypeError: unhashable
230
+ # value (e.g. a list/dict) can't be looked up in the enum.
231
+ return False
232
+ is_numeric = check_type is float and isinstance(value, int)
233
+ if isinstance(value, check_type) or is_numeric:
199
234
  return True
200
235
  return False
201
236
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: celitech-sdk
3
- Version: 2.0.4
3
+ Version: 2.0.6
4
4
  Summary: Welcome to the CELITECH API documentation!
5
5
  License: MIT
6
6
  Project-URL: Repository, https://github.com/Celitech/CelitechSDKPython
@@ -11,14 +11,14 @@ Requires-Dist: requests>=2.31.0
11
11
  Requires-Dist: pydantic<3.0.0,>=2.0.0
12
12
  Dynamic: license-file
13
13
 
14
- # Celitech Python SDK 2.0.4<a id="celitech-python-sdk-204"></a>
14
+ # Celitech Python SDK 2.0.6<a id="celitech-python-sdk-206"></a>
15
15
 
16
16
  Welcome to the Celitech SDK documentation. This guide will help you get started with integrating and using the Celitech SDK in your project.
17
17
 
18
18
  ## Versions<a id="versions"></a>
19
19
 
20
- - API version: `2.0.4`
21
- - SDK version: `2.0.4`
20
+ - API version: `2.0.6`
21
+ - SDK version: `2.0.6`
22
22
 
23
23
  ## About the API<a id="about-the-api"></a>
24
24
 
@@ -44,7 +44,7 @@ Useful links: [Homepage](https://www.celitech.com) | [Support email](mailto:supp
44
44
 
45
45
  ## Supported Language Versions<a id="supported-language-versions"></a>
46
46
 
47
- This SDK is compatible with the following versions: `Python >= 3.7`
47
+ This SDK is compatible with the following versions: `Python >= 3.9`
48
48
 
49
49
  ## Installation<a id="installation"></a>
50
50
 
File without changes
File without changes