paid-python 0.6.0__py3-none-any.whl → 1.0.0a1__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 (140) hide show
  1. paid/__init__.py +65 -95
  2. paid/client.py +17 -494
  3. paid/contacts/client.py +415 -133
  4. paid/contacts/raw_client.py +1046 -118
  5. paid/core/client_wrapper.py +9 -10
  6. paid/customers/client.py +270 -566
  7. paid/customers/raw_client.py +731 -537
  8. paid/environment.py +1 -1
  9. paid/errors/bad_request_error.py +2 -2
  10. paid/errors/forbidden_error.py +2 -2
  11. paid/errors/internal_server_error.py +2 -2
  12. paid/errors/not_found_error.py +2 -2
  13. paid/invoices/client.py +369 -0
  14. paid/invoices/raw_client.py +692 -0
  15. paid/orders/__init__.py +0 -3
  16. paid/orders/client.py +371 -128
  17. paid/orders/raw_client.py +829 -121
  18. paid/products/__init__.py +0 -3
  19. paid/products/client.py +129 -265
  20. paid/products/raw_client.py +563 -233
  21. paid/signals/client.py +130 -0
  22. paid/signals/raw_client.py +190 -0
  23. paid/tracing/autoinstrumentation.py +12 -6
  24. paid/tracing/context_manager.py +2 -6
  25. paid/tracing/distributed_tracing.py +3 -3
  26. paid/tracing/signal.py +3 -3
  27. paid/tracing/wrappers/openai_agents/openaiAgentsHook.py +1 -1
  28. paid/types/__init__.py +62 -86
  29. paid/types/attribution.py +8 -0
  30. paid/types/{agent_attribute.py → bulk_signals_response.py} +4 -5
  31. paid/types/contact.py +12 -20
  32. paid/types/{address.py → contact_billing_address.py} +6 -7
  33. paid/types/{traces_response.py → contact_list_response.py} +5 -9
  34. paid/types/customer.py +15 -22
  35. paid/types/customer_attribution.py +8 -0
  36. paid/types/customer_billing_address.py +26 -0
  37. paid/types/{usage_summary_order.py → customer_by_external_id.py} +3 -5
  38. paid/types/{usage_summary_order_line.py → customer_by_id.py} +3 -5
  39. paid/types/customer_creation_state.py +5 -0
  40. paid/types/customer_list_response.py +22 -0
  41. paid/types/empty_response.py +17 -0
  42. paid/types/{error.py → error_response.py} +4 -7
  43. paid/types/invoice.py +57 -0
  44. paid/types/invoice_line.py +42 -0
  45. paid/types/invoice_line_payment_status.py +7 -0
  46. paid/types/invoice_lines_response.py +22 -0
  47. paid/types/invoice_list_response.py +22 -0
  48. paid/types/invoice_payment_status.py +5 -0
  49. paid/types/invoice_source.py +5 -0
  50. paid/types/invoice_status.py +7 -0
  51. paid/types/invoice_tax_status.py +7 -0
  52. paid/types/order.py +30 -29
  53. paid/types/order_creation_state.py +5 -0
  54. paid/types/order_line.py +6 -24
  55. paid/types/order_lines_response.py +22 -0
  56. paid/types/order_list_response.py +22 -0
  57. paid/types/pagination.py +24 -0
  58. paid/types/product.py +4 -29
  59. paid/types/{tier.py → product_by_external_id.py} +5 -4
  60. paid/types/{cost_amount.py → product_by_id.py} +5 -12
  61. paid/types/product_list_response.py +22 -0
  62. paid/types/signal.py +8 -34
  63. paid/types/{agent.py → update_contact_request.py} +10 -11
  64. paid/types/update_customer_request.py +38 -0
  65. paid/types/{product_update.py → update_product_request.py} +2 -12
  66. {paid_python-0.6.0.dist-info → paid_python-1.0.0a1.dist-info}/METADATA +27 -11
  67. paid_python-1.0.0a1.dist-info/RECORD +110 -0
  68. opentelemetry/instrumentation/openai/__init__.py +0 -54
  69. opentelemetry/instrumentation/openai/shared/__init__.py +0 -399
  70. opentelemetry/instrumentation/openai/shared/audio_wrappers.py +0 -247
  71. opentelemetry/instrumentation/openai/shared/chat_wrappers.py +0 -1192
  72. opentelemetry/instrumentation/openai/shared/completion_wrappers.py +0 -292
  73. opentelemetry/instrumentation/openai/shared/config.py +0 -15
  74. opentelemetry/instrumentation/openai/shared/embeddings_wrappers.py +0 -311
  75. opentelemetry/instrumentation/openai/shared/event_emitter.py +0 -108
  76. opentelemetry/instrumentation/openai/shared/event_models.py +0 -41
  77. opentelemetry/instrumentation/openai/shared/image_gen_wrappers.py +0 -68
  78. opentelemetry/instrumentation/openai/shared/span_utils.py +0 -0
  79. opentelemetry/instrumentation/openai/utils.py +0 -213
  80. opentelemetry/instrumentation/openai/v0/__init__.py +0 -176
  81. opentelemetry/instrumentation/openai/v1/__init__.py +0 -394
  82. opentelemetry/instrumentation/openai/v1/assistant_wrappers.py +0 -329
  83. opentelemetry/instrumentation/openai/v1/event_handler_wrapper.py +0 -134
  84. opentelemetry/instrumentation/openai/v1/responses_wrappers.py +0 -1113
  85. opentelemetry/instrumentation/openai/version.py +0 -1
  86. paid/agents/client.py +0 -880
  87. paid/agents/raw_client.py +0 -785
  88. paid/orders/lines/client.py +0 -144
  89. paid/orders/lines/raw_client.py +0 -129
  90. paid/plans/__init__.py +0 -4
  91. paid/plans/client.py +0 -332
  92. paid/plans/raw_client.py +0 -464
  93. paid/products/types/__init__.py +0 -7
  94. paid/products/types/product_create_type.py +0 -5
  95. paid/traces/__init__.py +0 -4
  96. paid/traces/client.py +0 -218
  97. paid/traces/raw_client.py +0 -226
  98. paid/types/agent_price_point.py +0 -27
  99. paid/types/agent_price_point_tiers.py +0 -23
  100. paid/types/agent_update.py +0 -29
  101. paid/types/api_error.py +0 -29
  102. paid/types/billing_frequency.py +0 -5
  103. paid/types/charge_type.py +0 -5
  104. paid/types/cost_trace.py +0 -55
  105. paid/types/cost_traces_response.py +0 -26
  106. paid/types/creation_source.py +0 -5
  107. paid/types/creation_state.py +0 -5
  108. paid/types/customer_update.py +0 -40
  109. paid/types/entitlement_usage.py +0 -48
  110. paid/types/order_line_attribute.py +0 -27
  111. paid/types/order_line_attribute_create_one.py +0 -5
  112. paid/types/order_line_attribute_pricing.py +0 -33
  113. paid/types/order_line_create.py +0 -72
  114. paid/types/pagination_meta.py +0 -84
  115. paid/types/plan.py +0 -81
  116. paid/types/plan_group.py +0 -60
  117. paid/types/plan_plan_products_item.py +0 -35
  118. paid/types/plan_plan_products_item_plan_product_attribute_item.py +0 -34
  119. paid/types/price_point.py +0 -25
  120. paid/types/pricing.py +0 -31
  121. paid/types/pricing_model_type.py +0 -7
  122. paid/types/product_type.py +0 -5
  123. paid/types/product_update_type.py +0 -5
  124. paid/types/salutation.py +0 -5
  125. paid/types/signal_v_2.py +0 -56
  126. paid/types/tax_exempt_status.py +0 -5
  127. paid/types/trace.py +0 -69
  128. paid/types/usage_pagination_meta.py +0 -43
  129. paid/types/usage_summaries_response.py +0 -26
  130. paid/types/usage_summary.py +0 -121
  131. paid/usage/__init__.py +0 -7
  132. paid/usage/client.py +0 -321
  133. paid/usage/raw_client.py +0 -387
  134. paid/usage/types/__init__.py +0 -7
  135. paid/usage/types/usage_check_usage_response.py +0 -53
  136. paid_python-0.6.0.dist-info/RECORD +0 -153
  137. /paid/{agents → invoices}/__init__.py +0 -0
  138. /paid/{orders/lines → signals}/__init__.py +0 -0
  139. {paid_python-0.6.0.dist-info → paid_python-1.0.0a1.dist-info}/LICENSE +0 -0
  140. {paid_python-0.6.0.dist-info → paid_python-1.0.0a1.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_in_bulk(
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_in_bulk(
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_in_bulk(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_in_bulk(
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_in_bulk(
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_in_bulk(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_in_bulk(
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_in_bulk(
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,104 +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 .charge_type import ChargeType
5
+ from .attribution import Attribution
6
+ from .bulk_signals_response import BulkSignalsResponse
14
7
  from .contact import Contact
15
- from .cost_amount import CostAmount
16
- from .cost_trace import CostTrace
17
- from .cost_traces_response import CostTracesResponse
18
- from .creation_source import CreationSource
19
- from .creation_state import CreationState
8
+ from .contact_billing_address import ContactBillingAddress
9
+ from .contact_list_response import ContactListResponse
20
10
  from .customer import Customer
21
- from .customer_update import CustomerUpdate
22
- from .entitlement_usage import EntitlementUsage
23
- 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
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
26
+ from .invoice_status import InvoiceStatus
27
+ from .invoice_tax_status import InvoiceTaxStatus
24
28
  from .order import Order
29
+ from .order_creation_state import OrderCreationState
25
30
  from .order_line import OrderLine
26
- from .order_line_attribute import OrderLineAttribute
27
- from .order_line_attribute_create_one import OrderLineAttributeCreateOne
28
- from .order_line_attribute_pricing import OrderLineAttributePricing
29
- from .order_line_create import OrderLineCreate
30
- from .pagination_meta import PaginationMeta
31
- from .plan import Plan
32
- from .plan_group import PlanGroup
33
- from .plan_plan_products_item import PlanPlanProductsItem
34
- from .plan_plan_products_item_plan_product_attribute_item import PlanPlanProductsItemPlanProductAttributeItem
35
- from .price_point import PricePoint
36
- from .pricing import Pricing
37
- 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
38
34
  from .product import Product
39
- from .product_type import ProductType
40
- from .product_update import ProductUpdate
41
- from .product_update_type import ProductUpdateType
42
- 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
43
38
  from .signal import Signal
44
- from .signal_v_2 import SignalV2
45
- from .tax_exempt_status import TaxExemptStatus
46
- from .tier import Tier
47
- from .trace import Trace
48
- from .traces_response import TracesResponse
49
- from .usage_pagination_meta import UsagePaginationMeta
50
- from .usage_summaries_response import UsageSummariesResponse
51
- from .usage_summary import UsageSummary
52
- from .usage_summary_order import UsageSummaryOrder
53
- 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
54
42
 
55
43
  __all__ = [
56
- "Address",
57
- "Agent",
58
- "AgentAttribute",
59
- "AgentPricePoint",
60
- "AgentPricePointTiers",
61
- "AgentUpdate",
62
- "ApiError",
63
- "BillingFrequency",
64
- "ChargeType",
44
+ "Attribution",
45
+ "BulkSignalsResponse",
65
46
  "Contact",
66
- "CostAmount",
67
- "CostTrace",
68
- "CostTracesResponse",
69
- "CreationSource",
70
- "CreationState",
47
+ "ContactBillingAddress",
48
+ "ContactListResponse",
71
49
  "Customer",
72
- "CustomerUpdate",
73
- "EntitlementUsage",
74
- "Error",
50
+ "CustomerAttribution",
51
+ "CustomerBillingAddress",
52
+ "CustomerByExternalId",
53
+ "CustomerById",
54
+ "CustomerCreationState",
55
+ "CustomerListResponse",
56
+ "EmptyResponse",
57
+ "ErrorResponse",
58
+ "Invoice",
59
+ "InvoiceLine",
60
+ "InvoiceLinePaymentStatus",
61
+ "InvoiceLinesResponse",
62
+ "InvoiceListResponse",
63
+ "InvoicePaymentStatus",
64
+ "InvoiceSource",
65
+ "InvoiceStatus",
66
+ "InvoiceTaxStatus",
75
67
  "Order",
68
+ "OrderCreationState",
76
69
  "OrderLine",
77
- "OrderLineAttribute",
78
- "OrderLineAttributeCreateOne",
79
- "OrderLineAttributePricing",
80
- "OrderLineCreate",
81
- "PaginationMeta",
82
- "Plan",
83
- "PlanGroup",
84
- "PlanPlanProductsItem",
85
- "PlanPlanProductsItemPlanProductAttributeItem",
86
- "PricePoint",
87
- "Pricing",
88
- "PricingModelType",
70
+ "OrderLinesResponse",
71
+ "OrderListResponse",
72
+ "Pagination",
89
73
  "Product",
90
- "ProductType",
91
- "ProductUpdate",
92
- "ProductUpdateType",
93
- "Salutation",
74
+ "ProductByExternalId",
75
+ "ProductById",
76
+ "ProductListResponse",
94
77
  "Signal",
95
- "SignalV2",
96
- "TaxExemptStatus",
97
- "Tier",
98
- "Trace",
99
- "TracesResponse",
100
- "UsagePaginationMeta",
101
- "UsageSummariesResponse",
102
- "UsageSummary",
103
- "UsageSummaryOrder",
104
- "UsageSummaryOrderLine",
78
+ "UpdateContactRequest",
79
+ "UpdateCustomerRequest",
80
+ "UpdateProductRequest",
105
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]
@@ -4,13 +4,12 @@ import typing
4
4
 
5
5
  import pydantic
6
6
  from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
- from .pricing import Pricing
8
7
 
9
8
 
10
- class AgentAttribute(UniversalBaseModel):
11
- name: str
12
- active: bool
13
- pricing: Pricing
9
+ class BulkSignalsResponse(UniversalBaseModel):
10
+ ingested: int
11
+ duplicates: int
12
+ failed: int
14
13
 
15
14
  if IS_PYDANTIC_V2:
16
15
  model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2