paid-python 1.0.0a0__py3-none-any.whl → 1.0.0a2__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 (137) hide show
  1. paid/__init__.py +61 -122
  2. paid/client.py +16 -22
  3. paid/contacts/client.py +417 -133
  4. paid/contacts/raw_client.py +1048 -118
  5. paid/core/client_wrapper.py +8 -10
  6. paid/customers/__init__.py +0 -3
  7. paid/customers/client.py +394 -1112
  8. paid/customers/raw_client.py +656 -1054
  9. paid/environment.py +1 -1
  10. paid/errors/bad_request_error.py +2 -2
  11. paid/errors/forbidden_error.py +2 -2
  12. paid/errors/internal_server_error.py +2 -2
  13. paid/errors/not_found_error.py +2 -2
  14. paid/invoices/client.py +369 -0
  15. paid/{plans → invoices}/raw_client.py +312 -201
  16. paid/orders/__init__.py +0 -3
  17. paid/orders/client.py +281 -471
  18. paid/orders/raw_client.py +552 -537
  19. paid/products/__init__.py +0 -3
  20. paid/products/client.py +129 -265
  21. paid/products/raw_client.py +565 -233
  22. paid/signals/client.py +130 -0
  23. paid/signals/raw_client.py +190 -0
  24. paid/tracing/autoinstrumentation.py +12 -6
  25. paid/tracing/context_manager.py +2 -6
  26. paid/tracing/distributed_tracing.py +3 -3
  27. paid/tracing/signal.py +3 -3
  28. paid/tracing/wrappers/openai_agents/openaiAgentsHook.py +1 -1
  29. paid/types/__init__.py +58 -110
  30. paid/types/attribution.py +8 -0
  31. paid/types/{agent_attribute.py → bulk_signals_response.py} +4 -5
  32. paid/types/contact.py +12 -20
  33. paid/types/{address.py → contact_billing_address.py} +6 -7
  34. paid/types/{traces_response.py → contact_list_response.py} +5 -9
  35. paid/types/customer.py +15 -22
  36. paid/types/customer_attribution.py +8 -0
  37. paid/types/customer_billing_address.py +26 -0
  38. paid/types/{usage_summary_order.py → customer_by_external_id.py} +3 -5
  39. paid/types/{usage_summary_order_line.py → customer_by_id.py} +3 -5
  40. paid/types/customer_creation_state.py +5 -0
  41. paid/types/customer_list_response.py +22 -0
  42. paid/types/empty_response.py +17 -0
  43. paid/types/{error.py → error_response.py} +4 -7
  44. paid/types/invoice.py +33 -51
  45. paid/types/invoice_line.py +42 -0
  46. paid/types/invoice_line_payment_status.py +7 -0
  47. paid/types/invoice_lines_response.py +22 -0
  48. paid/types/invoice_list_response.py +22 -0
  49. paid/types/invoice_payment_status.py +5 -0
  50. paid/types/invoice_source.py +5 -0
  51. paid/types/invoice_status.py +3 -1
  52. paid/types/invoice_tax_status.py +7 -0
  53. paid/types/order.py +30 -29
  54. paid/types/order_creation_state.py +5 -0
  55. paid/types/order_line.py +6 -24
  56. paid/types/order_lines_response.py +22 -0
  57. paid/types/order_list_response.py +22 -0
  58. paid/types/pagination.py +24 -0
  59. paid/types/product.py +4 -29
  60. paid/types/{tier.py → product_by_external_id.py} +5 -4
  61. paid/types/{cost_amount.py → product_by_id.py} +5 -12
  62. paid/types/product_list_response.py +22 -0
  63. paid/types/signal.py +8 -34
  64. paid/types/{agent_update.py → update_contact_request.py} +10 -9
  65. paid/types/update_customer_request.py +38 -0
  66. paid/types/{product_update.py → update_product_request.py} +2 -12
  67. {paid_python-1.0.0a0.dist-info → paid_python-1.0.0a2.dist-info}/METADATA +23 -8
  68. paid_python-1.0.0a2.dist-info/RECORD +110 -0
  69. paid/agents/client.py +0 -880
  70. paid/agents/raw_client.py +0 -785
  71. paid/customers/types/__init__.py +0 -8
  72. paid/customers/types/customers_check_entitlement_request_view.py +0 -5
  73. paid/customers/types/customers_check_entitlement_response.py +0 -22
  74. paid/orders/lines/client.py +0 -144
  75. paid/orders/lines/raw_client.py +0 -129
  76. paid/plans/__init__.py +0 -4
  77. paid/plans/client.py +0 -403
  78. paid/products/types/__init__.py +0 -7
  79. paid/products/types/product_create_type.py +0 -5
  80. paid/traces/__init__.py +0 -4
  81. paid/traces/client.py +0 -218
  82. paid/traces/raw_client.py +0 -226
  83. paid/types/agent.py +0 -31
  84. paid/types/agent_price_point.py +0 -27
  85. paid/types/agent_price_point_tiers.py +0 -23
  86. paid/types/api_error.py +0 -29
  87. paid/types/billing_frequency.py +0 -5
  88. paid/types/cancel_renewal_response.py +0 -49
  89. paid/types/charge_type.py +0 -5
  90. paid/types/contact_create_for_customer.py +0 -37
  91. paid/types/cost_trace.py +0 -55
  92. paid/types/cost_traces_response.py +0 -26
  93. paid/types/creation_source.py +0 -5
  94. paid/types/creation_state.py +0 -5
  95. paid/types/customer_update.py +0 -40
  96. paid/types/entitlement_usage.py +0 -48
  97. paid/types/order_line_attribute.py +0 -27
  98. paid/types/order_line_attribute_create_one.py +0 -5
  99. paid/types/order_line_attribute_pricing.py +0 -33
  100. paid/types/order_line_create.py +0 -72
  101. paid/types/pagination_meta.py +0 -84
  102. paid/types/payment_method.py +0 -58
  103. paid/types/payment_method_card.py +0 -49
  104. paid/types/payment_method_type.py +0 -5
  105. paid/types/payment_method_us_bank_account.py +0 -36
  106. paid/types/payment_method_us_bank_account_account_type.py +0 -5
  107. paid/types/plan.py +0 -81
  108. paid/types/plan_group.py +0 -60
  109. paid/types/plan_plan_products_item.py +0 -41
  110. paid/types/plan_plan_products_item_plan_product_attribute_item.py +0 -34
  111. paid/types/plan_with_features.py +0 -69
  112. paid/types/plan_with_features_features_item.py +0 -34
  113. paid/types/price_point.py +0 -25
  114. paid/types/pricing.py +0 -31
  115. paid/types/pricing_model_type.py +0 -7
  116. paid/types/product_type.py +0 -5
  117. paid/types/product_update_type.py +0 -5
  118. paid/types/proration_attribute_update.py +0 -44
  119. paid/types/proration_detail.py +0 -49
  120. paid/types/proration_upgrade_response.py +0 -73
  121. paid/types/salutation.py +0 -5
  122. paid/types/signal_v_2.py +0 -56
  123. paid/types/tax_exempt_status.py +0 -5
  124. paid/types/trace.py +0 -69
  125. paid/types/usage_pagination_meta.py +0 -43
  126. paid/types/usage_summaries_response.py +0 -26
  127. paid/types/usage_summary.py +0 -121
  128. paid/usage/__init__.py +0 -7
  129. paid/usage/client.py +0 -321
  130. paid/usage/raw_client.py +0 -387
  131. paid/usage/types/__init__.py +0 -7
  132. paid/usage/types/usage_check_usage_response.py +0 -53
  133. paid_python-1.0.0a0.dist-info/RECORD +0 -152
  134. /paid/{agents → invoices}/__init__.py +0 -0
  135. /paid/{orders/lines → signals}/__init__.py +0 -0
  136. {paid_python-1.0.0a0.dist-info → paid_python-1.0.0a2.dist-info}/LICENSE +0 -0
  137. {paid_python-1.0.0a0.dist-info → paid_python-1.0.0a2.dist-info}/WHEEL +0 -0
paid/signals/client.py ADDED
@@ -0,0 +1,130 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
6
+ from ..core.request_options import RequestOptions
7
+ from ..types.bulk_signals_response import BulkSignalsResponse
8
+ from ..types.signal import Signal
9
+ from .raw_client import AsyncRawSignalsClient, RawSignalsClient
10
+
11
+ # this is used as the default value for optional parameters
12
+ OMIT = typing.cast(typing.Any, ...)
13
+
14
+
15
+ class SignalsClient:
16
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
17
+ self._raw_client = RawSignalsClient(client_wrapper=client_wrapper)
18
+
19
+ @property
20
+ def with_raw_response(self) -> RawSignalsClient:
21
+ """
22
+ Retrieves a raw implementation of this client that returns raw responses.
23
+
24
+ Returns
25
+ -------
26
+ RawSignalsClient
27
+ """
28
+ return self._raw_client
29
+
30
+ def create_signals(
31
+ self, *, signals: typing.Sequence[Signal], request_options: typing.Optional[RequestOptions] = None
32
+ ) -> BulkSignalsResponse:
33
+ """
34
+ Create multiple signals (usage events) in a single request. Each signal must include a customer attribution (either customerId or externalCustomerId) and a product attribution (either productId or externalProductId).
35
+
36
+ Parameters
37
+ ----------
38
+ signals : typing.Sequence[Signal]
39
+
40
+ request_options : typing.Optional[RequestOptions]
41
+ Request-specific configuration.
42
+
43
+ Returns
44
+ -------
45
+ BulkSignalsResponse
46
+ 200
47
+
48
+ Examples
49
+ --------
50
+ from paid import CustomerById, Paid, Signal
51
+
52
+ client = Paid(
53
+ token="YOUR_TOKEN",
54
+ )
55
+ client.signals.create_signals(
56
+ signals=[
57
+ Signal(
58
+ event_name="eventName",
59
+ customer=CustomerById(
60
+ customer_id="customerId",
61
+ ),
62
+ )
63
+ ],
64
+ )
65
+ """
66
+ _response = self._raw_client.create_signals(signals=signals, request_options=request_options)
67
+ return _response.data
68
+
69
+
70
+ class AsyncSignalsClient:
71
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
72
+ self._raw_client = AsyncRawSignalsClient(client_wrapper=client_wrapper)
73
+
74
+ @property
75
+ def with_raw_response(self) -> AsyncRawSignalsClient:
76
+ """
77
+ Retrieves a raw implementation of this client that returns raw responses.
78
+
79
+ Returns
80
+ -------
81
+ AsyncRawSignalsClient
82
+ """
83
+ return self._raw_client
84
+
85
+ async def create_signals(
86
+ self, *, signals: typing.Sequence[Signal], request_options: typing.Optional[RequestOptions] = None
87
+ ) -> BulkSignalsResponse:
88
+ """
89
+ Create multiple signals (usage events) in a single request. Each signal must include a customer attribution (either customerId or externalCustomerId) and a product attribution (either productId or externalProductId).
90
+
91
+ Parameters
92
+ ----------
93
+ signals : typing.Sequence[Signal]
94
+
95
+ request_options : typing.Optional[RequestOptions]
96
+ Request-specific configuration.
97
+
98
+ Returns
99
+ -------
100
+ BulkSignalsResponse
101
+ 200
102
+
103
+ Examples
104
+ --------
105
+ import asyncio
106
+
107
+ from paid import AsyncPaid, CustomerById, Signal
108
+
109
+ client = AsyncPaid(
110
+ token="YOUR_TOKEN",
111
+ )
112
+
113
+
114
+ async def main() -> None:
115
+ await client.signals.create_signals(
116
+ signals=[
117
+ Signal(
118
+ event_name="eventName",
119
+ customer=CustomerById(
120
+ customer_id="customerId",
121
+ ),
122
+ )
123
+ ],
124
+ )
125
+
126
+
127
+ asyncio.run(main())
128
+ """
129
+ _response = await self._raw_client.create_signals(signals=signals, request_options=request_options)
130
+ return _response.data
@@ -0,0 +1,190 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+ from json.decoder import JSONDecodeError
5
+
6
+ from ..core.api_error import ApiError
7
+ from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
8
+ from ..core.http_response import AsyncHttpResponse, HttpResponse
9
+ from ..core.pydantic_utilities import parse_obj_as
10
+ from ..core.request_options import RequestOptions
11
+ from ..core.serialization import convert_and_respect_annotation_metadata
12
+ from ..errors.bad_request_error import BadRequestError
13
+ from ..errors.forbidden_error import ForbiddenError
14
+ from ..errors.internal_server_error import InternalServerError
15
+ from ..types.bulk_signals_response import BulkSignalsResponse
16
+ from ..types.error_response import ErrorResponse
17
+ from ..types.signal import Signal
18
+
19
+ # this is used as the default value for optional parameters
20
+ OMIT = typing.cast(typing.Any, ...)
21
+
22
+
23
+ class RawSignalsClient:
24
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
25
+ self._client_wrapper = client_wrapper
26
+
27
+ def create_signals(
28
+ self, *, signals: typing.Sequence[Signal], request_options: typing.Optional[RequestOptions] = None
29
+ ) -> HttpResponse[BulkSignalsResponse]:
30
+ """
31
+ Create multiple signals (usage events) in a single request. Each signal must include a customer attribution (either customerId or externalCustomerId) and a product attribution (either productId or externalProductId).
32
+
33
+ Parameters
34
+ ----------
35
+ signals : typing.Sequence[Signal]
36
+
37
+ request_options : typing.Optional[RequestOptions]
38
+ Request-specific configuration.
39
+
40
+ Returns
41
+ -------
42
+ HttpResponse[BulkSignalsResponse]
43
+ 200
44
+ """
45
+ _response = self._client_wrapper.httpx_client.request(
46
+ "signals/bulk",
47
+ method="POST",
48
+ json={
49
+ "signals": convert_and_respect_annotation_metadata(
50
+ object_=signals, annotation=typing.Sequence[Signal], direction="write"
51
+ ),
52
+ },
53
+ headers={
54
+ "content-type": "application/json",
55
+ },
56
+ request_options=request_options,
57
+ omit=OMIT,
58
+ )
59
+ try:
60
+ if 200 <= _response.status_code < 300:
61
+ _data = typing.cast(
62
+ BulkSignalsResponse,
63
+ parse_obj_as(
64
+ type_=BulkSignalsResponse, # type: ignore
65
+ object_=_response.json(),
66
+ ),
67
+ )
68
+ return HttpResponse(response=_response, data=_data)
69
+ if _response.status_code == 400:
70
+ raise BadRequestError(
71
+ headers=dict(_response.headers),
72
+ body=typing.cast(
73
+ ErrorResponse,
74
+ parse_obj_as(
75
+ type_=ErrorResponse, # type: ignore
76
+ object_=_response.json(),
77
+ ),
78
+ ),
79
+ )
80
+ if _response.status_code == 403:
81
+ raise ForbiddenError(
82
+ headers=dict(_response.headers),
83
+ body=typing.cast(
84
+ ErrorResponse,
85
+ parse_obj_as(
86
+ type_=ErrorResponse, # type: ignore
87
+ object_=_response.json(),
88
+ ),
89
+ ),
90
+ )
91
+ if _response.status_code == 500:
92
+ raise InternalServerError(
93
+ headers=dict(_response.headers),
94
+ body=typing.cast(
95
+ ErrorResponse,
96
+ parse_obj_as(
97
+ type_=ErrorResponse, # type: ignore
98
+ object_=_response.json(),
99
+ ),
100
+ ),
101
+ )
102
+ _response_json = _response.json()
103
+ except JSONDecodeError:
104
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
105
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
106
+
107
+
108
+ class AsyncRawSignalsClient:
109
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
110
+ self._client_wrapper = client_wrapper
111
+
112
+ async def create_signals(
113
+ self, *, signals: typing.Sequence[Signal], request_options: typing.Optional[RequestOptions] = None
114
+ ) -> AsyncHttpResponse[BulkSignalsResponse]:
115
+ """
116
+ Create multiple signals (usage events) in a single request. Each signal must include a customer attribution (either customerId or externalCustomerId) and a product attribution (either productId or externalProductId).
117
+
118
+ Parameters
119
+ ----------
120
+ signals : typing.Sequence[Signal]
121
+
122
+ request_options : typing.Optional[RequestOptions]
123
+ Request-specific configuration.
124
+
125
+ Returns
126
+ -------
127
+ AsyncHttpResponse[BulkSignalsResponse]
128
+ 200
129
+ """
130
+ _response = await self._client_wrapper.httpx_client.request(
131
+ "signals/bulk",
132
+ method="POST",
133
+ json={
134
+ "signals": convert_and_respect_annotation_metadata(
135
+ object_=signals, annotation=typing.Sequence[Signal], direction="write"
136
+ ),
137
+ },
138
+ headers={
139
+ "content-type": "application/json",
140
+ },
141
+ request_options=request_options,
142
+ omit=OMIT,
143
+ )
144
+ try:
145
+ if 200 <= _response.status_code < 300:
146
+ _data = typing.cast(
147
+ BulkSignalsResponse,
148
+ parse_obj_as(
149
+ type_=BulkSignalsResponse, # type: ignore
150
+ object_=_response.json(),
151
+ ),
152
+ )
153
+ return AsyncHttpResponse(response=_response, data=_data)
154
+ if _response.status_code == 400:
155
+ raise BadRequestError(
156
+ headers=dict(_response.headers),
157
+ body=typing.cast(
158
+ ErrorResponse,
159
+ parse_obj_as(
160
+ type_=ErrorResponse, # type: ignore
161
+ object_=_response.json(),
162
+ ),
163
+ ),
164
+ )
165
+ if _response.status_code == 403:
166
+ raise ForbiddenError(
167
+ headers=dict(_response.headers),
168
+ body=typing.cast(
169
+ ErrorResponse,
170
+ parse_obj_as(
171
+ type_=ErrorResponse, # type: ignore
172
+ object_=_response.json(),
173
+ ),
174
+ ),
175
+ )
176
+ if _response.status_code == 500:
177
+ raise InternalServerError(
178
+ headers=dict(_response.headers),
179
+ body=typing.cast(
180
+ ErrorResponse,
181
+ parse_obj_as(
182
+ type_=ErrorResponse, # type: ignore
183
+ object_=_response.json(),
184
+ ),
185
+ ),
186
+ )
187
+ _response_json = _response.json()
188
+ except JSONDecodeError:
189
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
190
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
@@ -18,42 +18,48 @@ try:
18
18
  from opentelemetry.instrumentation.anthropic import AnthropicInstrumentor
19
19
 
20
20
  ANTHROPIC_AVAILABLE = True
21
- except ImportError:
21
+ except Exception:
22
+ logger.debug("Anthropic instrumentation library not available, skipping instrumentation")
22
23
  ANTHROPIC_AVAILABLE = False
23
24
 
24
25
  try:
25
26
  from opentelemetry.instrumentation.openai import OpenAIInstrumentor
26
27
 
27
28
  OPENAI_AVAILABLE = True
28
- except ImportError:
29
+ except Exception:
30
+ logger.debug("OpenAI instrumentation library not available, skipping instrumentation")
29
31
  OPENAI_AVAILABLE = False
30
32
 
31
33
  try:
32
34
  from openinference.instrumentation.openai_agents import OpenAIAgentsInstrumentor
33
35
 
34
36
  OPENAI_AGENTS_AVAILABLE = True
35
- except ImportError:
37
+ except Exception:
38
+ logger.debug("OpenAI Agents instrumentation library not available, skipping instrumentation")
36
39
  OPENAI_AGENTS_AVAILABLE = False
37
40
 
38
41
  try:
39
42
  from openinference.instrumentation.bedrock import BedrockInstrumentor
40
43
 
41
44
  BEDROCK_AVAILABLE = True
42
- except ImportError:
45
+ except Exception:
46
+ logger.debug("Bedrock instrumentation library not available, skipping instrumentation")
43
47
  BEDROCK_AVAILABLE = False
44
48
 
45
49
  try:
46
50
  from openinference.instrumentation.langchain import LangChainInstrumentor
47
51
 
48
52
  LANGCHAIN_AVAILABLE = True
49
- except ImportError:
53
+ except Exception:
54
+ logger.debug("LangChain instrumentation library not available, skipping instrumentation")
50
55
  LANGCHAIN_AVAILABLE = False
51
56
 
52
57
  try:
53
58
  from openinference.instrumentation.google_genai import GoogleGenAIInstrumentor
54
59
 
55
60
  GOOGLE_GENAI_AVAILABLE = True
56
- except ImportError:
61
+ except Exception:
62
+ logger.debug("Google GenAI instrumentation library not available, skipping instrumentation")
57
63
  GOOGLE_GENAI_AVAILABLE = False
58
64
 
59
65
 
@@ -25,9 +25,6 @@ class paid_tracing:
25
25
  The external customer ID to associate with the trace.
26
26
  external_product_id : Optional[str], optional
27
27
  The external product ID to associate with the trace, by default None.
28
- external_agent_id : Optional[str], optional
29
- **Deprecated.** Use external_product_id instead. The external agent ID to associate
30
- with the trace, by default None.
31
28
  tracing_token : Optional[int], optional
32
29
  Optional tracing token for distributed tracing, by default None.
33
30
  store_prompt : bool, optional
@@ -68,15 +65,14 @@ class paid_tracing:
68
65
  external_customer_id: Optional[str] = None,
69
66
  *,
70
67
  external_product_id: Optional[str] = None,
71
- external_agent_id: Optional[str] = None,
72
68
  tracing_token: Optional[int] = None,
73
69
  store_prompt: bool = False,
74
70
  collector_endpoint: Optional[str] = tracing.DEFAULT_COLLECTOR_ENDPOINT,
75
71
  metadata: Optional[Dict[str, Any]] = None,
76
72
  ):
77
73
  self.external_customer_id = external_customer_id
78
- # external_product_id overrides external_agent_id for backwards compatibility
79
- self.external_agent_id = external_product_id if external_product_id else external_agent_id
74
+ # Map external_product_id to external_agent_id for internal context
75
+ self.external_agent_id = external_product_id
80
76
  self.tracing_token = tracing_token
81
77
  self.store_prompt = store_prompt
82
78
  self.collector_endpoint = collector_endpoint
@@ -35,7 +35,7 @@ def generate_tracing_token() -> int:
35
35
  token = load_from_database("task_123")
36
36
  set_tracing_token(token)
37
37
 
38
- @paid_tracing(external_customer_id="cust_123", external_agent_id="agent_456")
38
+ @paid_tracing(external_customer_id="cust_123", external_product_id="product_456")
39
39
  def process_task():
40
40
  # This trace is now linked to the same token
41
41
  pass
@@ -56,7 +56,7 @@ def set_tracing_token(token: int):
56
56
  Instead of:
57
57
  token = load_from_storage("workflow_123")
58
58
  set_tracing_token(token)
59
- @paid_tracing(external_customer_id="cust_123", external_agent_id="agent_456")
59
+ @paid_tracing(external_customer_id="cust_123", external_product_id="product_456")
60
60
  def process_workflow():
61
61
  ...
62
62
  unset_tracing_token()
@@ -66,7 +66,7 @@ def set_tracing_token(token: int):
66
66
 
67
67
  @paid_tracing(
68
68
  external_customer_id="cust_123",
69
- external_agent_id="agent_456",
69
+ external_product_id="product_456",
70
70
  tracing_token=token
71
71
  )
72
72
  def process_workflow():
paid/tracing/signal.py CHANGED
@@ -37,21 +37,21 @@ def signal(event_name: str, enable_cost_tracing: bool = False, data: typing.Opti
37
37
 
38
38
  from paid.tracing import paid_tracing, signal
39
39
 
40
- @paid_tracing(external_customer_id="cust_123", external_agent_id="agent_456")
40
+ @paid_tracing(external_customer_id="cust_123", external_product_id="product_456")
41
41
  def process_order(order_id):
42
42
  # ... do work ...
43
43
  signal("order_processed", data={"order_id": order_id})
44
44
 
45
45
  Signal with cost tracking:
46
46
 
47
- @paid_tracing(external_customer_id="cust_123", external_agent_id="agent_456")
47
+ @paid_tracing(external_customer_id="cust_123", external_product_id="product_456")
48
48
  def call_ai_api():
49
49
  # ... call AI provider ...
50
50
  signal("ai_api_call_complete", enable_cost_tracing=True)
51
51
 
52
52
  Using context manager:
53
53
 
54
- with paid_tracing(external_customer_id="cust_123", external_agent_id="agent_456"):
54
+ with paid_tracing(external_customer_id="cust_123", external_product_id="product_456"):
55
55
  # ... do work ...
56
56
  signal("milestone_reached", data={"step": "validation_complete"})
57
57
  """
@@ -36,7 +36,7 @@ class PaidOpenAIAgentsHook(RunHooks[Any]):
36
36
  user_hooks: Optional user-provided RunHooks to combine with Paid tracking
37
37
 
38
38
  Usage:
39
- @paid_tracing("<ext_customer_id>", "<ext_agent_id>")
39
+ @paid_tracing("<ext_customer_id>", external_product_id="<ext_product_id>")
40
40
  def run_agent():
41
41
  hook = PaidAgentsHook()
42
42
  return Runner.run_streamed(agent, input, hooks=hook)
paid/types/__init__.py CHANGED
@@ -2,132 +2,80 @@
2
2
 
3
3
  # isort: skip_file
4
4
 
5
- from .address import Address
6
- from .agent import Agent
7
- from .agent_attribute import AgentAttribute
8
- from .agent_price_point import AgentPricePoint
9
- from .agent_price_point_tiers import AgentPricePointTiers
10
- from .agent_update import AgentUpdate
11
- from .api_error import ApiError
12
- from .billing_frequency import BillingFrequency
13
- from .cancel_renewal_response import CancelRenewalResponse
14
- from .charge_type import ChargeType
5
+ from .attribution import Attribution
6
+ from .bulk_signals_response import BulkSignalsResponse
15
7
  from .contact import Contact
16
- from .contact_create_for_customer import ContactCreateForCustomer
17
- from .cost_amount import CostAmount
18
- from .cost_trace import CostTrace
19
- from .cost_traces_response import CostTracesResponse
20
- from .creation_source import CreationSource
21
- from .creation_state import CreationState
8
+ from .contact_billing_address import ContactBillingAddress
9
+ from .contact_list_response import ContactListResponse
22
10
  from .customer import Customer
23
- from .customer_update import CustomerUpdate
24
- from .entitlement_usage import EntitlementUsage
25
- from .error import Error
11
+ from .customer_attribution import CustomerAttribution
12
+ from .customer_billing_address import CustomerBillingAddress
13
+ from .customer_by_external_id import CustomerByExternalId
14
+ from .customer_by_id import CustomerById
15
+ from .customer_creation_state import CustomerCreationState
16
+ from .customer_list_response import CustomerListResponse
17
+ from .empty_response import EmptyResponse
18
+ from .error_response import ErrorResponse
26
19
  from .invoice import Invoice
20
+ from .invoice_line import InvoiceLine
21
+ from .invoice_line_payment_status import InvoiceLinePaymentStatus
22
+ from .invoice_lines_response import InvoiceLinesResponse
23
+ from .invoice_list_response import InvoiceListResponse
24
+ from .invoice_payment_status import InvoicePaymentStatus
25
+ from .invoice_source import InvoiceSource
27
26
  from .invoice_status import InvoiceStatus
27
+ from .invoice_tax_status import InvoiceTaxStatus
28
28
  from .order import Order
29
+ from .order_creation_state import OrderCreationState
29
30
  from .order_line import OrderLine
30
- from .order_line_attribute import OrderLineAttribute
31
- from .order_line_attribute_create_one import OrderLineAttributeCreateOne
32
- from .order_line_attribute_pricing import OrderLineAttributePricing
33
- from .order_line_create import OrderLineCreate
34
- from .pagination_meta import PaginationMeta
35
- from .payment_method import PaymentMethod
36
- from .payment_method_card import PaymentMethodCard
37
- from .payment_method_type import PaymentMethodType
38
- from .payment_method_us_bank_account import PaymentMethodUsBankAccount
39
- from .payment_method_us_bank_account_account_type import PaymentMethodUsBankAccountAccountType
40
- from .plan import Plan
41
- from .plan_group import PlanGroup
42
- from .plan_plan_products_item import PlanPlanProductsItem
43
- from .plan_plan_products_item_plan_product_attribute_item import PlanPlanProductsItemPlanProductAttributeItem
44
- from .plan_with_features import PlanWithFeatures
45
- from .plan_with_features_features_item import PlanWithFeaturesFeaturesItem
46
- from .price_point import PricePoint
47
- from .pricing import Pricing
48
- from .pricing_model_type import PricingModelType
31
+ from .order_lines_response import OrderLinesResponse
32
+ from .order_list_response import OrderListResponse
33
+ from .pagination import Pagination
49
34
  from .product import Product
50
- from .product_type import ProductType
51
- from .product_update import ProductUpdate
52
- from .product_update_type import ProductUpdateType
53
- from .proration_attribute_update import ProrationAttributeUpdate
54
- from .proration_detail import ProrationDetail
55
- from .proration_upgrade_response import ProrationUpgradeResponse
56
- from .salutation import Salutation
35
+ from .product_by_external_id import ProductByExternalId
36
+ from .product_by_id import ProductById
37
+ from .product_list_response import ProductListResponse
57
38
  from .signal import Signal
58
- from .signal_v_2 import SignalV2
59
- from .tax_exempt_status import TaxExemptStatus
60
- from .tier import Tier
61
- from .trace import Trace
62
- from .traces_response import TracesResponse
63
- from .usage_pagination_meta import UsagePaginationMeta
64
- from .usage_summaries_response import UsageSummariesResponse
65
- from .usage_summary import UsageSummary
66
- from .usage_summary_order import UsageSummaryOrder
67
- from .usage_summary_order_line import UsageSummaryOrderLine
39
+ from .update_contact_request import UpdateContactRequest
40
+ from .update_customer_request import UpdateCustomerRequest
41
+ from .update_product_request import UpdateProductRequest
68
42
 
69
43
  __all__ = [
70
- "Address",
71
- "Agent",
72
- "AgentAttribute",
73
- "AgentPricePoint",
74
- "AgentPricePointTiers",
75
- "AgentUpdate",
76
- "ApiError",
77
- "BillingFrequency",
78
- "CancelRenewalResponse",
79
- "ChargeType",
44
+ "Attribution",
45
+ "BulkSignalsResponse",
80
46
  "Contact",
81
- "ContactCreateForCustomer",
82
- "CostAmount",
83
- "CostTrace",
84
- "CostTracesResponse",
85
- "CreationSource",
86
- "CreationState",
47
+ "ContactBillingAddress",
48
+ "ContactListResponse",
87
49
  "Customer",
88
- "CustomerUpdate",
89
- "EntitlementUsage",
90
- "Error",
50
+ "CustomerAttribution",
51
+ "CustomerBillingAddress",
52
+ "CustomerByExternalId",
53
+ "CustomerById",
54
+ "CustomerCreationState",
55
+ "CustomerListResponse",
56
+ "EmptyResponse",
57
+ "ErrorResponse",
91
58
  "Invoice",
59
+ "InvoiceLine",
60
+ "InvoiceLinePaymentStatus",
61
+ "InvoiceLinesResponse",
62
+ "InvoiceListResponse",
63
+ "InvoicePaymentStatus",
64
+ "InvoiceSource",
92
65
  "InvoiceStatus",
66
+ "InvoiceTaxStatus",
93
67
  "Order",
68
+ "OrderCreationState",
94
69
  "OrderLine",
95
- "OrderLineAttribute",
96
- "OrderLineAttributeCreateOne",
97
- "OrderLineAttributePricing",
98
- "OrderLineCreate",
99
- "PaginationMeta",
100
- "PaymentMethod",
101
- "PaymentMethodCard",
102
- "PaymentMethodType",
103
- "PaymentMethodUsBankAccount",
104
- "PaymentMethodUsBankAccountAccountType",
105
- "Plan",
106
- "PlanGroup",
107
- "PlanPlanProductsItem",
108
- "PlanPlanProductsItemPlanProductAttributeItem",
109
- "PlanWithFeatures",
110
- "PlanWithFeaturesFeaturesItem",
111
- "PricePoint",
112
- "Pricing",
113
- "PricingModelType",
70
+ "OrderLinesResponse",
71
+ "OrderListResponse",
72
+ "Pagination",
114
73
  "Product",
115
- "ProductType",
116
- "ProductUpdate",
117
- "ProductUpdateType",
118
- "ProrationAttributeUpdate",
119
- "ProrationDetail",
120
- "ProrationUpgradeResponse",
121
- "Salutation",
74
+ "ProductByExternalId",
75
+ "ProductById",
76
+ "ProductListResponse",
122
77
  "Signal",
123
- "SignalV2",
124
- "TaxExemptStatus",
125
- "Tier",
126
- "Trace",
127
- "TracesResponse",
128
- "UsagePaginationMeta",
129
- "UsageSummariesResponse",
130
- "UsageSummary",
131
- "UsageSummaryOrder",
132
- "UsageSummaryOrderLine",
78
+ "UpdateContactRequest",
79
+ "UpdateCustomerRequest",
80
+ "UpdateProductRequest",
133
81
  ]
@@ -0,0 +1,8 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ from .product_by_external_id import ProductByExternalId
6
+ from .product_by_id import ProductById
7
+
8
+ Attribution = typing.Union[ProductById, ProductByExternalId]