dub 0.34.0__py3-none-any.whl → 0.35.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 (93) hide show
  1. dub/_version.py +3 -3
  2. dub/basesdk.py +20 -6
  3. dub/{workspaces.py → bounties.py} +349 -69
  4. dub/models/components/__init__.py +114 -26
  5. dub/models/components/analyticsbrowsers.py +18 -1
  6. dub/models/components/analyticscities.py +18 -1
  7. dub/models/components/analyticscontinents.py +18 -1
  8. dub/models/components/analyticscount.py +18 -1
  9. dub/models/components/analyticscountries.py +20 -1
  10. dub/models/components/analyticsdevices.py +18 -1
  11. dub/models/components/analyticsos.py +18 -1
  12. dub/models/components/analyticsreferers.py +18 -1
  13. dub/models/components/analyticsrefererurls.py +18 -1
  14. dub/models/components/analyticsregions.py +18 -1
  15. dub/models/components/analyticstimeseries.py +18 -1
  16. dub/models/components/analyticstoplinks.py +16 -26
  17. dub/models/components/analyticstopurls.py +18 -1
  18. dub/models/components/analyticstriggers.py +18 -1
  19. dub/models/components/commissioncreatedevent.py +123 -63
  20. dub/models/components/domainschema.py +31 -50
  21. dub/models/components/folderschema.py +18 -19
  22. dub/models/components/leadcreatedevent.py +151 -134
  23. dub/models/components/linkclickedevent.py +57 -70
  24. dub/models/components/linkschema.py +63 -64
  25. dub/models/components/linkwebhookevent.py +43 -51
  26. dub/models/components/partneranalyticscount.py +18 -1
  27. dub/models/components/partneranalyticstimeseries.py +18 -1
  28. dub/models/components/partneranalyticstoplinks.py +16 -27
  29. dub/models/components/partnerapplicationsubmittedevent.py +42 -75
  30. dub/models/components/partnerenrolledevent.py +477 -83
  31. dub/models/components/salecreatedevent.py +152 -151
  32. dub/models/errors/badrequest.py +18 -1
  33. dub/models/errors/conflict.py +18 -1
  34. dub/models/errors/forbidden.py +18 -1
  35. dub/models/errors/internalservererror.py +18 -1
  36. dub/models/errors/inviteexpired.py +18 -1
  37. dub/models/errors/notfound.py +18 -1
  38. dub/models/errors/ratelimitexceeded.py +18 -1
  39. dub/models/errors/unauthorized.py +18 -1
  40. dub/models/errors/unprocessableentity.py +18 -1
  41. dub/models/operations/__init__.py +323 -19
  42. dub/models/operations/approvebountysubmission.py +211 -0
  43. dub/models/operations/banpartner.py +14 -19
  44. dub/models/operations/bulkcreatelinks.py +86 -87
  45. dub/models/operations/bulkupdatelinks.py +97 -82
  46. dub/models/operations/checkdomainstatus.py +1 -17
  47. dub/models/operations/createdomain.py +33 -34
  48. dub/models/operations/createfolder.py +18 -19
  49. dub/models/operations/createlink.py +86 -87
  50. dub/models/operations/createpartner.py +560 -168
  51. dub/models/operations/createpartnerlink.py +74 -85
  52. dub/models/operations/createreferralsembedtoken.py +99 -87
  53. dub/models/operations/createtag.py +18 -1
  54. dub/models/operations/deactivatepartner.py +65 -0
  55. dub/models/operations/getcustomer.py +106 -105
  56. dub/models/operations/getcustomers.py +123 -105
  57. dub/models/operations/getlinkinfo.py +18 -1
  58. dub/models/operations/getlinks.py +36 -1
  59. dub/models/operations/getlinkscount.py +32 -1
  60. dub/models/operations/getqrcode.py +29 -1
  61. dub/models/operations/gettags.py +20 -1
  62. dub/models/operations/listbountysubmissions.py +249 -0
  63. dub/models/operations/listcommissions.py +129 -64
  64. dub/models/operations/listdomains.py +18 -1
  65. dub/models/operations/listevents.py +414 -389
  66. dub/models/operations/listfolders.py +18 -1
  67. dub/models/operations/listpartners.py +510 -84
  68. dub/models/operations/registerdomain.py +1 -17
  69. dub/models/operations/rejectbountysubmission.py +219 -0
  70. dub/models/operations/retrieveanalytics.py +65 -66
  71. dub/models/operations/retrievelinks.py +30 -19
  72. dub/models/operations/retrievepartneranalytics.py +25 -28
  73. dub/models/operations/tracklead.py +38 -83
  74. dub/models/operations/tracksale.py +52 -95
  75. dub/models/operations/updatecommission.py +126 -64
  76. dub/models/operations/updatecustomer.py +122 -131
  77. dub/models/operations/updatedomain.py +50 -35
  78. dub/models/operations/updatefolder.py +34 -19
  79. dub/models/operations/updatelink.py +101 -86
  80. dub/models/operations/updatetag.py +34 -1
  81. dub/models/operations/upsertlink.py +86 -87
  82. dub/models/operations/upsertpartnerlink.py +77 -90
  83. dub/partners.py +288 -0
  84. dub/sdk.py +3 -3
  85. dub/utils/__init__.py +10 -1
  86. {dub-0.34.0.dist-info → dub-0.35.0.dist-info}/METADATA +10 -8
  87. dub-0.35.0.dist-info/RECORD +143 -0
  88. dub/models/components/workspaceschema.py +0 -328
  89. dub/models/operations/getworkspace.py +0 -21
  90. dub/models/operations/updateworkspace.py +0 -78
  91. dub-0.34.0.dist-info/RECORD +0 -142
  92. {dub-0.34.0.dist-info → dub-0.35.0.dist-info}/WHEEL +0 -0
  93. {dub-0.34.0.dist-info → dub-0.35.0.dist-info}/licenses/LICENSE +0 -0
@@ -194,6 +194,41 @@ class ListCommissionsRequest(BaseModel):
194
194
  ] = 100
195
195
  r"""The number of items per page."""
196
196
 
197
+ @model_serializer(mode="wrap")
198
+ def serialize_model(self, handler):
199
+ optional_fields = set(
200
+ [
201
+ "type",
202
+ "customerId",
203
+ "payoutId",
204
+ "partnerId",
205
+ "tenantId",
206
+ "groupId",
207
+ "invoiceId",
208
+ "status",
209
+ "sortBy",
210
+ "sortOrder",
211
+ "interval",
212
+ "start",
213
+ "end",
214
+ "timezone",
215
+ "page",
216
+ "pageSize",
217
+ ]
218
+ )
219
+ serialized = handler(self)
220
+ m = {}
221
+
222
+ for n, f in type(self).model_fields.items():
223
+ k = f.alias or n
224
+ val = serialized.get(k)
225
+
226
+ if val != UNSET_SENTINEL:
227
+ if val is not None or k not in optional_fields:
228
+ m[k] = val
229
+
230
+ return m
231
+
197
232
 
198
233
  class ListCommissionsType(str, Enum):
199
234
  CLICK = "click"
@@ -255,31 +290,28 @@ class ListCommissionsPartner(BaseModel):
255
290
 
256
291
  @model_serializer(mode="wrap")
257
292
  def serialize_model(self, handler):
258
- optional_fields = ["groupId"]
259
- nullable_fields = ["email", "image", "payoutsEnabledAt", "country", "groupId"]
260
- null_default_fields = []
261
-
293
+ optional_fields = set(["groupId"])
294
+ nullable_fields = set(
295
+ ["email", "image", "payoutsEnabledAt", "country", "groupId"]
296
+ )
262
297
  serialized = handler(self)
263
-
264
298
  m = {}
265
299
 
266
300
  for n, f in type(self).model_fields.items():
267
301
  k = f.alias or n
268
302
  val = serialized.get(k)
269
- serialized.pop(k, None)
270
-
271
- optional_nullable = k in optional_fields and k in nullable_fields
272
- is_set = (
273
- self.__pydantic_fields_set__.intersection({n})
274
- or k in null_default_fields
275
- ) # pylint: disable=no-member
276
-
277
- if val is not None and val != UNSET_SENTINEL:
278
- m[k] = val
279
- elif val != UNSET_SENTINEL and (
280
- not k in optional_fields or (optional_nullable and is_set)
281
- ):
282
- m[k] = val
303
+ is_nullable_and_explicitly_set = (
304
+ k in nullable_fields
305
+ and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
306
+ )
307
+
308
+ if val != UNSET_SENTINEL:
309
+ if (
310
+ val is not None
311
+ or k not in optional_fields
312
+ or is_nullable_and_explicitly_set
313
+ ):
314
+ m[k] = val
283
315
 
284
316
  return m
285
317
 
@@ -287,36 +319,42 @@ class ListCommissionsPartner(BaseModel):
287
319
  class ListCommissionsCustomerTypedDict(TypedDict):
288
320
  id: str
289
321
  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`)."""
290
- external_id: str
291
- r"""Unique identifier for the customer in the client's app."""
292
322
  name: str
293
323
  r"""Name of the customer."""
324
+ external_id: str
325
+ r"""Unique identifier for the customer in the client's app."""
294
326
  created_at: str
295
- r"""The date the customer was created."""
327
+ r"""The date the customer was created (usually the signup date or trial start date)."""
296
328
  email: NotRequired[Nullable[str]]
297
329
  r"""Email of the customer."""
298
330
  avatar: NotRequired[Nullable[str]]
299
331
  r"""Avatar URL of the customer."""
332
+ stripe_customer_id: NotRequired[Nullable[str]]
333
+ r"""The customer's Stripe customer ID. This is useful for attributing recurring sale events to the partner who referred the customer."""
300
334
  country: NotRequired[Nullable[str]]
301
335
  r"""Country of the customer."""
302
336
  sales: NotRequired[Nullable[float]]
303
337
  r"""Total number of sales for the customer."""
304
338
  sale_amount: NotRequired[Nullable[float]]
305
339
  r"""Total amount of sales for the customer."""
340
+ first_sale_at: NotRequired[Nullable[str]]
341
+ r"""The date the customer made their first sale. Useful for calculating the time to first sale and LTV."""
342
+ subscription_canceled_at: NotRequired[Nullable[str]]
343
+ r"""The date the customer canceled their subscription. Useful for calculating LTV and churn rate."""
306
344
 
307
345
 
308
346
  class ListCommissionsCustomer(BaseModel):
309
347
  id: str
310
348
  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`)."""
311
349
 
312
- external_id: Annotated[str, pydantic.Field(alias="externalId")]
313
- r"""Unique identifier for the customer in the client's app."""
314
-
315
350
  name: str
316
351
  r"""Name of the customer."""
317
352
 
353
+ external_id: Annotated[str, pydantic.Field(alias="externalId")]
354
+ r"""Unique identifier for the customer in the client's app."""
355
+
318
356
  created_at: Annotated[str, pydantic.Field(alias="createdAt")]
319
- r"""The date the customer was created."""
357
+ r"""The date the customer was created (usually the signup date or trial start date)."""
320
358
 
321
359
  email: OptionalNullable[str] = UNSET
322
360
  r"""Email of the customer."""
@@ -324,6 +362,11 @@ class ListCommissionsCustomer(BaseModel):
324
362
  avatar: OptionalNullable[str] = UNSET
325
363
  r"""Avatar URL of the customer."""
326
364
 
365
+ stripe_customer_id: Annotated[
366
+ OptionalNullable[str], pydantic.Field(alias="stripeCustomerId")
367
+ ] = UNSET
368
+ r"""The customer's Stripe customer ID. This is useful for attributing recurring sale events to the partner who referred the customer."""
369
+
327
370
  country: OptionalNullable[str] = UNSET
328
371
  r"""Country of the customer."""
329
372
 
@@ -335,33 +378,60 @@ class ListCommissionsCustomer(BaseModel):
335
378
  ] = UNSET
336
379
  r"""Total amount of sales for the customer."""
337
380
 
381
+ first_sale_at: Annotated[
382
+ OptionalNullable[str], pydantic.Field(alias="firstSaleAt")
383
+ ] = UNSET
384
+ r"""The date the customer made their first sale. Useful for calculating the time to first sale and LTV."""
385
+
386
+ subscription_canceled_at: Annotated[
387
+ OptionalNullable[str], pydantic.Field(alias="subscriptionCanceledAt")
388
+ ] = UNSET
389
+ r"""The date the customer canceled their subscription. Useful for calculating LTV and churn rate."""
390
+
338
391
  @model_serializer(mode="wrap")
339
392
  def serialize_model(self, handler):
340
- optional_fields = ["email", "avatar", "country", "sales", "saleAmount"]
341
- nullable_fields = ["email", "avatar", "country", "sales", "saleAmount"]
342
- null_default_fields = []
343
-
393
+ optional_fields = set(
394
+ [
395
+ "email",
396
+ "avatar",
397
+ "stripeCustomerId",
398
+ "country",
399
+ "sales",
400
+ "saleAmount",
401
+ "firstSaleAt",
402
+ "subscriptionCanceledAt",
403
+ ]
404
+ )
405
+ nullable_fields = set(
406
+ [
407
+ "email",
408
+ "avatar",
409
+ "stripeCustomerId",
410
+ "country",
411
+ "sales",
412
+ "saleAmount",
413
+ "firstSaleAt",
414
+ "subscriptionCanceledAt",
415
+ ]
416
+ )
344
417
  serialized = handler(self)
345
-
346
418
  m = {}
347
419
 
348
420
  for n, f in type(self).model_fields.items():
349
421
  k = f.alias or n
350
422
  val = serialized.get(k)
351
- serialized.pop(k, None)
352
-
353
- optional_nullable = k in optional_fields and k in nullable_fields
354
- is_set = (
355
- self.__pydantic_fields_set__.intersection({n})
356
- or k in null_default_fields
357
- ) # pylint: disable=no-member
358
-
359
- if val is not None and val != UNSET_SENTINEL:
360
- m[k] = val
361
- elif val != UNSET_SENTINEL and (
362
- not k in optional_fields or (optional_nullable and is_set)
363
- ):
364
- m[k] = val
423
+ is_nullable_and_explicitly_set = (
424
+ k in nullable_fields
425
+ and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
426
+ )
427
+
428
+ if val != UNSET_SENTINEL:
429
+ if (
430
+ val is not None
431
+ or k not in optional_fields
432
+ or is_nullable_and_explicitly_set
433
+ ):
434
+ m[k] = val
365
435
 
366
436
  return m
367
437
 
@@ -418,30 +488,25 @@ class ListCommissionsResponseBody(BaseModel):
418
488
 
419
489
  @model_serializer(mode="wrap")
420
490
  def serialize_model(self, handler):
421
- optional_fields = ["type", "userId", "customer"]
422
- nullable_fields = ["invoiceId", "description", "userId", "customer"]
423
- null_default_fields = []
424
-
491
+ optional_fields = set(["type", "userId", "customer"])
492
+ nullable_fields = set(["invoiceId", "description", "userId", "customer"])
425
493
  serialized = handler(self)
426
-
427
494
  m = {}
428
495
 
429
496
  for n, f in type(self).model_fields.items():
430
497
  k = f.alias or n
431
498
  val = serialized.get(k)
432
- serialized.pop(k, None)
433
-
434
- optional_nullable = k in optional_fields and k in nullable_fields
435
- is_set = (
436
- self.__pydantic_fields_set__.intersection({n})
437
- or k in null_default_fields
438
- ) # pylint: disable=no-member
439
-
440
- if val is not None and val != UNSET_SENTINEL:
441
- m[k] = val
442
- elif val != UNSET_SENTINEL and (
443
- not k in optional_fields or (optional_nullable and is_set)
444
- ):
445
- m[k] = val
499
+ is_nullable_and_explicitly_set = (
500
+ k in nullable_fields
501
+ and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
502
+ )
503
+
504
+ if val != UNSET_SENTINEL:
505
+ if (
506
+ val is not None
507
+ or k not in optional_fields
508
+ or is_nullable_and_explicitly_set
509
+ ):
510
+ m[k] = val
446
511
 
447
512
  return m
@@ -2,9 +2,10 @@
2
2
 
3
3
  from __future__ import annotations
4
4
  from dub.models.components import domainschema as components_domainschema
5
- from dub.types import BaseModel
5
+ from dub.types import BaseModel, UNSET_SENTINEL
6
6
  from dub.utils import FieldMetadata, QueryParamMetadata
7
7
  import pydantic
8
+ from pydantic import model_serializer
8
9
  from typing import Callable, List, Optional
9
10
  from typing_extensions import Annotated, NotRequired, TypedDict
10
11
 
@@ -46,6 +47,22 @@ class ListDomainsRequest(BaseModel):
46
47
  ] = 50
47
48
  r"""The number of items per page."""
48
49
 
50
+ @model_serializer(mode="wrap")
51
+ def serialize_model(self, handler):
52
+ optional_fields = set(["archived", "search", "page", "pageSize"])
53
+ serialized = handler(self)
54
+ m = {}
55
+
56
+ for n, f in type(self).model_fields.items():
57
+ k = f.alias or n
58
+ val = serialized.get(k)
59
+
60
+ if val != UNSET_SENTINEL:
61
+ if val is not None or k not in optional_fields:
62
+ m[k] = val
63
+
64
+ return m
65
+
49
66
 
50
67
  class ListDomainsResponseTypedDict(TypedDict):
51
68
  result: List[components_domainschema.DomainSchemaTypedDict]