stigg-api-client-v2 0.693.0__py3-none-any.whl → 5.9.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.
- stigg/_edge_utils.py +58 -0
- stigg/client.py +97 -21
- stigg/generated/__init__.py +734 -42
- stigg/generated/apply_subscription.py +4 -12
- stigg/generated/archive_customer.py +2 -3
- stigg/generated/async_base_client.py +187 -29
- stigg/generated/async_client.py +3659 -620
- stigg/generated/base_client.py +144 -23
- stigg/generated/base_model.py +16 -47
- stigg/generated/cancel_subscription.py +2 -3
- stigg/generated/cancel_subscription_updates.py +1 -4
- stigg/generated/client.py +3661 -616
- stigg/generated/create_payment_session.py +20 -0
- stigg/generated/create_subscription.py +2 -3
- stigg/generated/delegate_subscription_to_customer.py +22 -0
- stigg/generated/detach_customer_payment_method.py +20 -0
- stigg/generated/enums.py +426 -7
- stigg/generated/estimate_subscription.py +2 -3
- stigg/generated/estimate_subscription_update.py +2 -3
- stigg/generated/exceptions.py +9 -5
- stigg/generated/fragments.py +1864 -701
- stigg/generated/get_active_subscriptions.py +2 -3
- stigg/generated/get_active_subscriptions_list.py +22 -0
- stigg/generated/get_checkout_state.py +2 -3
- stigg/generated/get_coupons.py +4 -5
- stigg/generated/get_credit_balance.py +20 -0
- stigg/generated/get_credit_grants.py +36 -0
- stigg/generated/get_credit_ledger.py +25 -0
- stigg/generated/get_credit_usage.py +18 -0
- stigg/generated/get_customer_by_id.py +2 -3
- stigg/generated/get_customer_portal_by_ref_id.py +2 -3
- stigg/generated/get_customer_statistics.py +2 -3
- stigg/generated/get_entitlement.py +2 -3
- stigg/generated/get_entitlements.py +2 -3
- stigg/generated/get_entitlements_state.py +31 -0
- stigg/generated/get_mock_paywall.py +3 -5
- stigg/generated/get_paywall.py +2 -3
- stigg/generated/get_products.py +4 -5
- stigg/generated/get_sdk_configuration.py +3 -3
- stigg/generated/get_subscription.py +18 -0
- stigg/generated/get_subscriptions.py +35 -0
- stigg/generated/get_usage_history.py +2 -3
- stigg/generated/get_usage_history_v_2.py +18 -0
- stigg/generated/grant_credits.py +20 -0
- stigg/generated/grant_promotional_entitlements.py +2 -3
- stigg/generated/grant_promotional_entitlements_group.py +24 -0
- stigg/generated/import_customer.py +2 -3
- stigg/generated/import_customer_bulk.py +1 -4
- stigg/generated/import_subscriptions_bulk.py +1 -4
- stigg/generated/input_types.py +3871 -1878
- stigg/generated/migrate_subscription_to_latest.py +2 -3
- stigg/generated/preview_next_invoice.py +20 -0
- stigg/generated/preview_subscription.py +2 -3
- stigg/generated/provision_customer.py +4 -22
- stigg/generated/provision_subscription.py +4 -15
- stigg/generated/report_entitlement_check_requested.py +1 -4
- stigg/generated/report_event.py +1 -4
- stigg/generated/report_usage.py +6 -13
- stigg/generated/report_usage_bulk.py +22 -0
- stigg/generated/revoke_promotional_entitlement.py +5 -4
- stigg/generated/revoke_promotional_entitlements_group.py +24 -0
- stigg/generated/transfer_subscription.py +2 -3
- stigg/generated/transfer_subscription_to_resource.py +22 -0
- stigg/generated/unarchive_customer.py +2 -3
- stigg/generated/unlink_promotional_entitlements_group.py +24 -0
- stigg/generated/update_customer.py +2 -3
- stigg/generated/update_subscription.py +2 -3
- stigg/generated/void_credit_grant.py +18 -0
- {stigg_api_client_v2-0.693.0.dist-info → stigg_api_client_v2-5.9.0.dist-info}/METADATA +3 -4
- stigg_api_client_v2-5.9.0.dist-info/RECORD +73 -0
- stigg/edge_utils.py +0 -28
- stigg/generated/scalars.py +0 -6
- stigg_api_client_v2-0.693.0.dist-info/RECORD +0 -54
- {stigg_api_client_v2-0.693.0.dist-info → stigg_api_client_v2-5.9.0.dist-info}/LICENSE +0 -0
- {stigg_api_client_v2-0.693.0.dist-info → stigg_api_client_v2-5.9.0.dist-info}/WHEEL +0 -0
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
# Generated by ariadne-codegen
|
|
1
|
+
# Generated by ariadne-codegen
|
|
2
2
|
# Source: operations.graphql
|
|
3
3
|
|
|
4
|
-
from typing import Optional
|
|
5
|
-
|
|
6
4
|
from pydantic import Field
|
|
7
5
|
|
|
8
6
|
from .base_model import BaseModel
|
|
9
|
-
from .fragments import
|
|
7
|
+
from .fragments import ApplySubscriptionFragment
|
|
10
8
|
|
|
11
9
|
|
|
12
10
|
class ApplySubscription(BaseModel):
|
|
@@ -15,14 +13,8 @@ class ApplySubscription(BaseModel):
|
|
|
15
13
|
)
|
|
16
14
|
|
|
17
15
|
|
|
18
|
-
class ApplySubscriptionApplySubscription(
|
|
19
|
-
subscription: Optional["ApplySubscriptionApplySubscriptionSubscription"]
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
class ApplySubscriptionApplySubscriptionSubscription(SubscriptionFragment):
|
|
16
|
+
class ApplySubscriptionApplySubscription(ApplySubscriptionFragment):
|
|
23
17
|
pass
|
|
24
18
|
|
|
25
19
|
|
|
26
|
-
ApplySubscription.
|
|
27
|
-
ApplySubscriptionApplySubscription.update_forward_refs()
|
|
28
|
-
ApplySubscriptionApplySubscriptionSubscription.update_forward_refs()
|
|
20
|
+
ApplySubscription.model_rebuild()
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Generated by ariadne-codegen
|
|
1
|
+
# Generated by ariadne-codegen
|
|
2
2
|
# Source: operations.graphql
|
|
3
3
|
|
|
4
4
|
from pydantic import Field
|
|
@@ -14,5 +14,4 @@ class ArchiveCustomerArchiveCustomer(BaseModel):
|
|
|
14
14
|
customer_id: str = Field(alias="customerId")
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
ArchiveCustomer.
|
|
18
|
-
ArchiveCustomerArchiveCustomer.update_forward_refs()
|
|
17
|
+
ArchiveCustomer.model_rebuild()
|
|
@@ -1,26 +1,32 @@
|
|
|
1
|
-
# Generated by ariadne-codegen
|
|
1
|
+
# Generated by ariadne-codegen
|
|
2
2
|
|
|
3
3
|
import enum
|
|
4
4
|
import json
|
|
5
|
-
from typing import Any, AsyncIterator, Dict, Optional, TypeVar, cast
|
|
5
|
+
from typing import IO, Any, AsyncIterator, Dict, List, Optional, Tuple, TypeVar, cast
|
|
6
6
|
from uuid import uuid4
|
|
7
7
|
|
|
8
8
|
import httpx
|
|
9
9
|
from pydantic import BaseModel
|
|
10
|
-
from
|
|
10
|
+
from pydantic_core import to_jsonable_python
|
|
11
11
|
|
|
12
|
-
from .base_model import UNSET
|
|
12
|
+
from .base_model import UNSET, Upload
|
|
13
13
|
from .exceptions import (
|
|
14
14
|
GraphQLClientGraphQLMultiError,
|
|
15
15
|
GraphQLClientHttpError,
|
|
16
16
|
GraphQLClientInvalidMessageFormat,
|
|
17
|
-
|
|
17
|
+
GraphQLClientInvalidResponseError,
|
|
18
18
|
)
|
|
19
19
|
|
|
20
20
|
try:
|
|
21
|
-
from websockets.client import
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
from websockets.client import ( # type: ignore[import-not-found,unused-ignore]
|
|
22
|
+
WebSocketClientProtocol,
|
|
23
|
+
connect as ws_connect,
|
|
24
|
+
)
|
|
25
|
+
from websockets.typing import ( # type: ignore[import-not-found,unused-ignore]
|
|
26
|
+
Data,
|
|
27
|
+
Origin,
|
|
28
|
+
Subprotocol,
|
|
29
|
+
)
|
|
24
30
|
except ImportError:
|
|
25
31
|
from contextlib import asynccontextmanager
|
|
26
32
|
|
|
@@ -29,10 +35,12 @@ except ImportError:
|
|
|
29
35
|
raise NotImplementedError("Subscriptions require 'websockets' package.")
|
|
30
36
|
yield # pylint: disable=unreachable
|
|
31
37
|
|
|
32
|
-
WebSocketClientProtocol = Any # type: ignore
|
|
33
|
-
Data = Any # type: ignore
|
|
34
|
-
Origin = Any # type: ignore
|
|
35
|
-
|
|
38
|
+
WebSocketClientProtocol = Any # type: ignore[misc,assignment,unused-ignore]
|
|
39
|
+
Data = Any # type: ignore[misc,assignment,unused-ignore]
|
|
40
|
+
Origin = Any # type: ignore[misc,assignment,unused-ignore]
|
|
41
|
+
|
|
42
|
+
def Subprotocol(*args, **kwargs): # type: ignore # pylint: disable=invalid-name
|
|
43
|
+
raise NotImplementedError("Subscriptions require 'websockets' package.")
|
|
36
44
|
|
|
37
45
|
|
|
38
46
|
Self = TypeVar("Self", bound="AsyncBaseClient")
|
|
@@ -67,6 +75,7 @@ class AsyncBaseClient:
|
|
|
67
75
|
self.http_client = (
|
|
68
76
|
http_client if http_client else httpx.AsyncClient(headers=headers)
|
|
69
77
|
)
|
|
78
|
+
|
|
70
79
|
self.ws_url = ws_url
|
|
71
80
|
self.ws_headers = ws_headers or {}
|
|
72
81
|
self.ws_origin = Origin(ws_origin) if ws_origin else None
|
|
@@ -84,13 +93,30 @@ class AsyncBaseClient:
|
|
|
84
93
|
await self.http_client.aclose()
|
|
85
94
|
|
|
86
95
|
async def execute(
|
|
87
|
-
self,
|
|
96
|
+
self,
|
|
97
|
+
query: str,
|
|
98
|
+
operation_name: Optional[str] = None,
|
|
99
|
+
variables: Optional[Dict[str, Any]] = None,
|
|
100
|
+
**kwargs: Any,
|
|
88
101
|
) -> httpx.Response:
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
102
|
+
processed_variables, files, files_map = self._process_variables(variables)
|
|
103
|
+
|
|
104
|
+
if files and files_map:
|
|
105
|
+
return await self._execute_multipart(
|
|
106
|
+
query=query,
|
|
107
|
+
operation_name=operation_name,
|
|
108
|
+
variables=processed_variables,
|
|
109
|
+
files=files,
|
|
110
|
+
files_map=files_map,
|
|
111
|
+
**kwargs,
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
return await self._execute_json(
|
|
115
|
+
query=query,
|
|
116
|
+
operation_name=operation_name,
|
|
117
|
+
variables=processed_variables,
|
|
118
|
+
**kwargs,
|
|
119
|
+
)
|
|
94
120
|
|
|
95
121
|
def get_data(self, response: httpx.Response) -> Dict[str, Any]:
|
|
96
122
|
if not response.is_success:
|
|
@@ -101,12 +127,14 @@ class AsyncBaseClient:
|
|
|
101
127
|
try:
|
|
102
128
|
response_json = response.json()
|
|
103
129
|
except ValueError as exc:
|
|
104
|
-
raise
|
|
130
|
+
raise GraphQLClientInvalidResponseError(response=response) from exc
|
|
105
131
|
|
|
106
|
-
if (not isinstance(response_json, dict)) or (
|
|
107
|
-
|
|
132
|
+
if (not isinstance(response_json, dict)) or (
|
|
133
|
+
"data" not in response_json and "errors" not in response_json
|
|
134
|
+
):
|
|
135
|
+
raise GraphQLClientInvalidResponseError(response=response)
|
|
108
136
|
|
|
109
|
-
data = response_json
|
|
137
|
+
data = response_json.get("data")
|
|
110
138
|
errors = response_json.get("errors")
|
|
111
139
|
|
|
112
140
|
if errors:
|
|
@@ -114,23 +142,40 @@ class AsyncBaseClient:
|
|
|
114
142
|
errors_dicts=errors, data=data
|
|
115
143
|
)
|
|
116
144
|
|
|
117
|
-
return cast(
|
|
145
|
+
return cast(Dict[str, Any], data)
|
|
118
146
|
|
|
119
147
|
async def execute_ws(
|
|
120
|
-
self,
|
|
148
|
+
self,
|
|
149
|
+
query: str,
|
|
150
|
+
operation_name: Optional[str] = None,
|
|
151
|
+
variables: Optional[Dict[str, Any]] = None,
|
|
152
|
+
**kwargs: Any,
|
|
121
153
|
) -> AsyncIterator[Dict[str, Any]]:
|
|
154
|
+
headers = self.ws_headers.copy()
|
|
155
|
+
headers.update(kwargs.get("extra_headers", {}))
|
|
156
|
+
|
|
157
|
+
merged_kwargs: Dict[str, Any] = {"origin": self.ws_origin}
|
|
158
|
+
merged_kwargs.update(kwargs)
|
|
159
|
+
merged_kwargs["extra_headers"] = headers
|
|
160
|
+
|
|
122
161
|
operation_id = str(uuid4())
|
|
123
162
|
async with ws_connect(
|
|
124
163
|
self.ws_url,
|
|
125
164
|
subprotocols=[Subprotocol(GRAPHQL_TRANSPORT_WS)],
|
|
126
|
-
|
|
127
|
-
extra_headers=self.ws_headers,
|
|
165
|
+
**merged_kwargs,
|
|
128
166
|
) as websocket:
|
|
129
167
|
await self._send_connection_init(websocket)
|
|
168
|
+
# wait for connection_ack from server
|
|
169
|
+
await self._handle_ws_message(
|
|
170
|
+
await websocket.recv(),
|
|
171
|
+
websocket,
|
|
172
|
+
expected_type=GraphQLTransportWSMessageType.CONNECTION_ACK,
|
|
173
|
+
)
|
|
130
174
|
await self._send_subscribe(
|
|
131
175
|
websocket,
|
|
132
176
|
operation_id=operation_id,
|
|
133
177
|
query=query,
|
|
178
|
+
operation_name=operation_name,
|
|
134
179
|
variables=variables,
|
|
135
180
|
)
|
|
136
181
|
|
|
@@ -139,6 +184,17 @@ class AsyncBaseClient:
|
|
|
139
184
|
if data:
|
|
140
185
|
yield data
|
|
141
186
|
|
|
187
|
+
def _process_variables(
|
|
188
|
+
self, variables: Optional[Dict[str, Any]]
|
|
189
|
+
) -> Tuple[
|
|
190
|
+
Dict[str, Any], Dict[str, Tuple[str, IO[bytes], str]], Dict[str, List[str]]
|
|
191
|
+
]:
|
|
192
|
+
if not variables:
|
|
193
|
+
return {}, {}, {}
|
|
194
|
+
|
|
195
|
+
serializable_variables = self._convert_dict_to_json_serializable(variables)
|
|
196
|
+
return self._get_files_from_variables(serializable_variables)
|
|
197
|
+
|
|
142
198
|
def _convert_dict_to_json_serializable(
|
|
143
199
|
self, dict_: Dict[str, Any]
|
|
144
200
|
) -> Dict[str, Any]:
|
|
@@ -150,11 +206,104 @@ class AsyncBaseClient:
|
|
|
150
206
|
|
|
151
207
|
def _convert_value(self, value: Any) -> Any:
|
|
152
208
|
if isinstance(value, BaseModel):
|
|
153
|
-
return value.
|
|
209
|
+
return value.model_dump(by_alias=True, exclude_unset=True)
|
|
154
210
|
if isinstance(value, list):
|
|
155
211
|
return [self._convert_value(item) for item in value]
|
|
156
212
|
return value
|
|
157
213
|
|
|
214
|
+
def _get_files_from_variables(
|
|
215
|
+
self, variables: Dict[str, Any]
|
|
216
|
+
) -> Tuple[
|
|
217
|
+
Dict[str, Any], Dict[str, Tuple[str, IO[bytes], str]], Dict[str, List[str]]
|
|
218
|
+
]:
|
|
219
|
+
files_map: Dict[str, List[str]] = {}
|
|
220
|
+
files_list: List[Upload] = []
|
|
221
|
+
|
|
222
|
+
def separate_files(path: str, obj: Any) -> Any:
|
|
223
|
+
if isinstance(obj, list):
|
|
224
|
+
nulled_list = []
|
|
225
|
+
for index, value in enumerate(obj):
|
|
226
|
+
value = separate_files(f"{path}.{index}", value)
|
|
227
|
+
nulled_list.append(value)
|
|
228
|
+
return nulled_list
|
|
229
|
+
|
|
230
|
+
if isinstance(obj, dict):
|
|
231
|
+
nulled_dict = {}
|
|
232
|
+
for key, value in obj.items():
|
|
233
|
+
value = separate_files(f"{path}.{key}", value)
|
|
234
|
+
nulled_dict[key] = value
|
|
235
|
+
return nulled_dict
|
|
236
|
+
|
|
237
|
+
if isinstance(obj, Upload):
|
|
238
|
+
if obj in files_list:
|
|
239
|
+
file_index = files_list.index(obj)
|
|
240
|
+
files_map[str(file_index)].append(path)
|
|
241
|
+
else:
|
|
242
|
+
file_index = len(files_list)
|
|
243
|
+
files_list.append(obj)
|
|
244
|
+
files_map[str(file_index)] = [path]
|
|
245
|
+
return None
|
|
246
|
+
|
|
247
|
+
return obj
|
|
248
|
+
|
|
249
|
+
nulled_variables = separate_files("variables", variables)
|
|
250
|
+
files: Dict[str, Tuple[str, IO[bytes], str]] = {
|
|
251
|
+
str(i): (file_.filename, cast(IO[bytes], file_.content), file_.content_type)
|
|
252
|
+
for i, file_ in enumerate(files_list)
|
|
253
|
+
}
|
|
254
|
+
return nulled_variables, files, files_map
|
|
255
|
+
|
|
256
|
+
async def _execute_multipart(
|
|
257
|
+
self,
|
|
258
|
+
query: str,
|
|
259
|
+
operation_name: Optional[str],
|
|
260
|
+
variables: Dict[str, Any],
|
|
261
|
+
files: Dict[str, Tuple[str, IO[bytes], str]],
|
|
262
|
+
files_map: Dict[str, List[str]],
|
|
263
|
+
**kwargs: Any,
|
|
264
|
+
) -> httpx.Response:
|
|
265
|
+
data = {
|
|
266
|
+
"operations": json.dumps(
|
|
267
|
+
{
|
|
268
|
+
"query": query,
|
|
269
|
+
"operationName": operation_name,
|
|
270
|
+
"variables": variables,
|
|
271
|
+
},
|
|
272
|
+
default=to_jsonable_python,
|
|
273
|
+
),
|
|
274
|
+
"map": json.dumps(files_map, default=to_jsonable_python),
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return await self.http_client.post(
|
|
278
|
+
url=self.url, data=data, files=files, **kwargs
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
async def _execute_json(
|
|
282
|
+
self,
|
|
283
|
+
query: str,
|
|
284
|
+
operation_name: Optional[str],
|
|
285
|
+
variables: Dict[str, Any],
|
|
286
|
+
**kwargs: Any,
|
|
287
|
+
) -> httpx.Response:
|
|
288
|
+
headers: Dict[str, str] = {"Content-Type": "application/json"}
|
|
289
|
+
headers.update(kwargs.get("headers", {}))
|
|
290
|
+
|
|
291
|
+
merged_kwargs: Dict[str, Any] = kwargs.copy()
|
|
292
|
+
merged_kwargs["headers"] = headers
|
|
293
|
+
|
|
294
|
+
return await self.http_client.post(
|
|
295
|
+
url=self.url,
|
|
296
|
+
content=json.dumps(
|
|
297
|
+
{
|
|
298
|
+
"query": query,
|
|
299
|
+
"operationName": operation_name,
|
|
300
|
+
"variables": variables,
|
|
301
|
+
},
|
|
302
|
+
default=to_jsonable_python,
|
|
303
|
+
),
|
|
304
|
+
**merged_kwargs,
|
|
305
|
+
)
|
|
306
|
+
|
|
158
307
|
async def _send_connection_init(self, websocket: WebSocketClientProtocol) -> None:
|
|
159
308
|
payload: Dict[str, Any] = {
|
|
160
309
|
"type": GraphQLTransportWSMessageType.CONNECTION_INIT.value
|
|
@@ -168,12 +317,13 @@ class AsyncBaseClient:
|
|
|
168
317
|
websocket: WebSocketClientProtocol,
|
|
169
318
|
operation_id: str,
|
|
170
319
|
query: str,
|
|
320
|
+
operation_name: Optional[str] = None,
|
|
171
321
|
variables: Optional[Dict[str, Any]] = None,
|
|
172
322
|
) -> None:
|
|
173
323
|
payload: Dict[str, Any] = {
|
|
174
324
|
"id": operation_id,
|
|
175
325
|
"type": GraphQLTransportWSMessageType.SUBSCRIBE.value,
|
|
176
|
-
"payload": {"query": query},
|
|
326
|
+
"payload": {"query": query, "operationName": operation_name},
|
|
177
327
|
}
|
|
178
328
|
if variables:
|
|
179
329
|
payload["payload"]["variables"] = self._convert_dict_to_json_serializable(
|
|
@@ -182,7 +332,10 @@ class AsyncBaseClient:
|
|
|
182
332
|
await websocket.send(json.dumps(payload))
|
|
183
333
|
|
|
184
334
|
async def _handle_ws_message(
|
|
185
|
-
self,
|
|
335
|
+
self,
|
|
336
|
+
message: Data,
|
|
337
|
+
websocket: WebSocketClientProtocol,
|
|
338
|
+
expected_type: Optional[GraphQLTransportWSMessageType] = None,
|
|
186
339
|
) -> Optional[Dict[str, Any]]:
|
|
187
340
|
try:
|
|
188
341
|
message_dict = json.loads(message)
|
|
@@ -195,6 +348,11 @@ class AsyncBaseClient:
|
|
|
195
348
|
if not type_ or type_ not in {t.value for t in GraphQLTransportWSMessageType}:
|
|
196
349
|
raise GraphQLClientInvalidMessageFormat(message=message)
|
|
197
350
|
|
|
351
|
+
if expected_type and expected_type != type_:
|
|
352
|
+
raise GraphQLClientInvalidMessageFormat(
|
|
353
|
+
f"Invalid message received. Expected: {expected_type.value}"
|
|
354
|
+
)
|
|
355
|
+
|
|
198
356
|
if type_ == GraphQLTransportWSMessageType.NEXT:
|
|
199
357
|
if "data" not in payload:
|
|
200
358
|
raise GraphQLClientInvalidMessageFormat(message=message)
|