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,121 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import datetime as dt
4
+ import typing
5
+
6
+ import pydantic
7
+ import typing_extensions
8
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
9
+ from ..core.serialization import FieldMetadata
10
+ from .usage_summary_order import UsageSummaryOrder
11
+ from .usage_summary_order_line import UsageSummaryOrderLine
12
+
13
+
14
+ class UsageSummary(UniversalBaseModel):
15
+ """
16
+ A single usage summary record
17
+ """
18
+
19
+ id: str = pydantic.Field()
20
+ """
21
+ The unique identifier of the usage summary
22
+ """
23
+
24
+ event_name: typing_extensions.Annotated[str, FieldMetadata(alias="eventName")] = pydantic.Field()
25
+ """
26
+ The name of the event being tracked
27
+ """
28
+
29
+ events_quantity: typing_extensions.Annotated[int, FieldMetadata(alias="eventsQuantity")] = pydantic.Field()
30
+ """
31
+ The quantity of events in this usage period
32
+ """
33
+
34
+ start_date: typing_extensions.Annotated[dt.datetime, FieldMetadata(alias="startDate")] = pydantic.Field()
35
+ """
36
+ The start date of the usage period
37
+ """
38
+
39
+ end_date: typing_extensions.Annotated[dt.datetime, FieldMetadata(alias="endDate")] = pydantic.Field()
40
+ """
41
+ The end date of the usage period
42
+ """
43
+
44
+ subtotal: int = pydantic.Field()
45
+ """
46
+ The subtotal amount in the smallest currency unit (e.g., cents)
47
+ """
48
+
49
+ next_billing_date: typing_extensions.Annotated[dt.datetime, FieldMetadata(alias="nextBillingDate")] = (
50
+ pydantic.Field()
51
+ )
52
+ """
53
+ The next billing date for this usage
54
+ """
55
+
56
+ customer_id: typing_extensions.Annotated[str, FieldMetadata(alias="customerId")] = pydantic.Field()
57
+ """
58
+ The internal customer ID
59
+ """
60
+
61
+ order_id: typing_extensions.Annotated[str, FieldMetadata(alias="orderId")] = pydantic.Field()
62
+ """
63
+ The order ID associated with this usage
64
+ """
65
+
66
+ order_line_id: typing_extensions.Annotated[str, FieldMetadata(alias="orderLineId")] = pydantic.Field()
67
+ """
68
+ The order line ID associated with this usage
69
+ """
70
+
71
+ order_line_attribute_id: typing_extensions.Annotated[str, FieldMetadata(alias="orderLineAttributeId")] = (
72
+ pydantic.Field()
73
+ )
74
+ """
75
+ The order line attribute ID associated with this usage
76
+ """
77
+
78
+ invoice_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="invoiceId")] = pydantic.Field(
79
+ default=None
80
+ )
81
+ """
82
+ The invoice ID if this usage has been invoiced
83
+ """
84
+
85
+ invoice_line_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="invoiceLineId")] = (
86
+ pydantic.Field(default=None)
87
+ )
88
+ """
89
+ The invoice line ID if this usage has been invoiced
90
+ """
91
+
92
+ created_at: typing_extensions.Annotated[dt.datetime, FieldMetadata(alias="createdAt")] = pydantic.Field()
93
+ """
94
+ When the usage summary was created
95
+ """
96
+
97
+ updated_at: typing_extensions.Annotated[dt.datetime, FieldMetadata(alias="updatedAt")] = pydantic.Field()
98
+ """
99
+ When the usage summary was last updated
100
+ """
101
+
102
+ order: typing.Optional[UsageSummaryOrder] = pydantic.Field(default=None)
103
+ """
104
+ Associated order information
105
+ """
106
+
107
+ order_line: typing_extensions.Annotated[
108
+ typing.Optional[UsageSummaryOrderLine], FieldMetadata(alias="orderLine")
109
+ ] = pydantic.Field(default=None)
110
+ """
111
+ Associated order line information
112
+ """
113
+
114
+ if IS_PYDANTIC_V2:
115
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
116
+ else:
117
+
118
+ class Config:
119
+ frozen = True
120
+ smart_union = True
121
+ extra = pydantic.Extra.allow
@@ -0,0 +1,26 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ import typing_extensions
7
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
8
+ from ..core.serialization import FieldMetadata
9
+
10
+
11
+ class UsageSummaryOrder(UniversalBaseModel):
12
+ """
13
+ Associated order information
14
+ """
15
+
16
+ id: typing.Optional[str] = None
17
+ display_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="displayId")] = None
18
+
19
+ if IS_PYDANTIC_V2:
20
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
21
+ else:
22
+
23
+ class Config:
24
+ frozen = True
25
+ smart_union = True
26
+ extra = pydantic.Extra.allow
@@ -0,0 +1,26 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ import typing_extensions
7
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
8
+ from ..core.serialization import FieldMetadata
9
+
10
+
11
+ class UsageSummaryOrderLine(UniversalBaseModel):
12
+ """
13
+ Associated order line information
14
+ """
15
+
16
+ id: typing.Optional[str] = None
17
+ display_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="displayId")] = None
18
+
19
+ if IS_PYDANTIC_V2:
20
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
21
+ else:
22
+
23
+ class Config:
24
+ frozen = True
25
+ smart_union = True
26
+ extra = pydantic.Extra.allow
paid/usage/__init__.py CHANGED
@@ -2,3 +2,6 @@
2
2
 
3
3
  # isort: skip_file
4
4
 
5
+ from .types import UsageCheckUsageResponse
6
+
7
+ __all__ = ["UsageCheckUsageResponse"]
paid/usage/client.py CHANGED
@@ -5,7 +5,9 @@ import typing
5
5
  from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
6
6
  from ..core.request_options import RequestOptions
7
7
  from ..types.signal import Signal
8
+ from ..types.signal_v_2 import SignalV2
8
9
  from .raw_client import AsyncRawUsageClient, RawUsageClient
10
+ from .types.usage_check_usage_response import UsageCheckUsageResponse
9
11
 
10
12
  # this is used as the default value for optional parameters
11
13
  OMIT = typing.cast(typing.Any, ...)
@@ -33,6 +35,8 @@ class UsageClient:
33
35
  request_options: typing.Optional[RequestOptions] = None,
34
36
  ) -> None:
35
37
  """
38
+ DEPRECATED: Use POST /usage/v2/signals/bulk instead for cleaner field names.
39
+
36
40
  Parameters
37
41
  ----------
38
42
  signals : typing.Optional[typing.Sequence[Signal]]
@@ -58,6 +62,98 @@ class UsageClient:
58
62
  _response = self._raw_client.record_bulk(signals=signals, request_options=request_options)
59
63
  return _response.data
60
64
 
65
+ def usage_record_bulk_v_2(
66
+ self,
67
+ *,
68
+ signals: typing.Optional[typing.Sequence[SignalV2]] = OMIT,
69
+ request_options: typing.Optional[RequestOptions] = None,
70
+ ) -> None:
71
+ """
72
+ Parameters
73
+ ----------
74
+ signals : typing.Optional[typing.Sequence[SignalV2]]
75
+
76
+ request_options : typing.Optional[RequestOptions]
77
+ Request-specific configuration.
78
+
79
+ Returns
80
+ -------
81
+ None
82
+
83
+ Examples
84
+ --------
85
+ from paid import Paid, SignalV2
86
+
87
+ client = Paid(
88
+ token="YOUR_TOKEN",
89
+ )
90
+ client.usage.usage_record_bulk_v_2(
91
+ signals=[
92
+ SignalV2(
93
+ event_name="emails_sent",
94
+ product_id="63fd642c-569d-44f9-8d67-5cf4944a16cc",
95
+ customer_id="7d0b6fce-d82a-433d-8315-c994f8f1d68d",
96
+ ),
97
+ SignalV2(
98
+ event_name="emails_sent",
99
+ external_product_id="acme-product",
100
+ external_customer_id="acme-inc",
101
+ ),
102
+ SignalV2(
103
+ event_name="meeting_booked",
104
+ product_id="63fd642c-569d-44f9-8d67-5cf4944a16cc",
105
+ external_customer_id="acme-inc",
106
+ data={"meeting_duration": 30, "meeting_type": "demo"},
107
+ ),
108
+ ],
109
+ )
110
+ """
111
+ _response = self._raw_client.usage_record_bulk_v_2(signals=signals, request_options=request_options)
112
+ return _response.data
113
+
114
+ def check_usage(
115
+ self,
116
+ *,
117
+ external_customer_id: str,
118
+ external_product_id: str,
119
+ request_options: typing.Optional[RequestOptions] = None,
120
+ ) -> UsageCheckUsageResponse:
121
+ """
122
+ Parameters
123
+ ----------
124
+ external_customer_id : str
125
+ External customer ID
126
+
127
+ external_product_id : str
128
+ External product ID (the external ID of the product/agent)
129
+
130
+ request_options : typing.Optional[RequestOptions]
131
+ Request-specific configuration.
132
+
133
+ Returns
134
+ -------
135
+ UsageCheckUsageResponse
136
+ Usage check response
137
+
138
+ Examples
139
+ --------
140
+ from paid import Paid
141
+
142
+ client = Paid(
143
+ token="YOUR_TOKEN",
144
+ )
145
+ client.usage.check_usage(
146
+ external_customer_id="acme-inc",
147
+ external_product_id="acme-agent",
148
+ )
149
+ """
150
+ _response = self._raw_client.check_usage(
151
+ external_customer_id=external_customer_id,
152
+ external_product_id=external_product_id,
153
+ request_options=request_options,
154
+ )
155
+ return _response.data
156
+
61
157
 
62
158
  class AsyncUsageClient:
63
159
  def __init__(self, *, client_wrapper: AsyncClientWrapper):
@@ -81,6 +177,8 @@ class AsyncUsageClient:
81
177
  request_options: typing.Optional[RequestOptions] = None,
82
178
  ) -> None:
83
179
  """
180
+ DEPRECATED: Use POST /usage/v2/signals/bulk instead for cleaner field names.
181
+
84
182
  Parameters
85
183
  ----------
86
184
  signals : typing.Optional[typing.Sequence[Signal]]
@@ -113,3 +211,111 @@ class AsyncUsageClient:
113
211
  """
114
212
  _response = await self._raw_client.record_bulk(signals=signals, request_options=request_options)
115
213
  return _response.data
214
+
215
+ async def usage_record_bulk_v_2(
216
+ self,
217
+ *,
218
+ signals: typing.Optional[typing.Sequence[SignalV2]] = OMIT,
219
+ request_options: typing.Optional[RequestOptions] = None,
220
+ ) -> None:
221
+ """
222
+ Parameters
223
+ ----------
224
+ signals : typing.Optional[typing.Sequence[SignalV2]]
225
+
226
+ request_options : typing.Optional[RequestOptions]
227
+ Request-specific configuration.
228
+
229
+ Returns
230
+ -------
231
+ None
232
+
233
+ Examples
234
+ --------
235
+ import asyncio
236
+
237
+ from paid import AsyncPaid, SignalV2
238
+
239
+ client = AsyncPaid(
240
+ token="YOUR_TOKEN",
241
+ )
242
+
243
+
244
+ async def main() -> None:
245
+ await client.usage.usage_record_bulk_v_2(
246
+ signals=[
247
+ SignalV2(
248
+ event_name="emails_sent",
249
+ product_id="63fd642c-569d-44f9-8d67-5cf4944a16cc",
250
+ customer_id="7d0b6fce-d82a-433d-8315-c994f8f1d68d",
251
+ ),
252
+ SignalV2(
253
+ event_name="emails_sent",
254
+ external_product_id="acme-product",
255
+ external_customer_id="acme-inc",
256
+ ),
257
+ SignalV2(
258
+ event_name="meeting_booked",
259
+ product_id="63fd642c-569d-44f9-8d67-5cf4944a16cc",
260
+ external_customer_id="acme-inc",
261
+ data={"meeting_duration": 30, "meeting_type": "demo"},
262
+ ),
263
+ ],
264
+ )
265
+
266
+
267
+ asyncio.run(main())
268
+ """
269
+ _response = await self._raw_client.usage_record_bulk_v_2(signals=signals, request_options=request_options)
270
+ return _response.data
271
+
272
+ async def check_usage(
273
+ self,
274
+ *,
275
+ external_customer_id: str,
276
+ external_product_id: str,
277
+ request_options: typing.Optional[RequestOptions] = None,
278
+ ) -> UsageCheckUsageResponse:
279
+ """
280
+ Parameters
281
+ ----------
282
+ external_customer_id : str
283
+ External customer ID
284
+
285
+ external_product_id : str
286
+ External product ID (the external ID of the product/agent)
287
+
288
+ request_options : typing.Optional[RequestOptions]
289
+ Request-specific configuration.
290
+
291
+ Returns
292
+ -------
293
+ UsageCheckUsageResponse
294
+ Usage check response
295
+
296
+ Examples
297
+ --------
298
+ import asyncio
299
+
300
+ from paid import AsyncPaid
301
+
302
+ client = AsyncPaid(
303
+ token="YOUR_TOKEN",
304
+ )
305
+
306
+
307
+ async def main() -> None:
308
+ await client.usage.check_usage(
309
+ external_customer_id="acme-inc",
310
+ external_product_id="acme-agent",
311
+ )
312
+
313
+
314
+ asyncio.run(main())
315
+ """
316
+ _response = await self._raw_client.check_usage(
317
+ external_customer_id=external_customer_id,
318
+ external_product_id=external_product_id,
319
+ request_options=request_options,
320
+ )
321
+ return _response.data