dub 0.32.0__py3-none-any.whl → 0.33.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 (45) hide show
  1. dub/_version.py +3 -3
  2. dub/analytics.py +4 -4
  3. dub/commissions.py +8 -8
  4. dub/customers.py +16 -313
  5. dub/domains.py +22 -26
  6. dub/embed_tokens.py +4 -4
  7. dub/events.py +4 -4
  8. dub/folders.py +16 -20
  9. dub/links.py +38 -54
  10. dub/models/components/__init__.py +32 -0
  11. dub/models/components/analyticstopurls.py +2 -2
  12. dub/models/components/clickevent.py +7 -6
  13. dub/models/components/leadcreatedevent.py +7 -6
  14. dub/models/components/leadevent.py +7 -6
  15. dub/models/components/linkclickedevent.py +7 -6
  16. dub/models/components/linkschema.py +6 -0
  17. dub/models/components/linkwebhookevent.py +7 -6
  18. dub/models/components/partnerapplicationsubmittedevent.py +269 -0
  19. dub/models/components/partnerenrolledevent.py +64 -4
  20. dub/models/components/salecreatedevent.py +7 -6
  21. dub/models/components/saleevent.py +7 -6
  22. dub/models/components/webhookevent.py +6 -0
  23. dub/models/components/workspaceschema.py +6 -0
  24. dub/models/operations/__init__.py +17 -35
  25. dub/models/operations/banpartner.py +83 -0
  26. dub/models/operations/createpartner.py +64 -4
  27. dub/models/operations/listcommissions.py +13 -2
  28. dub/models/operations/listevents.py +10 -0
  29. dub/models/operations/listpartners.py +71 -4
  30. dub/models/operations/retrieveanalytics.py +12 -0
  31. dub/models/operations/retrievelinks.py +42 -7
  32. dub/models/operations/retrievepartneranalytics.py +51 -11
  33. dub/models/operations/updatecommission.py +7 -2
  34. dub/partners.py +298 -24
  35. dub/qr_codes.py +2 -2
  36. dub/tags.py +16 -24
  37. dub/track.py +8 -16
  38. dub/utils/retries.py +69 -5
  39. dub/utils/unmarshal_json_response.py +15 -1
  40. dub/workspaces.py +8 -16
  41. {dub-0.32.0.dist-info → dub-0.33.0.dist-info}/METADATA +2 -20
  42. {dub-0.32.0.dist-info → dub-0.33.0.dist-info}/RECORD +44 -43
  43. dub/models/operations/createcustomer.py +0 -382
  44. {dub-0.32.0.dist-info → dub-0.33.0.dist-info}/WHEEL +0 -0
  45. {dub-0.32.0.dist-info → dub-0.33.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,83 @@
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_extensions import Annotated, NotRequired, TypedDict
9
+
10
+
11
+ class Reason(str, Enum):
12
+ TOS_VIOLATION = "tos_violation"
13
+ INAPPROPRIATE_CONTENT = "inappropriate_content"
14
+ FAKE_TRAFFIC = "fake_traffic"
15
+ FRAUD = "fraud"
16
+ SPAM = "spam"
17
+ BRAND_ABUSE = "brand_abuse"
18
+
19
+
20
+ class BanPartnerRequestBodyTypedDict(TypedDict):
21
+ reason: Reason
22
+ partner_id: NotRequired[Nullable[str]]
23
+ r"""The ID of the partner to create a link for. Will take precedence over `tenantId` if provided."""
24
+ tenant_id: NotRequired[Nullable[str]]
25
+ r"""The ID of the partner in your system. If both `partnerId` and `tenantId` are not provided, an error will be thrown."""
26
+
27
+
28
+ class BanPartnerRequestBody(BaseModel):
29
+ reason: Reason
30
+
31
+ partner_id: Annotated[OptionalNullable[str], pydantic.Field(alias="partnerId")] = (
32
+ UNSET
33
+ )
34
+ r"""The ID of the partner to create a link for. Will take precedence over `tenantId` if provided."""
35
+
36
+ tenant_id: Annotated[OptionalNullable[str], pydantic.Field(alias="tenantId")] = (
37
+ UNSET
38
+ )
39
+ r"""The ID of the partner in your system. If both `partnerId` and `tenantId` are not provided, an error will be thrown."""
40
+
41
+ @model_serializer(mode="wrap")
42
+ def serialize_model(self, handler):
43
+ optional_fields = ["partnerId", "tenantId"]
44
+ nullable_fields = ["partnerId", "tenantId"]
45
+ null_default_fields = []
46
+
47
+ serialized = handler(self)
48
+
49
+ m = {}
50
+
51
+ for n, f in type(self).model_fields.items():
52
+ k = f.alias or n
53
+ val = serialized.get(k)
54
+ serialized.pop(k, None)
55
+
56
+ optional_nullable = k in optional_fields and k in nullable_fields
57
+ is_set = (
58
+ self.__pydantic_fields_set__.intersection({n})
59
+ or k in null_default_fields
60
+ ) # pylint: disable=no-member
61
+
62
+ if val is not None and val != UNSET_SENTINEL:
63
+ m[k] = val
64
+ elif val != UNSET_SENTINEL and (
65
+ not k in optional_fields or (optional_nullable and is_set)
66
+ ):
67
+ m[k] = val
68
+
69
+ return m
70
+
71
+
72
+ class BanPartnerResponseBodyTypedDict(TypedDict):
73
+ r"""The banned partner"""
74
+
75
+ partner_id: str
76
+ r"""The ID of the banned partner."""
77
+
78
+
79
+ class BanPartnerResponseBody(BaseModel):
80
+ r"""The banned partner"""
81
+
82
+ partner_id: Annotated[str, pydantic.Field(alias="partnerId")]
83
+ r"""The ID of the banned partner."""
@@ -493,6 +493,8 @@ class CreatePartnerResponseBodyTypedDict(TypedDict):
493
493
  r"""The partner's Stripe Connect ID (for receiving payouts via Stripe)."""
494
494
  payouts_enabled_at: Nullable[str]
495
495
  r"""The date when the partner enabled payouts."""
496
+ trusted_at: Nullable[str]
497
+ r"""The date when the partner received the trusted badge in the partner network."""
496
498
  program_id: str
497
499
  r"""The program's unique ID on Dub."""
498
500
  partner_id: str
@@ -529,9 +531,21 @@ class CreatePartnerResponseBodyTypedDict(TypedDict):
529
531
  total_sales: NotRequired[float]
530
532
  r"""The total number of sales generated by the partner's links (includes recurring sales)"""
531
533
  total_sale_amount: NotRequired[float]
532
- r"""The total amount of sales (in cents) generated by the partner's links"""
534
+ r"""Total revenue generated by the partner's links"""
533
535
  net_revenue: NotRequired[float]
534
- r"""The total net revenue generated by the partner"""
536
+ r"""Net revenue after commissions (`Total Revenue - Total Commissions`)"""
537
+ earnings_per_click: NotRequired[Nullable[float]]
538
+ r"""Earnings Per Click (EPC) (`Total Revenue ÷ Total Clicks`)"""
539
+ average_lifetime_value: NotRequired[Nullable[float]]
540
+ r"""Average lifetime value for each paying customer (`Total Revenue ÷ Total Conversions`)"""
541
+ click_to_lead_rate: NotRequired[Nullable[float]]
542
+ r"""Percentage of clicks that become leads (`Total Leads ÷ Total Clicks`)"""
543
+ click_to_conversion_rate: NotRequired[Nullable[float]]
544
+ r"""Percentage of clicks that convert to paying customers (`Total Conversions ÷ Total Clicks`)"""
545
+ lead_to_conversion_rate: NotRequired[Nullable[float]]
546
+ r"""Percentage of leads that convert to paying customers (`Total Conversions ÷ Total Leads`)"""
547
+ return_on_ad_spend: NotRequired[Nullable[float]]
548
+ r"""Return On Ad Spend (ROAS) (`Total Revenue ÷ Total Commissions`)"""
535
549
  website: NotRequired[Nullable[str]]
536
550
  r"""The partner's website URL (including the https protocol)."""
537
551
  youtube: NotRequired[Nullable[str]]
@@ -578,6 +592,9 @@ class CreatePartnerResponseBody(BaseModel):
578
592
  ]
579
593
  r"""The date when the partner enabled payouts."""
580
594
 
595
+ trusted_at: Annotated[Nullable[str], pydantic.Field(alias="trustedAt")]
596
+ r"""The date when the partner received the trusted badge in the partner network."""
597
+
581
598
  program_id: Annotated[str, pydantic.Field(alias="programId")]
582
599
  r"""The program's unique ID on Dub."""
583
600
 
@@ -654,10 +671,40 @@ class CreatePartnerResponseBody(BaseModel):
654
671
  total_sale_amount: Annotated[
655
672
  Optional[float], pydantic.Field(alias="totalSaleAmount")
656
673
  ] = 0
657
- r"""The total amount of sales (in cents) generated by the partner's links"""
674
+ r"""Total revenue generated by the partner's links"""
658
675
 
659
676
  net_revenue: Annotated[Optional[float], pydantic.Field(alias="netRevenue")] = 0
660
- r"""The total net revenue generated by the partner"""
677
+ r"""Net revenue after commissions (`Total Revenue - Total Commissions`)"""
678
+
679
+ earnings_per_click: Annotated[
680
+ OptionalNullable[float], pydantic.Field(alias="earningsPerClick")
681
+ ] = UNSET
682
+ r"""Earnings Per Click (EPC) (`Total Revenue ÷ Total Clicks`)"""
683
+
684
+ average_lifetime_value: Annotated[
685
+ OptionalNullable[float], pydantic.Field(alias="averageLifetimeValue")
686
+ ] = UNSET
687
+ r"""Average lifetime value for each paying customer (`Total Revenue ÷ Total Conversions`)"""
688
+
689
+ click_to_lead_rate: Annotated[
690
+ OptionalNullable[float], pydantic.Field(alias="clickToLeadRate")
691
+ ] = UNSET
692
+ r"""Percentage of clicks that become leads (`Total Leads ÷ Total Clicks`)"""
693
+
694
+ click_to_conversion_rate: Annotated[
695
+ OptionalNullable[float], pydantic.Field(alias="clickToConversionRate")
696
+ ] = UNSET
697
+ r"""Percentage of clicks that convert to paying customers (`Total Conversions ÷ Total Clicks`)"""
698
+
699
+ lead_to_conversion_rate: Annotated[
700
+ OptionalNullable[float], pydantic.Field(alias="leadToConversionRate")
701
+ ] = UNSET
702
+ r"""Percentage of leads that convert to paying customers (`Total Conversions ÷ Total Leads`)"""
703
+
704
+ return_on_ad_spend: Annotated[
705
+ OptionalNullable[float], pydantic.Field(alias="returnOnAdSpend")
706
+ ] = UNSET
707
+ r"""Return On Ad Spend (ROAS) (`Total Revenue ÷ Total Commissions`)"""
661
708
 
662
709
  website: OptionalNullable[str] = UNSET
663
710
  r"""The partner's website URL (including the https protocol)."""
@@ -696,6 +743,12 @@ class CreatePartnerResponseBody(BaseModel):
696
743
  "totalSales",
697
744
  "totalSaleAmount",
698
745
  "netRevenue",
746
+ "earningsPerClick",
747
+ "averageLifetimeValue",
748
+ "clickToLeadRate",
749
+ "clickToConversionRate",
750
+ "leadToConversionRate",
751
+ "returnOnAdSpend",
699
752
  "website",
700
753
  "youtube",
701
754
  "twitter",
@@ -712,6 +765,7 @@ class CreatePartnerResponseBody(BaseModel):
712
765
  "paypalEmail",
713
766
  "stripeConnectId",
714
767
  "payoutsEnabledAt",
768
+ "trustedAt",
715
769
  "groupId",
716
770
  "tenantId",
717
771
  "links",
@@ -722,6 +776,12 @@ class CreatePartnerResponseBody(BaseModel):
722
776
  "applicationId",
723
777
  "bannedAt",
724
778
  "bannedReason",
779
+ "earningsPerClick",
780
+ "averageLifetimeValue",
781
+ "clickToLeadRate",
782
+ "clickToConversionRate",
783
+ "leadToConversionRate",
784
+ "returnOnAdSpend",
725
785
  "website",
726
786
  "youtube",
727
787
  "twitter",
@@ -83,6 +83,7 @@ class ListCommissionsRequestTypedDict(TypedDict):
83
83
  r"""The start date of the date range to filter the commissions by."""
84
84
  end: NotRequired[str]
85
85
  r"""The end date of the date range to filter the commissions by."""
86
+ timezone: NotRequired[str]
86
87
  page: NotRequired[float]
87
88
  r"""The page number for pagination."""
88
89
  page_size: NotRequired[float]
@@ -175,6 +176,11 @@ class ListCommissionsRequest(BaseModel):
175
176
  ] = None
176
177
  r"""The end date of the date range to filter the commissions by."""
177
178
 
179
+ timezone: Annotated[
180
+ Optional[str],
181
+ FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
182
+ ] = None
183
+
178
184
  page: Annotated[
179
185
  Optional[float],
180
186
  FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
@@ -219,6 +225,8 @@ class ListCommissionsPartnerTypedDict(TypedDict):
219
225
  r"""The date when the partner enabled payouts."""
220
226
  country: Nullable[str]
221
227
  r"""The partner's country (required for tax purposes)."""
228
+ group_id: NotRequired[Nullable[str]]
229
+ r"""The partner's group ID on Dub."""
222
230
 
223
231
 
224
232
  class ListCommissionsPartner(BaseModel):
@@ -242,10 +250,13 @@ class ListCommissionsPartner(BaseModel):
242
250
  country: Nullable[str]
243
251
  r"""The partner's country (required for tax purposes)."""
244
252
 
253
+ group_id: Annotated[OptionalNullable[str], pydantic.Field(alias="groupId")] = UNSET
254
+ r"""The partner's group ID on Dub."""
255
+
245
256
  @model_serializer(mode="wrap")
246
257
  def serialize_model(self, handler):
247
- optional_fields = []
248
- nullable_fields = ["email", "image", "payoutsEnabledAt", "country"]
258
+ optional_fields = ["groupId"]
259
+ nullable_fields = ["email", "image", "payoutsEnabledAt", "country", "groupId"]
249
260
  null_default_fields = []
250
261
 
251
262
  serialized = handler(self)
@@ -148,6 +148,8 @@ class ListEventsRequestTypedDict(TypedDict):
148
148
  r"""The tag IDs to retrieve analytics for."""
149
149
  folder_id: NotRequired[str]
150
150
  r"""The folder ID to retrieve analytics for. If not provided, return analytics for unsorted links."""
151
+ group_id: NotRequired[str]
152
+ r"""The group ID to retrieve analytics for."""
151
153
  root: NotRequired[bool]
152
154
  r"""Filter for root domains. If true, filter for domains only. If false, filter for links only. If undefined, return both."""
153
155
  sale_type: NotRequired[QueryParamSaleType]
@@ -346,6 +348,13 @@ class ListEventsRequest(BaseModel):
346
348
  ] = None
347
349
  r"""The folder ID to retrieve analytics for. If not provided, return analytics for unsorted links."""
348
350
 
351
+ group_id: Annotated[
352
+ Optional[str],
353
+ pydantic.Field(alias="groupId"),
354
+ FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
355
+ ] = None
356
+ r"""The group ID to retrieve analytics for."""
357
+
349
358
  root: Annotated[
350
359
  Optional[bool],
351
360
  FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
@@ -473,6 +482,7 @@ class ListEventsRequest(BaseModel):
473
482
  "url",
474
483
  "tagIds",
475
484
  "folderId",
485
+ "groupId",
476
486
  "root",
477
487
  "saleType",
478
488
  "query",
@@ -32,6 +32,13 @@ class ListPartnersQueryParamSortBy(str, Enum):
32
32
  TOTAL_CONVERSIONS = "totalConversions"
33
33
  TOTAL_SALE_AMOUNT = "totalSaleAmount"
34
34
  TOTAL_COMMISSIONS = "totalCommissions"
35
+ NET_REVENUE = "netRevenue"
36
+ EARNINGS_PER_CLICK = "earningsPerClick"
37
+ AVERAGE_LIFETIME_VALUE = "averageLifetimeValue"
38
+ CLICK_TO_LEAD_RATE = "clickToLeadRate"
39
+ CLICK_TO_CONVERSION_RATE = "clickToConversionRate"
40
+ LEAD_TO_CONVERSION_RATE = "leadToConversionRate"
41
+ RETURN_ON_AD_SPEND = "returnOnAdSpend"
35
42
 
36
43
 
37
44
  class ListPartnersQueryParamSortOrder(str, Enum):
@@ -220,6 +227,8 @@ class ListPartnersResponseBodyTypedDict(TypedDict):
220
227
  r"""The partner's Stripe Connect ID (for receiving payouts via Stripe)."""
221
228
  payouts_enabled_at: Nullable[str]
222
229
  r"""The date when the partner enabled payouts."""
230
+ trusted_at: Nullable[str]
231
+ r"""The date when the partner received the trusted badge in the partner network."""
223
232
  program_id: str
224
233
  r"""The program's unique ID on Dub."""
225
234
  partner_id: str
@@ -256,9 +265,21 @@ class ListPartnersResponseBodyTypedDict(TypedDict):
256
265
  total_sales: NotRequired[float]
257
266
  r"""The total number of sales generated by the partner's links (includes recurring sales)"""
258
267
  total_sale_amount: NotRequired[float]
259
- r"""The total amount of sales (in cents) generated by the partner's links"""
268
+ r"""Total revenue generated by the partner's links"""
260
269
  net_revenue: NotRequired[float]
261
- r"""The total net revenue generated by the partner"""
270
+ r"""Net revenue after commissions (`Total Revenue - Total Commissions`)"""
271
+ earnings_per_click: NotRequired[Nullable[float]]
272
+ r"""Earnings Per Click (EPC) (`Total Revenue ÷ Total Clicks`)"""
273
+ average_lifetime_value: NotRequired[Nullable[float]]
274
+ r"""Average lifetime value for each paying customer (`Total Revenue ÷ Total Conversions`)"""
275
+ click_to_lead_rate: NotRequired[Nullable[float]]
276
+ r"""Percentage of clicks that become leads (`Total Leads ÷ Total Clicks`)"""
277
+ click_to_conversion_rate: NotRequired[Nullable[float]]
278
+ r"""Percentage of clicks that convert to paying customers (`Total Conversions ÷ Total Clicks`)"""
279
+ lead_to_conversion_rate: NotRequired[Nullable[float]]
280
+ r"""Percentage of leads that convert to paying customers (`Total Conversions ÷ Total Leads`)"""
281
+ return_on_ad_spend: NotRequired[Nullable[float]]
282
+ r"""Return On Ad Spend (ROAS) (`Total Revenue ÷ Total Commissions`)"""
262
283
  website: NotRequired[Nullable[str]]
263
284
  r"""The partner's website URL (including the https protocol)."""
264
285
  youtube: NotRequired[Nullable[str]]
@@ -303,6 +324,9 @@ class ListPartnersResponseBody(BaseModel):
303
324
  ]
304
325
  r"""The date when the partner enabled payouts."""
305
326
 
327
+ trusted_at: Annotated[Nullable[str], pydantic.Field(alias="trustedAt")]
328
+ r"""The date when the partner received the trusted badge in the partner network."""
329
+
306
330
  program_id: Annotated[str, pydantic.Field(alias="programId")]
307
331
  r"""The program's unique ID on Dub."""
308
332
 
@@ -379,10 +403,40 @@ class ListPartnersResponseBody(BaseModel):
379
403
  total_sale_amount: Annotated[
380
404
  Optional[float], pydantic.Field(alias="totalSaleAmount")
381
405
  ] = 0
382
- r"""The total amount of sales (in cents) generated by the partner's links"""
406
+ r"""Total revenue generated by the partner's links"""
383
407
 
384
408
  net_revenue: Annotated[Optional[float], pydantic.Field(alias="netRevenue")] = 0
385
- r"""The total net revenue generated by the partner"""
409
+ r"""Net revenue after commissions (`Total Revenue - Total Commissions`)"""
410
+
411
+ earnings_per_click: Annotated[
412
+ OptionalNullable[float], pydantic.Field(alias="earningsPerClick")
413
+ ] = UNSET
414
+ r"""Earnings Per Click (EPC) (`Total Revenue ÷ Total Clicks`)"""
415
+
416
+ average_lifetime_value: Annotated[
417
+ OptionalNullable[float], pydantic.Field(alias="averageLifetimeValue")
418
+ ] = UNSET
419
+ r"""Average lifetime value for each paying customer (`Total Revenue ÷ Total Conversions`)"""
420
+
421
+ click_to_lead_rate: Annotated[
422
+ OptionalNullable[float], pydantic.Field(alias="clickToLeadRate")
423
+ ] = UNSET
424
+ r"""Percentage of clicks that become leads (`Total Leads ÷ Total Clicks`)"""
425
+
426
+ click_to_conversion_rate: Annotated[
427
+ OptionalNullable[float], pydantic.Field(alias="clickToConversionRate")
428
+ ] = UNSET
429
+ r"""Percentage of clicks that convert to paying customers (`Total Conversions ÷ Total Clicks`)"""
430
+
431
+ lead_to_conversion_rate: Annotated[
432
+ OptionalNullable[float], pydantic.Field(alias="leadToConversionRate")
433
+ ] = UNSET
434
+ r"""Percentage of leads that convert to paying customers (`Total Conversions ÷ Total Leads`)"""
435
+
436
+ return_on_ad_spend: Annotated[
437
+ OptionalNullable[float], pydantic.Field(alias="returnOnAdSpend")
438
+ ] = UNSET
439
+ r"""Return On Ad Spend (ROAS) (`Total Revenue ÷ Total Commissions`)"""
386
440
 
387
441
  website: OptionalNullable[str] = UNSET
388
442
  r"""The partner's website URL (including the https protocol)."""
@@ -421,6 +475,12 @@ class ListPartnersResponseBody(BaseModel):
421
475
  "totalSales",
422
476
  "totalSaleAmount",
423
477
  "netRevenue",
478
+ "earningsPerClick",
479
+ "averageLifetimeValue",
480
+ "clickToLeadRate",
481
+ "clickToConversionRate",
482
+ "leadToConversionRate",
483
+ "returnOnAdSpend",
424
484
  "website",
425
485
  "youtube",
426
486
  "twitter",
@@ -437,6 +497,7 @@ class ListPartnersResponseBody(BaseModel):
437
497
  "paypalEmail",
438
498
  "stripeConnectId",
439
499
  "payoutsEnabledAt",
500
+ "trustedAt",
440
501
  "groupId",
441
502
  "tenantId",
442
503
  "links",
@@ -447,6 +508,12 @@ class ListPartnersResponseBody(BaseModel):
447
508
  "applicationId",
448
509
  "bannedAt",
449
510
  "bannedReason",
511
+ "earningsPerClick",
512
+ "averageLifetimeValue",
513
+ "clickToLeadRate",
514
+ "clickToConversionRate",
515
+ "leadToConversionRate",
516
+ "returnOnAdSpend",
450
517
  "website",
451
518
  "youtube",
452
519
  "twitter",
@@ -57,7 +57,9 @@ class QueryParamGroupBy(str, Enum):
57
57
  TOP_DOMAINS = "top_domains"
58
58
  TOP_LINKS = "top_links"
59
59
  TOP_URLS = "top_urls"
60
+ TOP_BASE_URLS = "top_base_urls"
60
61
  TOP_PARTNERS = "top_partners"
62
+ TOP_GROUPS = "top_groups"
61
63
  UTM_SOURCES = "utm_sources"
62
64
  UTM_MEDIUMS = "utm_mediums"
63
65
  UTM_CAMPAIGNS = "utm_campaigns"
@@ -162,6 +164,8 @@ class RetrieveAnalyticsRequestTypedDict(TypedDict):
162
164
  r"""The tag IDs to retrieve analytics for."""
163
165
  folder_id: NotRequired[str]
164
166
  r"""The folder ID to retrieve analytics for. If not provided, return analytics for unsorted links."""
167
+ group_id: NotRequired[str]
168
+ r"""The group ID to retrieve analytics for."""
165
169
  root: NotRequired[bool]
166
170
  r"""Filter for root domains. If true, filter for domains only. If false, filter for links only. If undefined, return both."""
167
171
  sale_type: NotRequired[SaleType]
@@ -359,6 +363,13 @@ class RetrieveAnalyticsRequest(BaseModel):
359
363
  ] = None
360
364
  r"""The folder ID to retrieve analytics for. If not provided, return analytics for unsorted links."""
361
365
 
366
+ group_id: Annotated[
367
+ Optional[str],
368
+ pydantic.Field(alias="groupId"),
369
+ FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
370
+ ] = None
371
+ r"""The group ID to retrieve analytics for."""
372
+
362
373
  root: Annotated[
363
374
  Optional[bool],
364
375
  FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
@@ -457,6 +468,7 @@ class RetrieveAnalyticsRequest(BaseModel):
457
468
  "url",
458
469
  "tagIds",
459
470
  "folderId",
471
+ "groupId",
460
472
  "root",
461
473
  "saleType",
462
474
  "query",
@@ -1,30 +1,65 @@
1
1
  """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
2
2
 
3
3
  from __future__ import annotations
4
- from dub.types import BaseModel
4
+ from dub.types import BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL
5
5
  from dub.utils import FieldMetadata, QueryParamMetadata
6
6
  import pydantic
7
+ from pydantic import model_serializer
7
8
  from typing import Optional
8
9
  from typing_extensions import Annotated, NotRequired, TypedDict
9
10
 
10
11
 
11
12
  class RetrieveLinksRequestTypedDict(TypedDict):
12
- partner_id: NotRequired[str]
13
- tenant_id: NotRequired[str]
13
+ partner_id: NotRequired[Nullable[str]]
14
+ r"""The ID of the partner to create a link for. Will take precedence over `tenantId` if provided."""
15
+ tenant_id: NotRequired[Nullable[str]]
16
+ r"""The ID of the partner in your system. If both `partnerId` and `tenantId` are not provided, an error will be thrown."""
14
17
 
15
18
 
16
19
  class RetrieveLinksRequest(BaseModel):
17
20
  partner_id: Annotated[
18
- Optional[str],
21
+ OptionalNullable[str],
19
22
  pydantic.Field(alias="partnerId"),
20
23
  FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
21
- ] = None
24
+ ] = UNSET
25
+ r"""The ID of the partner to create a link for. Will take precedence over `tenantId` if provided."""
22
26
 
23
27
  tenant_id: Annotated[
24
- Optional[str],
28
+ OptionalNullable[str],
25
29
  pydantic.Field(alias="tenantId"),
26
30
  FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
27
- ] = None
31
+ ] = UNSET
32
+ r"""The ID of the partner in your system. If both `partnerId` and `tenantId` are not provided, an error will be thrown."""
33
+
34
+ @model_serializer(mode="wrap")
35
+ def serialize_model(self, handler):
36
+ optional_fields = ["partnerId", "tenantId"]
37
+ nullable_fields = ["partnerId", "tenantId"]
38
+ null_default_fields = []
39
+
40
+ serialized = handler(self)
41
+
42
+ m = {}
43
+
44
+ for n, f in type(self).model_fields.items():
45
+ k = f.alias or n
46
+ val = serialized.get(k)
47
+ serialized.pop(k, None)
48
+
49
+ optional_nullable = k in optional_fields and k in nullable_fields
50
+ is_set = (
51
+ self.__pydantic_fields_set__.intersection({n})
52
+ or k in null_default_fields
53
+ ) # pylint: disable=no-member
54
+
55
+ if val is not None and val != UNSET_SENTINEL:
56
+ m[k] = val
57
+ elif val != UNSET_SENTINEL and (
58
+ not k in optional_fields or (optional_nullable and is_set)
59
+ ):
60
+ m[k] = val
61
+
62
+ return m
28
63
 
29
64
 
30
65
  class LinkTypedDict(TypedDict):
@@ -6,10 +6,11 @@ from dub.models.components import (
6
6
  partneranalyticstimeseries as components_partneranalyticstimeseries,
7
7
  partneranalyticstoplinks as components_partneranalyticstoplinks,
8
8
  )
9
- from dub.types import BaseModel
9
+ from dub.types import BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL
10
10
  from dub.utils import FieldMetadata, QueryParamMetadata
11
11
  from enum import Enum
12
12
  import pydantic
13
+ from pydantic import model_serializer
13
14
  from typing import List, Optional, Union
14
15
  from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict
15
16
 
@@ -37,10 +38,10 @@ class RetrievePartnerAnalyticsQueryParamGroupBy(str, Enum):
37
38
 
38
39
 
39
40
  class RetrievePartnerAnalyticsRequestTypedDict(TypedDict):
40
- partner_id: NotRequired[str]
41
- r"""The ID of the partner to retrieve analytics for."""
42
- tenant_id: NotRequired[str]
43
- r"""The ID of the tenant that created the link inside your system."""
41
+ partner_id: NotRequired[Nullable[str]]
42
+ r"""The ID of the partner to create a link for. Will take precedence over `tenantId` if provided."""
43
+ tenant_id: NotRequired[Nullable[str]]
44
+ r"""The ID of the partner in your system. If both `partnerId` and `tenantId` are not provided, an error will be thrown."""
44
45
  interval: NotRequired[RetrievePartnerAnalyticsQueryParamInterval]
45
46
  r"""The interval to retrieve analytics for. If undefined, defaults to 24h."""
46
47
  start: NotRequired[str]
@@ -57,18 +58,18 @@ class RetrievePartnerAnalyticsRequestTypedDict(TypedDict):
57
58
 
58
59
  class RetrievePartnerAnalyticsRequest(BaseModel):
59
60
  partner_id: Annotated[
60
- Optional[str],
61
+ OptionalNullable[str],
61
62
  pydantic.Field(alias="partnerId"),
62
63
  FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
63
- ] = None
64
- r"""The ID of the partner to retrieve analytics for."""
64
+ ] = UNSET
65
+ r"""The ID of the partner to create a link for. Will take precedence over `tenantId` if provided."""
65
66
 
66
67
  tenant_id: Annotated[
67
- Optional[str],
68
+ OptionalNullable[str],
68
69
  pydantic.Field(alias="tenantId"),
69
70
  FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
70
- ] = None
71
- r"""The ID of the tenant that created the link inside your system."""
71
+ ] = UNSET
72
+ r"""The ID of the partner in your system. If both `partnerId` and `tenantId` are not provided, an error will be thrown."""
72
73
 
73
74
  interval: Annotated[
74
75
  Optional[RetrievePartnerAnalyticsQueryParamInterval],
@@ -107,6 +108,45 @@ class RetrievePartnerAnalyticsRequest(BaseModel):
107
108
  ] = RetrievePartnerAnalyticsQueryParamGroupBy.COUNT
108
109
  r"""The parameter to group the analytics data points by. Defaults to `count` if undefined."""
109
110
 
111
+ @model_serializer(mode="wrap")
112
+ def serialize_model(self, handler):
113
+ optional_fields = [
114
+ "partnerId",
115
+ "tenantId",
116
+ "interval",
117
+ "start",
118
+ "end",
119
+ "timezone",
120
+ "query",
121
+ "groupBy",
122
+ ]
123
+ nullable_fields = ["partnerId", "tenantId"]
124
+ null_default_fields = []
125
+
126
+ serialized = handler(self)
127
+
128
+ m = {}
129
+
130
+ for n, f in type(self).model_fields.items():
131
+ k = f.alias or n
132
+ val = serialized.get(k)
133
+ serialized.pop(k, None)
134
+
135
+ optional_nullable = k in optional_fields and k in nullable_fields
136
+ is_set = (
137
+ self.__pydantic_fields_set__.intersection({n})
138
+ or k in null_default_fields
139
+ ) # pylint: disable=no-member
140
+
141
+ if val is not None and val != UNSET_SENTINEL:
142
+ m[k] = val
143
+ elif val != UNSET_SENTINEL and (
144
+ not k in optional_fields or (optional_nullable and is_set)
145
+ ):
146
+ m[k] = val
147
+
148
+ return m
149
+
110
150
 
111
151
  RetrievePartnerAnalyticsResponseBodyTypedDict = TypeAliasType(
112
152
  "RetrievePartnerAnalyticsResponseBodyTypedDict",
@@ -94,6 +94,8 @@ class UpdateCommissionPartnerTypedDict(TypedDict):
94
94
  r"""The date when the partner enabled payouts."""
95
95
  country: Nullable[str]
96
96
  r"""The partner's country (required for tax purposes)."""
97
+ group_id: NotRequired[Nullable[str]]
98
+ r"""The partner's group ID on Dub."""
97
99
 
98
100
 
99
101
  class UpdateCommissionPartner(BaseModel):
@@ -117,10 +119,13 @@ class UpdateCommissionPartner(BaseModel):
117
119
  country: Nullable[str]
118
120
  r"""The partner's country (required for tax purposes)."""
119
121
 
122
+ group_id: Annotated[OptionalNullable[str], pydantic.Field(alias="groupId")] = UNSET
123
+ r"""The partner's group ID on Dub."""
124
+
120
125
  @model_serializer(mode="wrap")
121
126
  def serialize_model(self, handler):
122
- optional_fields = []
123
- nullable_fields = ["email", "image", "payoutsEnabledAt", "country"]
127
+ optional_fields = ["groupId"]
128
+ nullable_fields = ["email", "image", "payoutsEnabledAt", "country", "groupId"]
124
129
  null_default_fields = []
125
130
 
126
131
  serialized = handler(self)