paid-python 0.4.1a0__py3-none-any.whl → 0.6.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 (57) hide show
  1. paid/__init__.py +44 -4
  2. paid/agents/client.py +32 -0
  3. paid/agents/raw_client.py +32 -0
  4. paid/client.py +25 -2
  5. paid/core/client_wrapper.py +2 -3
  6. paid/customers/client.py +168 -36
  7. paid/customers/raw_client.py +217 -36
  8. paid/errors/__init__.py +2 -1
  9. paid/errors/internal_server_error.py +11 -0
  10. paid/orders/client.py +10 -0
  11. paid/orders/lines/client.py +0 -4
  12. paid/orders/raw_client.py +10 -0
  13. paid/plans/__init__.py +4 -0
  14. paid/plans/client.py +332 -0
  15. paid/plans/raw_client.py +464 -0
  16. paid/products/__init__.py +7 -0
  17. paid/products/client.py +788 -0
  18. paid/products/raw_client.py +807 -0
  19. paid/products/types/__init__.py +7 -0
  20. paid/products/types/product_create_type.py +5 -0
  21. paid/traces/__init__.py +4 -0
  22. paid/traces/client.py +218 -0
  23. paid/traces/raw_client.py +226 -0
  24. paid/tracing/context_manager.py +9 -4
  25. paid/types/__init__.py +34 -2
  26. paid/types/cost_trace.py +6 -1
  27. paid/types/customer.py +4 -3
  28. paid/types/customer_update.py +4 -2
  29. paid/types/order_line_attribute_create_one.py +5 -0
  30. paid/types/order_line_create.py +26 -5
  31. paid/types/pagination_meta.py +26 -0
  32. paid/types/plan.py +81 -0
  33. paid/types/plan_group.py +60 -0
  34. paid/types/plan_plan_products_item.py +35 -0
  35. paid/types/plan_plan_products_item_plan_product_attribute_item.py +34 -0
  36. paid/types/product.py +56 -0
  37. paid/types/product_type.py +5 -0
  38. paid/types/product_update.py +36 -0
  39. paid/types/product_update_type.py +5 -0
  40. paid/types/signal.py +17 -5
  41. paid/types/signal_v_2.py +56 -0
  42. paid/types/trace.py +69 -0
  43. paid/types/traces_response.py +26 -0
  44. paid/types/{order_line_attribute_create.py → usage_pagination_meta.py} +16 -8
  45. paid/types/usage_summaries_response.py +26 -0
  46. paid/types/usage_summary.py +121 -0
  47. paid/types/usage_summary_order.py +26 -0
  48. paid/types/usage_summary_order_line.py +26 -0
  49. paid/usage/__init__.py +3 -0
  50. paid/usage/client.py +206 -0
  51. paid/usage/raw_client.py +283 -0
  52. paid/usage/types/__init__.py +7 -0
  53. paid/usage/types/usage_check_usage_response.py +53 -0
  54. {paid_python-0.4.1a0.dist-info → paid_python-0.6.0.dist-info}/METADATA +20 -20
  55. {paid_python-0.4.1a0.dist-info → paid_python-0.6.0.dist-info}/RECORD +57 -27
  56. {paid_python-0.4.1a0.dist-info → paid_python-0.6.0.dist-info}/LICENSE +0 -0
  57. {paid_python-0.4.1a0.dist-info → paid_python-0.6.0.dist-info}/WHEEL +0 -0
@@ -0,0 +1,464 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import datetime as dt
4
+ import typing
5
+ from json.decoder import JSONDecodeError
6
+
7
+ from ..core.api_error import ApiError
8
+ from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
9
+ from ..core.datetime_utils import serialize_datetime
10
+ from ..core.http_response import AsyncHttpResponse, HttpResponse
11
+ from ..core.jsonable_encoder import jsonable_encoder
12
+ from ..core.pydantic_utilities import parse_obj_as
13
+ from ..core.request_options import RequestOptions
14
+ from ..errors.bad_request_error import BadRequestError
15
+ from ..errors.forbidden_error import ForbiddenError
16
+ from ..errors.not_found_error import NotFoundError
17
+ from ..types.error import Error
18
+ from ..types.plan import Plan
19
+ from ..types.plan_group import PlanGroup
20
+ from ..types.usage_summaries_response import UsageSummariesResponse
21
+
22
+
23
+ class RawPlansClient:
24
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
25
+ self._client_wrapper = client_wrapper
26
+
27
+ def get_by_id(self, plan_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> HttpResponse[Plan]:
28
+ """
29
+ Parameters
30
+ ----------
31
+ plan_id : str
32
+ The ID of the plan
33
+
34
+ request_options : typing.Optional[RequestOptions]
35
+ Request-specific configuration.
36
+
37
+ Returns
38
+ -------
39
+ HttpResponse[Plan]
40
+ Success response
41
+ """
42
+ _response = self._client_wrapper.httpx_client.request(
43
+ f"plans/{jsonable_encoder(plan_id)}",
44
+ method="GET",
45
+ request_options=request_options,
46
+ )
47
+ try:
48
+ if 200 <= _response.status_code < 300:
49
+ _data = typing.cast(
50
+ Plan,
51
+ parse_obj_as(
52
+ type_=Plan, # type: ignore
53
+ object_=_response.json(),
54
+ ),
55
+ )
56
+ return HttpResponse(response=_response, data=_data)
57
+ if _response.status_code == 403:
58
+ raise ForbiddenError(
59
+ headers=dict(_response.headers),
60
+ body=typing.cast(
61
+ Error,
62
+ parse_obj_as(
63
+ type_=Error, # type: ignore
64
+ object_=_response.json(),
65
+ ),
66
+ ),
67
+ )
68
+ if _response.status_code == 404:
69
+ raise NotFoundError(
70
+ headers=dict(_response.headers),
71
+ body=typing.cast(
72
+ Error,
73
+ parse_obj_as(
74
+ type_=Error, # type: ignore
75
+ object_=_response.json(),
76
+ ),
77
+ ),
78
+ )
79
+ _response_json = _response.json()
80
+ except JSONDecodeError:
81
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
82
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
83
+
84
+ def get_usage(
85
+ self,
86
+ plan_id: str,
87
+ *,
88
+ external_id: str,
89
+ limit: typing.Optional[int] = None,
90
+ offset: typing.Optional[int] = None,
91
+ start_time: typing.Optional[dt.datetime] = None,
92
+ end_time: typing.Optional[dt.datetime] = None,
93
+ request_options: typing.Optional[RequestOptions] = None,
94
+ ) -> HttpResponse[UsageSummariesResponse]:
95
+ """
96
+ Parameters
97
+ ----------
98
+ plan_id : str
99
+ The ID of the plan
100
+
101
+ external_id : str
102
+ The external ID of the customer
103
+
104
+ limit : typing.Optional[int]
105
+ Maximum number of usage summaries to return (1-1000)
106
+
107
+ offset : typing.Optional[int]
108
+ Number of usage summaries to skip for pagination
109
+
110
+ start_time : typing.Optional[dt.datetime]
111
+ Filter usage summaries starting from this time (ISO 8601 format). Returns summaries that overlap with the time range.
112
+
113
+ end_time : typing.Optional[dt.datetime]
114
+ Filter usage summaries up to this time (ISO 8601 format). Returns summaries that overlap with the time range.
115
+
116
+ request_options : typing.Optional[RequestOptions]
117
+ Request-specific configuration.
118
+
119
+ Returns
120
+ -------
121
+ HttpResponse[UsageSummariesResponse]
122
+ Success response
123
+ """
124
+ _response = self._client_wrapper.httpx_client.request(
125
+ f"plans/{jsonable_encoder(plan_id)}/usage",
126
+ method="GET",
127
+ params={
128
+ "externalId": external_id,
129
+ "limit": limit,
130
+ "offset": offset,
131
+ "startTime": serialize_datetime(start_time) if start_time is not None else None,
132
+ "endTime": serialize_datetime(end_time) if end_time is not None else None,
133
+ },
134
+ request_options=request_options,
135
+ )
136
+ try:
137
+ if 200 <= _response.status_code < 300:
138
+ _data = typing.cast(
139
+ UsageSummariesResponse,
140
+ parse_obj_as(
141
+ type_=UsageSummariesResponse, # type: ignore
142
+ object_=_response.json(),
143
+ ),
144
+ )
145
+ return HttpResponse(response=_response, data=_data)
146
+ if _response.status_code == 400:
147
+ raise BadRequestError(
148
+ headers=dict(_response.headers),
149
+ body=typing.cast(
150
+ Error,
151
+ parse_obj_as(
152
+ type_=Error, # type: ignore
153
+ object_=_response.json(),
154
+ ),
155
+ ),
156
+ )
157
+ if _response.status_code == 403:
158
+ raise ForbiddenError(
159
+ headers=dict(_response.headers),
160
+ body=typing.cast(
161
+ Error,
162
+ parse_obj_as(
163
+ type_=Error, # type: ignore
164
+ object_=_response.json(),
165
+ ),
166
+ ),
167
+ )
168
+ if _response.status_code == 404:
169
+ raise NotFoundError(
170
+ headers=dict(_response.headers),
171
+ body=typing.cast(
172
+ Error,
173
+ parse_obj_as(
174
+ type_=Error, # type: ignore
175
+ object_=_response.json(),
176
+ ),
177
+ ),
178
+ )
179
+ _response_json = _response.json()
180
+ except JSONDecodeError:
181
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
182
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
183
+
184
+ def get_group_by_id(
185
+ self, plan_group_id: str, *, request_options: typing.Optional[RequestOptions] = None
186
+ ) -> HttpResponse[PlanGroup]:
187
+ """
188
+ Parameters
189
+ ----------
190
+ plan_group_id : str
191
+ The ID of the plan group
192
+
193
+ request_options : typing.Optional[RequestOptions]
194
+ Request-specific configuration.
195
+
196
+ Returns
197
+ -------
198
+ HttpResponse[PlanGroup]
199
+ Success response
200
+ """
201
+ _response = self._client_wrapper.httpx_client.request(
202
+ f"plans/group/{jsonable_encoder(plan_group_id)}",
203
+ method="GET",
204
+ request_options=request_options,
205
+ )
206
+ try:
207
+ if 200 <= _response.status_code < 300:
208
+ _data = typing.cast(
209
+ PlanGroup,
210
+ parse_obj_as(
211
+ type_=PlanGroup, # type: ignore
212
+ object_=_response.json(),
213
+ ),
214
+ )
215
+ return HttpResponse(response=_response, data=_data)
216
+ if _response.status_code == 403:
217
+ raise ForbiddenError(
218
+ headers=dict(_response.headers),
219
+ body=typing.cast(
220
+ Error,
221
+ parse_obj_as(
222
+ type_=Error, # type: ignore
223
+ object_=_response.json(),
224
+ ),
225
+ ),
226
+ )
227
+ if _response.status_code == 404:
228
+ raise NotFoundError(
229
+ headers=dict(_response.headers),
230
+ body=typing.cast(
231
+ Error,
232
+ parse_obj_as(
233
+ type_=Error, # type: ignore
234
+ object_=_response.json(),
235
+ ),
236
+ ),
237
+ )
238
+ _response_json = _response.json()
239
+ except JSONDecodeError:
240
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
241
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
242
+
243
+
244
+ class AsyncRawPlansClient:
245
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
246
+ self._client_wrapper = client_wrapper
247
+
248
+ async def get_by_id(
249
+ self, plan_id: str, *, request_options: typing.Optional[RequestOptions] = None
250
+ ) -> AsyncHttpResponse[Plan]:
251
+ """
252
+ Parameters
253
+ ----------
254
+ plan_id : str
255
+ The ID of the plan
256
+
257
+ request_options : typing.Optional[RequestOptions]
258
+ Request-specific configuration.
259
+
260
+ Returns
261
+ -------
262
+ AsyncHttpResponse[Plan]
263
+ Success response
264
+ """
265
+ _response = await self._client_wrapper.httpx_client.request(
266
+ f"plans/{jsonable_encoder(plan_id)}",
267
+ method="GET",
268
+ request_options=request_options,
269
+ )
270
+ try:
271
+ if 200 <= _response.status_code < 300:
272
+ _data = typing.cast(
273
+ Plan,
274
+ parse_obj_as(
275
+ type_=Plan, # type: ignore
276
+ object_=_response.json(),
277
+ ),
278
+ )
279
+ return AsyncHttpResponse(response=_response, data=_data)
280
+ if _response.status_code == 403:
281
+ raise ForbiddenError(
282
+ headers=dict(_response.headers),
283
+ body=typing.cast(
284
+ Error,
285
+ parse_obj_as(
286
+ type_=Error, # type: ignore
287
+ object_=_response.json(),
288
+ ),
289
+ ),
290
+ )
291
+ if _response.status_code == 404:
292
+ raise NotFoundError(
293
+ headers=dict(_response.headers),
294
+ body=typing.cast(
295
+ Error,
296
+ parse_obj_as(
297
+ type_=Error, # type: ignore
298
+ object_=_response.json(),
299
+ ),
300
+ ),
301
+ )
302
+ _response_json = _response.json()
303
+ except JSONDecodeError:
304
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
305
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
306
+
307
+ async def get_usage(
308
+ self,
309
+ plan_id: str,
310
+ *,
311
+ external_id: str,
312
+ limit: typing.Optional[int] = None,
313
+ offset: typing.Optional[int] = None,
314
+ start_time: typing.Optional[dt.datetime] = None,
315
+ end_time: typing.Optional[dt.datetime] = None,
316
+ request_options: typing.Optional[RequestOptions] = None,
317
+ ) -> AsyncHttpResponse[UsageSummariesResponse]:
318
+ """
319
+ Parameters
320
+ ----------
321
+ plan_id : str
322
+ The ID of the plan
323
+
324
+ external_id : str
325
+ The external ID of the customer
326
+
327
+ limit : typing.Optional[int]
328
+ Maximum number of usage summaries to return (1-1000)
329
+
330
+ offset : typing.Optional[int]
331
+ Number of usage summaries to skip for pagination
332
+
333
+ start_time : typing.Optional[dt.datetime]
334
+ Filter usage summaries starting from this time (ISO 8601 format). Returns summaries that overlap with the time range.
335
+
336
+ end_time : typing.Optional[dt.datetime]
337
+ Filter usage summaries up to this time (ISO 8601 format). Returns summaries that overlap with the time range.
338
+
339
+ request_options : typing.Optional[RequestOptions]
340
+ Request-specific configuration.
341
+
342
+ Returns
343
+ -------
344
+ AsyncHttpResponse[UsageSummariesResponse]
345
+ Success response
346
+ """
347
+ _response = await self._client_wrapper.httpx_client.request(
348
+ f"plans/{jsonable_encoder(plan_id)}/usage",
349
+ method="GET",
350
+ params={
351
+ "externalId": external_id,
352
+ "limit": limit,
353
+ "offset": offset,
354
+ "startTime": serialize_datetime(start_time) if start_time is not None else None,
355
+ "endTime": serialize_datetime(end_time) if end_time is not None else None,
356
+ },
357
+ request_options=request_options,
358
+ )
359
+ try:
360
+ if 200 <= _response.status_code < 300:
361
+ _data = typing.cast(
362
+ UsageSummariesResponse,
363
+ parse_obj_as(
364
+ type_=UsageSummariesResponse, # type: ignore
365
+ object_=_response.json(),
366
+ ),
367
+ )
368
+ return AsyncHttpResponse(response=_response, data=_data)
369
+ if _response.status_code == 400:
370
+ raise BadRequestError(
371
+ headers=dict(_response.headers),
372
+ body=typing.cast(
373
+ Error,
374
+ parse_obj_as(
375
+ type_=Error, # type: ignore
376
+ object_=_response.json(),
377
+ ),
378
+ ),
379
+ )
380
+ if _response.status_code == 403:
381
+ raise ForbiddenError(
382
+ headers=dict(_response.headers),
383
+ body=typing.cast(
384
+ Error,
385
+ parse_obj_as(
386
+ type_=Error, # type: ignore
387
+ object_=_response.json(),
388
+ ),
389
+ ),
390
+ )
391
+ if _response.status_code == 404:
392
+ raise NotFoundError(
393
+ headers=dict(_response.headers),
394
+ body=typing.cast(
395
+ Error,
396
+ parse_obj_as(
397
+ type_=Error, # type: ignore
398
+ object_=_response.json(),
399
+ ),
400
+ ),
401
+ )
402
+ _response_json = _response.json()
403
+ except JSONDecodeError:
404
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
405
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
406
+
407
+ async def get_group_by_id(
408
+ self, plan_group_id: str, *, request_options: typing.Optional[RequestOptions] = None
409
+ ) -> AsyncHttpResponse[PlanGroup]:
410
+ """
411
+ Parameters
412
+ ----------
413
+ plan_group_id : str
414
+ The ID of the plan group
415
+
416
+ request_options : typing.Optional[RequestOptions]
417
+ Request-specific configuration.
418
+
419
+ Returns
420
+ -------
421
+ AsyncHttpResponse[PlanGroup]
422
+ Success response
423
+ """
424
+ _response = await self._client_wrapper.httpx_client.request(
425
+ f"plans/group/{jsonable_encoder(plan_group_id)}",
426
+ method="GET",
427
+ request_options=request_options,
428
+ )
429
+ try:
430
+ if 200 <= _response.status_code < 300:
431
+ _data = typing.cast(
432
+ PlanGroup,
433
+ parse_obj_as(
434
+ type_=PlanGroup, # type: ignore
435
+ object_=_response.json(),
436
+ ),
437
+ )
438
+ return AsyncHttpResponse(response=_response, data=_data)
439
+ if _response.status_code == 403:
440
+ raise ForbiddenError(
441
+ headers=dict(_response.headers),
442
+ body=typing.cast(
443
+ Error,
444
+ parse_obj_as(
445
+ type_=Error, # type: ignore
446
+ object_=_response.json(),
447
+ ),
448
+ ),
449
+ )
450
+ if _response.status_code == 404:
451
+ raise NotFoundError(
452
+ headers=dict(_response.headers),
453
+ body=typing.cast(
454
+ Error,
455
+ parse_obj_as(
456
+ type_=Error, # type: ignore
457
+ object_=_response.json(),
458
+ ),
459
+ ),
460
+ )
461
+ _response_json = _response.json()
462
+ except JSONDecodeError:
463
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
464
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
@@ -0,0 +1,7 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ # isort: skip_file
4
+
5
+ from .types import ProductCreateType
6
+
7
+ __all__ = ["ProductCreateType"]