dub 0.27.1__py3-none-any.whl → 0.27.3__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 (38) hide show
  1. dub/_version.py +3 -3
  2. dub/models/components/__init__.py +41 -2
  3. dub/models/components/analyticstriggers.py +2 -0
  4. dub/models/components/clickevent.py +92 -47
  5. dub/models/components/commissioncreatedevent.py +281 -0
  6. dub/models/components/leadcreatedevent.py +66 -21
  7. dub/models/components/leadevent.py +126 -48
  8. dub/models/components/linkclickedevent.py +66 -21
  9. dub/models/components/linkschema.py +26 -20
  10. dub/models/components/linkwebhookevent.py +33 -21
  11. dub/models/components/partnerenrolledevent.py +207 -80
  12. dub/models/components/salecreatedevent.py +66 -21
  13. dub/models/components/saleevent.py +206 -122
  14. dub/models/components/webhookevent.py +6 -0
  15. dub/models/errors/__init__.py +3 -2
  16. dub/models/operations/__init__.py +71 -2
  17. dub/models/operations/bulkcreatelinks.py +25 -25
  18. dub/models/operations/bulkupdatelinks.py +25 -25
  19. dub/models/operations/createlink.py +25 -25
  20. dub/models/operations/createpartner.py +207 -80
  21. dub/models/operations/getlinks.py +2 -2
  22. dub/models/operations/getlinkscount.py +2 -2
  23. dub/models/operations/listcommissions.py +169 -8
  24. dub/models/operations/listevents.py +48 -20
  25. dub/models/operations/listpartners.py +516 -0
  26. dub/models/operations/retrieveanalytics.py +48 -20
  27. dub/models/operations/retrievelinks.py +6 -6
  28. dub/models/operations/tracksale.py +1 -0
  29. dub/models/operations/updatecommission.py +169 -8
  30. dub/models/operations/updatelink.py +25 -25
  31. dub/models/operations/upsertlink.py +25 -25
  32. dub/partners.py +262 -0
  33. dub/sdk.py +1 -1
  34. dub/utils/__init__.py +3 -2
  35. {dub-0.27.1.dist-info → dub-0.27.3.dist-info}/METADATA +3 -2
  36. {dub-0.27.1.dist-info → dub-0.27.3.dist-info}/RECORD +38 -36
  37. {dub-0.27.1.dist-info → dub-0.27.3.dist-info}/LICENSE +0 -0
  38. {dub-0.27.1.dist-info → dub-0.27.3.dist-info}/WHEEL +0 -0
@@ -0,0 +1,281 @@
1
+ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
2
+
3
+ from __future__ import annotations
4
+ from dub.types import BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL
5
+ from enum import Enum
6
+ import pydantic
7
+ from pydantic import model_serializer
8
+ from typing import Optional
9
+ from typing_extensions import Annotated, NotRequired, TypedDict
10
+
11
+
12
+ class CommissionCreatedEventEvent(str, Enum):
13
+ COMMISSION_CREATED = "commission.created"
14
+
15
+
16
+ class CommissionCreatedEventType(str, Enum):
17
+ CLICK = "click"
18
+ LEAD = "lead"
19
+ SALE = "sale"
20
+ CUSTOM = "custom"
21
+
22
+
23
+ class CommissionCreatedEventStatus(str, Enum):
24
+ PENDING = "pending"
25
+ PROCESSED = "processed"
26
+ PAID = "paid"
27
+ REFUNDED = "refunded"
28
+ DUPLICATE = "duplicate"
29
+ FRAUD = "fraud"
30
+ CANCELED = "canceled"
31
+
32
+
33
+ class PartnerTypedDict(TypedDict):
34
+ id: str
35
+ r"""The partner's unique ID on Dub."""
36
+ name: str
37
+ r"""The partner's full legal name."""
38
+ email: Nullable[str]
39
+ r"""The partner's email address. Should be a unique value across Dub."""
40
+ image: Nullable[str]
41
+ r"""The partner's avatar image."""
42
+ payouts_enabled_at: Nullable[str]
43
+ r"""The date when the partner enabled payouts."""
44
+ country: Nullable[str]
45
+ r"""The partner's country (required for tax purposes)."""
46
+
47
+
48
+ class Partner(BaseModel):
49
+ id: str
50
+ r"""The partner's unique ID on Dub."""
51
+
52
+ name: str
53
+ r"""The partner's full legal name."""
54
+
55
+ email: Nullable[str]
56
+ r"""The partner's email address. Should be a unique value across Dub."""
57
+
58
+ image: Nullable[str]
59
+ r"""The partner's avatar image."""
60
+
61
+ payouts_enabled_at: Annotated[
62
+ Nullable[str], pydantic.Field(alias="payoutsEnabledAt")
63
+ ]
64
+ r"""The date when the partner enabled payouts."""
65
+
66
+ country: Nullable[str]
67
+ r"""The partner's country (required for tax purposes)."""
68
+
69
+ @model_serializer(mode="wrap")
70
+ def serialize_model(self, handler):
71
+ optional_fields = []
72
+ nullable_fields = ["email", "image", "payoutsEnabledAt", "country"]
73
+ null_default_fields = []
74
+
75
+ serialized = handler(self)
76
+
77
+ m = {}
78
+
79
+ for n, f in type(self).model_fields.items():
80
+ k = f.alias or n
81
+ val = serialized.get(k)
82
+ serialized.pop(k, None)
83
+
84
+ optional_nullable = k in optional_fields and k in nullable_fields
85
+ is_set = (
86
+ self.__pydantic_fields_set__.intersection({n})
87
+ or k in null_default_fields
88
+ ) # pylint: disable=no-member
89
+
90
+ if val is not None and val != UNSET_SENTINEL:
91
+ m[k] = val
92
+ elif val != UNSET_SENTINEL and (
93
+ not k in optional_fields or (optional_nullable and is_set)
94
+ ):
95
+ m[k] = val
96
+
97
+ return m
98
+
99
+
100
+ class CommissionCreatedEventCustomerTypedDict(TypedDict):
101
+ id: str
102
+ r"""The unique ID of the customer. You may use either the customer's `id` on Dub (obtained via `/customers` endpoint) or their `externalId` (unique ID within your system, prefixed with `ext_`, e.g. `ext_123`)."""
103
+ external_id: str
104
+ r"""Unique identifier for the customer in the client's app."""
105
+ name: str
106
+ r"""Name of the customer."""
107
+ created_at: str
108
+ r"""The date the customer was created."""
109
+ email: NotRequired[Nullable[str]]
110
+ r"""Email of the customer."""
111
+ avatar: NotRequired[Nullable[str]]
112
+ r"""Avatar URL of the customer."""
113
+ country: NotRequired[Nullable[str]]
114
+ r"""Country of the customer."""
115
+ sales: NotRequired[Nullable[float]]
116
+ r"""Total number of sales for the customer."""
117
+ sale_amount: NotRequired[Nullable[float]]
118
+ r"""Total amount of sales for the customer."""
119
+
120
+
121
+ class CommissionCreatedEventCustomer(BaseModel):
122
+ id: str
123
+ r"""The unique ID of the customer. You may use either the customer's `id` on Dub (obtained via `/customers` endpoint) or their `externalId` (unique ID within your system, prefixed with `ext_`, e.g. `ext_123`)."""
124
+
125
+ external_id: Annotated[str, pydantic.Field(alias="externalId")]
126
+ r"""Unique identifier for the customer in the client's app."""
127
+
128
+ name: str
129
+ r"""Name of the customer."""
130
+
131
+ created_at: Annotated[str, pydantic.Field(alias="createdAt")]
132
+ r"""The date the customer was created."""
133
+
134
+ email: OptionalNullable[str] = UNSET
135
+ r"""Email of the customer."""
136
+
137
+ avatar: OptionalNullable[str] = UNSET
138
+ r"""Avatar URL of the customer."""
139
+
140
+ country: OptionalNullable[str] = UNSET
141
+ r"""Country of the customer."""
142
+
143
+ sales: OptionalNullable[float] = UNSET
144
+ r"""Total number of sales for the customer."""
145
+
146
+ sale_amount: Annotated[
147
+ OptionalNullable[float], pydantic.Field(alias="saleAmount")
148
+ ] = UNSET
149
+ r"""Total amount of sales for the customer."""
150
+
151
+ @model_serializer(mode="wrap")
152
+ def serialize_model(self, handler):
153
+ optional_fields = ["email", "avatar", "country", "sales", "saleAmount"]
154
+ nullable_fields = ["email", "avatar", "country", "sales", "saleAmount"]
155
+ null_default_fields = []
156
+
157
+ serialized = handler(self)
158
+
159
+ m = {}
160
+
161
+ for n, f in type(self).model_fields.items():
162
+ k = f.alias or n
163
+ val = serialized.get(k)
164
+ serialized.pop(k, None)
165
+
166
+ optional_nullable = k in optional_fields and k in nullable_fields
167
+ is_set = (
168
+ self.__pydantic_fields_set__.intersection({n})
169
+ or k in null_default_fields
170
+ ) # pylint: disable=no-member
171
+
172
+ if val is not None and val != UNSET_SENTINEL:
173
+ m[k] = val
174
+ elif val != UNSET_SENTINEL and (
175
+ not k in optional_fields or (optional_nullable and is_set)
176
+ ):
177
+ m[k] = val
178
+
179
+ return m
180
+
181
+
182
+ class CommissionCreatedEventDataTypedDict(TypedDict):
183
+ id: str
184
+ r"""The commission's unique ID on Dub."""
185
+ amount: float
186
+ earnings: float
187
+ currency: str
188
+ status: CommissionCreatedEventStatus
189
+ invoice_id: Nullable[str]
190
+ description: Nullable[str]
191
+ quantity: float
192
+ created_at: str
193
+ updated_at: str
194
+ partner: PartnerTypedDict
195
+ type: NotRequired[CommissionCreatedEventType]
196
+ user_id: NotRequired[Nullable[str]]
197
+ r"""The user who created the manual commission."""
198
+ customer: NotRequired[Nullable[CommissionCreatedEventCustomerTypedDict]]
199
+
200
+
201
+ class CommissionCreatedEventData(BaseModel):
202
+ id: str
203
+ r"""The commission's unique ID on Dub."""
204
+
205
+ amount: float
206
+
207
+ earnings: float
208
+
209
+ currency: str
210
+
211
+ status: CommissionCreatedEventStatus
212
+
213
+ invoice_id: Annotated[Nullable[str], pydantic.Field(alias="invoiceId")]
214
+
215
+ description: Nullable[str]
216
+
217
+ quantity: float
218
+
219
+ created_at: Annotated[str, pydantic.Field(alias="createdAt")]
220
+
221
+ updated_at: Annotated[str, pydantic.Field(alias="updatedAt")]
222
+
223
+ partner: Partner
224
+
225
+ type: Optional[CommissionCreatedEventType] = None
226
+
227
+ user_id: Annotated[OptionalNullable[str], pydantic.Field(alias="userId")] = UNSET
228
+ r"""The user who created the manual commission."""
229
+
230
+ customer: OptionalNullable[CommissionCreatedEventCustomer] = UNSET
231
+
232
+ @model_serializer(mode="wrap")
233
+ def serialize_model(self, handler):
234
+ optional_fields = ["type", "userId", "customer"]
235
+ nullable_fields = ["invoiceId", "description", "userId", "customer"]
236
+ null_default_fields = []
237
+
238
+ serialized = handler(self)
239
+
240
+ m = {}
241
+
242
+ for n, f in type(self).model_fields.items():
243
+ k = f.alias or n
244
+ val = serialized.get(k)
245
+ serialized.pop(k, None)
246
+
247
+ optional_nullable = k in optional_fields and k in nullable_fields
248
+ is_set = (
249
+ self.__pydantic_fields_set__.intersection({n})
250
+ or k in null_default_fields
251
+ ) # pylint: disable=no-member
252
+
253
+ if val is not None and val != UNSET_SENTINEL:
254
+ m[k] = val
255
+ elif val != UNSET_SENTINEL and (
256
+ not k in optional_fields or (optional_nullable and is_set)
257
+ ):
258
+ m[k] = val
259
+
260
+ return m
261
+
262
+
263
+ class CommissionCreatedEventTypedDict(TypedDict):
264
+ r"""Triggered when a commission is created for a partner."""
265
+
266
+ id: str
267
+ event: CommissionCreatedEventEvent
268
+ created_at: str
269
+ data: CommissionCreatedEventDataTypedDict
270
+
271
+
272
+ class CommissionCreatedEvent(BaseModel):
273
+ r"""Triggered when a commission is created for a partner."""
274
+
275
+ id: str
276
+
277
+ event: CommissionCreatedEventEvent
278
+
279
+ created_at: Annotated[str, pydantic.Field(alias="createdAt")]
280
+
281
+ data: CommissionCreatedEventData
@@ -111,6 +111,7 @@ class LeadCreatedEventClickTypedDict(TypedDict):
111
111
  referer_url: str
112
112
  qr: bool
113
113
  ip: str
114
+ trigger: NotRequired[Nullable[str]]
114
115
 
115
116
 
116
117
  class LeadCreatedEventClick(BaseModel):
@@ -142,6 +143,38 @@ class LeadCreatedEventClick(BaseModel):
142
143
 
143
144
  ip: str
144
145
 
146
+ trigger: OptionalNullable[str] = UNSET
147
+
148
+ @model_serializer(mode="wrap")
149
+ def serialize_model(self, handler):
150
+ optional_fields = ["trigger"]
151
+ nullable_fields = ["trigger"]
152
+ null_default_fields = []
153
+
154
+ serialized = handler(self)
155
+
156
+ m = {}
157
+
158
+ for n, f in type(self).model_fields.items():
159
+ k = f.alias or n
160
+ val = serialized.get(k)
161
+ serialized.pop(k, None)
162
+
163
+ optional_nullable = k in optional_fields and k in nullable_fields
164
+ is_set = (
165
+ self.__pydantic_fields_set__.intersection({n})
166
+ or k in null_default_fields
167
+ ) # pylint: disable=no-member
168
+
169
+ if val is not None and val != UNSET_SENTINEL:
170
+ m[k] = val
171
+ elif val != UNSET_SENTINEL and (
172
+ not k in optional_fields or (optional_nullable and is_set)
173
+ ):
174
+ m[k] = val
175
+
176
+ return m
177
+
145
178
 
146
179
  class LeadCreatedEventGeoTypedDict(TypedDict):
147
180
  r"""Geo targeting information for the short link in JSON format `{[COUNTRY]: https://example.com }`. Learn more: https://d.to/geo"""
@@ -953,8 +986,6 @@ class LeadCreatedEventLinkTypedDict(TypedDict):
953
986
  geo: Nullable[LeadCreatedEventGeoTypedDict]
954
987
  r"""Geo targeting information for the short link in JSON format `{[COUNTRY]: https://example.com }`. Learn more: https://d.to/geo"""
955
988
  public_stats: bool
956
- tag_id: Nullable[str]
957
- r"""The unique ID of the tag assigned to the short link. This field is deprecated – use `tags` instead."""
958
989
  tags: Nullable[List[TagSchemaTypedDict]]
959
990
  r"""The tags assigned to the short link."""
960
991
  folder_id: Nullable[str]
@@ -985,18 +1016,22 @@ class LeadCreatedEventLinkTypedDict(TypedDict):
985
1016
  last_clicked: str
986
1017
  created_at: str
987
1018
  updated_at: str
1019
+ tag_id: Nullable[str]
1020
+ r"""Deprecated: Use `tags` instead. The unique ID of the tag assigned to the short link."""
988
1021
  project_id: str
989
- r"""The project ID of the short link. This field is deprecated – use `workspaceId` instead."""
1022
+ r"""Deprecated: Use `workspaceId` instead. The project ID of the short link."""
990
1023
  test_variants: NotRequired[Nullable[List[LeadCreatedEventTestVariantsTypedDict]]]
991
1024
  r"""An array of A/B test URLs and the percentage of traffic to send to each URL."""
992
1025
  clicks: NotRequired[float]
993
1026
  r"""The number of clicks on the short link."""
994
1027
  leads: NotRequired[float]
995
- r"""The number of leads the short links has generated."""
1028
+ r"""The number of leads the short link has generated."""
1029
+ conversions: NotRequired[float]
1030
+ r"""The number of leads that converted to paying customers."""
996
1031
  sales: NotRequired[float]
997
- r"""The number of sales the short links has generated."""
1032
+ r"""The total number of sales (includes recurring sales) generated by the short link."""
998
1033
  sale_amount: NotRequired[float]
999
- r"""The total dollar amount of sales the short links has generated (in cents)."""
1034
+ r"""The total dollar value of sales (in cents) generated by the short link."""
1000
1035
 
1001
1036
 
1002
1037
  class LeadCreatedEventLink(BaseModel):
@@ -1063,15 +1098,6 @@ class LeadCreatedEventLink(BaseModel):
1063
1098
 
1064
1099
  public_stats: Annotated[bool, pydantic.Field(alias="publicStats")]
1065
1100
 
1066
- tag_id: Annotated[
1067
- Nullable[str],
1068
- pydantic.Field(
1069
- deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible.",
1070
- alias="tagId",
1071
- ),
1072
- ]
1073
- r"""The unique ID of the tag assigned to the short link. This field is deprecated – use `tags` instead."""
1074
-
1075
1101
  tags: Nullable[List[TagSchema]]
1076
1102
  r"""The tags assigned to the short link."""
1077
1103
 
@@ -1120,6 +1146,15 @@ class LeadCreatedEventLink(BaseModel):
1120
1146
 
1121
1147
  updated_at: Annotated[str, pydantic.Field(alias="updatedAt")]
1122
1148
 
1149
+ tag_id: Annotated[
1150
+ Nullable[str],
1151
+ pydantic.Field(
1152
+ deprecated="warning: ** DEPRECATED ** - This will be removed in a future release, please migrate away from it as soon as possible.",
1153
+ alias="tagId",
1154
+ ),
1155
+ ]
1156
+ r"""Deprecated: Use `tags` instead. The unique ID of the tag assigned to the short link."""
1157
+
1123
1158
  project_id: Annotated[
1124
1159
  str,
1125
1160
  pydantic.Field(
@@ -1127,7 +1162,7 @@ class LeadCreatedEventLink(BaseModel):
1127
1162
  alias="projectId",
1128
1163
  ),
1129
1164
  ]
1130
- r"""The project ID of the short link. This field is deprecated – use `workspaceId` instead."""
1165
+ r"""Deprecated: Use `workspaceId` instead. The project ID of the short link."""
1131
1166
 
1132
1167
  test_variants: Annotated[
1133
1168
  OptionalNullable[List[LeadCreatedEventTestVariants]],
@@ -1139,17 +1174,27 @@ class LeadCreatedEventLink(BaseModel):
1139
1174
  r"""The number of clicks on the short link."""
1140
1175
 
1141
1176
  leads: Optional[float] = 0
1142
- r"""The number of leads the short links has generated."""
1177
+ r"""The number of leads the short link has generated."""
1178
+
1179
+ conversions: Optional[float] = 0
1180
+ r"""The number of leads that converted to paying customers."""
1143
1181
 
1144
1182
  sales: Optional[float] = 0
1145
- r"""The number of sales the short links has generated."""
1183
+ r"""The total number of sales (includes recurring sales) generated by the short link."""
1146
1184
 
1147
1185
  sale_amount: Annotated[Optional[float], pydantic.Field(alias="saleAmount")] = 0
1148
- r"""The total dollar amount of sales the short links has generated (in cents)."""
1186
+ r"""The total dollar value of sales (in cents) generated by the short link."""
1149
1187
 
1150
1188
  @model_serializer(mode="wrap")
1151
1189
  def serialize_model(self, handler):
1152
- optional_fields = ["testVariants", "clicks", "leads", "sales", "saleAmount"]
1190
+ optional_fields = [
1191
+ "testVariants",
1192
+ "clicks",
1193
+ "leads",
1194
+ "conversions",
1195
+ "sales",
1196
+ "saleAmount",
1197
+ ]
1153
1198
  nullable_fields = [
1154
1199
  "externalId",
1155
1200
  "tenantId",
@@ -1164,7 +1209,6 @@ class LeadCreatedEventLink(BaseModel):
1164
1209
  "ios",
1165
1210
  "android",
1166
1211
  "geo",
1167
- "tagId",
1168
1212
  "tags",
1169
1213
  "folderId",
1170
1214
  "comments",
@@ -1177,6 +1221,7 @@ class LeadCreatedEventLink(BaseModel):
1177
1221
  "testStartedAt",
1178
1222
  "testCompletedAt",
1179
1223
  "userId",
1224
+ "tagId",
1180
1225
  ]
1181
1226
  null_default_fields = []
1182
1227