dub 0.29.3__py3-none-any.whl → 0.31.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.
- dub/_version.py +3 -3
- dub/httpclient.py +0 -1
- dub/models/components/__init__.py +16 -4
- dub/models/components/commissioncreatedevent.py +4 -4
- dub/models/components/leadcreatedevent.py +122 -1
- dub/models/components/partnerenrolledevent.py +12 -63
- dub/models/components/salecreatedevent.py +122 -1
- dub/models/components/workspaceschema.py +8 -0
- dub/models/operations/createcustomer.py +10 -3
- dub/models/operations/createpartner.py +14 -65
- dub/models/operations/getcustomer.py +1 -1
- dub/models/operations/getcustomers.py +1 -1
- dub/models/operations/listcommissions.py +11 -2
- dub/models/operations/listevents.py +10 -0
- dub/models/operations/listpartners.py +32 -74
- dub/models/operations/retrieveanalytics.py +10 -0
- dub/models/operations/retrievelinks.py +5 -0
- dub/models/operations/updatecustomer.py +10 -3
- dub/partners.py +4 -4
- dub/sdk.py +2 -2
- dub/utils/annotations.py +32 -8
- {dub-0.29.3.dist-info → dub-0.31.0.dist-info}/METADATA +7 -3
- {dub-0.29.3.dist-info → dub-0.31.0.dist-info}/RECORD +25 -25
- {dub-0.29.3.dist-info → dub-0.31.0.dist-info}/WHEEL +1 -1
- {dub-0.29.3.dist-info → dub-0.31.0.dist-info/licenses}/LICENSE +0 -0
|
@@ -401,6 +401,7 @@ class CreatePartnerStatus(str, Enum):
|
|
|
401
401
|
REJECTED = "rejected"
|
|
402
402
|
INVITED = "invited"
|
|
403
403
|
DECLINED = "declined"
|
|
404
|
+
DEACTIVATED = "deactivated"
|
|
404
405
|
BANNED = "banned"
|
|
405
406
|
ARCHIVED = "archived"
|
|
406
407
|
|
|
@@ -420,6 +421,8 @@ class CreatePartnerLinkTypedDict(TypedDict):
|
|
|
420
421
|
r"""The number of clicks on the short link."""
|
|
421
422
|
leads: NotRequired[float]
|
|
422
423
|
r"""The number of leads the short link has generated."""
|
|
424
|
+
conversions: NotRequired[float]
|
|
425
|
+
r"""The number of leads that converted to paying customers."""
|
|
423
426
|
sales: NotRequired[float]
|
|
424
427
|
r"""The total number of sales (includes recurring sales) generated by the short link."""
|
|
425
428
|
sale_amount: NotRequired[float]
|
|
@@ -448,6 +451,9 @@ class CreatePartnerLink(BaseModel):
|
|
|
448
451
|
leads: Optional[float] = 0
|
|
449
452
|
r"""The number of leads the short link has generated."""
|
|
450
453
|
|
|
454
|
+
conversions: Optional[float] = 0
|
|
455
|
+
r"""The number of leads that converted to paying customers."""
|
|
456
|
+
|
|
451
457
|
sales: Optional[float] = 0
|
|
452
458
|
r"""The total number of sales (includes recurring sales) generated by the short link."""
|
|
453
459
|
|
|
@@ -467,12 +473,14 @@ class BannedReason(str, Enum):
|
|
|
467
473
|
|
|
468
474
|
|
|
469
475
|
class CreatePartnerResponseBodyTypedDict(TypedDict):
|
|
470
|
-
r"""The created partner"""
|
|
476
|
+
r"""The created or updated partner"""
|
|
471
477
|
|
|
472
478
|
id: str
|
|
473
479
|
r"""The partner's unique ID on Dub."""
|
|
474
480
|
name: str
|
|
475
481
|
r"""The partner's full legal name."""
|
|
482
|
+
company_name: Nullable[str]
|
|
483
|
+
r"""If the partner profile type is a company, this is the partner's legal company name."""
|
|
476
484
|
email: Nullable[str]
|
|
477
485
|
r"""The partner's email address. Should be a unique value across Dub."""
|
|
478
486
|
image: Nullable[str]
|
|
@@ -526,29 +534,20 @@ class CreatePartnerResponseBodyTypedDict(TypedDict):
|
|
|
526
534
|
r"""The total net revenue generated by the partner. Defaults to 0 if `includeExpandedFields` is false."""
|
|
527
535
|
website: NotRequired[Nullable[str]]
|
|
528
536
|
r"""The partner's website URL (including the https protocol)."""
|
|
529
|
-
website_txt_record: NotRequired[Nullable[str]]
|
|
530
|
-
website_verified_at: NotRequired[Nullable[str]]
|
|
531
537
|
youtube: NotRequired[Nullable[str]]
|
|
532
538
|
r"""The partner's YouTube channel username (e.g. `johndoe`)."""
|
|
533
|
-
youtube_verified_at: NotRequired[Nullable[str]]
|
|
534
|
-
youtube_subscriber_count: NotRequired[Nullable[float]]
|
|
535
|
-
youtube_view_count: NotRequired[Nullable[float]]
|
|
536
539
|
twitter: NotRequired[Nullable[str]]
|
|
537
540
|
r"""The partner's Twitter username (e.g. `johndoe`)."""
|
|
538
|
-
twitter_verified_at: NotRequired[Nullable[str]]
|
|
539
541
|
linkedin: NotRequired[Nullable[str]]
|
|
540
542
|
r"""The partner's LinkedIn username (e.g. `johndoe`)."""
|
|
541
|
-
linkedin_verified_at: NotRequired[Nullable[str]]
|
|
542
543
|
instagram: NotRequired[Nullable[str]]
|
|
543
544
|
r"""The partner's Instagram username (e.g. `johndoe`)."""
|
|
544
|
-
instagram_verified_at: NotRequired[Nullable[str]]
|
|
545
545
|
tiktok: NotRequired[Nullable[str]]
|
|
546
546
|
r"""The partner's TikTok username (e.g. `johndoe`)."""
|
|
547
|
-
tiktok_verified_at: NotRequired[Nullable[str]]
|
|
548
547
|
|
|
549
548
|
|
|
550
549
|
class CreatePartnerResponseBody(BaseModel):
|
|
551
|
-
r"""The created partner"""
|
|
550
|
+
r"""The created or updated partner"""
|
|
552
551
|
|
|
553
552
|
id: str
|
|
554
553
|
r"""The partner's unique ID on Dub."""
|
|
@@ -556,6 +555,9 @@ class CreatePartnerResponseBody(BaseModel):
|
|
|
556
555
|
name: str
|
|
557
556
|
r"""The partner's full legal name."""
|
|
558
557
|
|
|
558
|
+
company_name: Annotated[Nullable[str], pydantic.Field(alias="companyName")]
|
|
559
|
+
r"""If the partner profile type is a company, this is the partner's legal company name."""
|
|
560
|
+
|
|
559
561
|
email: Nullable[str]
|
|
560
562
|
r"""The partner's email address. Should be a unique value across Dub."""
|
|
561
563
|
|
|
@@ -656,57 +658,21 @@ class CreatePartnerResponseBody(BaseModel):
|
|
|
656
658
|
website: OptionalNullable[str] = UNSET
|
|
657
659
|
r"""The partner's website URL (including the https protocol)."""
|
|
658
660
|
|
|
659
|
-
website_txt_record: Annotated[
|
|
660
|
-
OptionalNullable[str], pydantic.Field(alias="websiteTxtRecord")
|
|
661
|
-
] = UNSET
|
|
662
|
-
|
|
663
|
-
website_verified_at: Annotated[
|
|
664
|
-
OptionalNullable[str], pydantic.Field(alias="websiteVerifiedAt")
|
|
665
|
-
] = UNSET
|
|
666
|
-
|
|
667
661
|
youtube: OptionalNullable[str] = UNSET
|
|
668
662
|
r"""The partner's YouTube channel username (e.g. `johndoe`)."""
|
|
669
663
|
|
|
670
|
-
youtube_verified_at: Annotated[
|
|
671
|
-
OptionalNullable[str], pydantic.Field(alias="youtubeVerifiedAt")
|
|
672
|
-
] = UNSET
|
|
673
|
-
|
|
674
|
-
youtube_subscriber_count: Annotated[
|
|
675
|
-
OptionalNullable[float], pydantic.Field(alias="youtubeSubscriberCount")
|
|
676
|
-
] = UNSET
|
|
677
|
-
|
|
678
|
-
youtube_view_count: Annotated[
|
|
679
|
-
OptionalNullable[float], pydantic.Field(alias="youtubeViewCount")
|
|
680
|
-
] = UNSET
|
|
681
|
-
|
|
682
664
|
twitter: OptionalNullable[str] = UNSET
|
|
683
665
|
r"""The partner's Twitter username (e.g. `johndoe`)."""
|
|
684
666
|
|
|
685
|
-
twitter_verified_at: Annotated[
|
|
686
|
-
OptionalNullable[str], pydantic.Field(alias="twitterVerifiedAt")
|
|
687
|
-
] = UNSET
|
|
688
|
-
|
|
689
667
|
linkedin: OptionalNullable[str] = UNSET
|
|
690
668
|
r"""The partner's LinkedIn username (e.g. `johndoe`)."""
|
|
691
669
|
|
|
692
|
-
linkedin_verified_at: Annotated[
|
|
693
|
-
OptionalNullable[str], pydantic.Field(alias="linkedinVerifiedAt")
|
|
694
|
-
] = UNSET
|
|
695
|
-
|
|
696
670
|
instagram: OptionalNullable[str] = UNSET
|
|
697
671
|
r"""The partner's Instagram username (e.g. `johndoe`)."""
|
|
698
672
|
|
|
699
|
-
instagram_verified_at: Annotated[
|
|
700
|
-
OptionalNullable[str], pydantic.Field(alias="instagramVerifiedAt")
|
|
701
|
-
] = UNSET
|
|
702
|
-
|
|
703
673
|
tiktok: OptionalNullable[str] = UNSET
|
|
704
674
|
r"""The partner's TikTok username (e.g. `johndoe`)."""
|
|
705
675
|
|
|
706
|
-
tiktok_verified_at: Annotated[
|
|
707
|
-
OptionalNullable[str], pydantic.Field(alias="tiktokVerifiedAt")
|
|
708
|
-
] = UNSET
|
|
709
|
-
|
|
710
676
|
@model_serializer(mode="wrap")
|
|
711
677
|
def serialize_model(self, handler):
|
|
712
678
|
optional_fields = [
|
|
@@ -727,22 +693,14 @@ class CreatePartnerResponseBody(BaseModel):
|
|
|
727
693
|
"saleAmount",
|
|
728
694
|
"netRevenue",
|
|
729
695
|
"website",
|
|
730
|
-
"websiteTxtRecord",
|
|
731
|
-
"websiteVerifiedAt",
|
|
732
696
|
"youtube",
|
|
733
|
-
"youtubeVerifiedAt",
|
|
734
|
-
"youtubeSubscriberCount",
|
|
735
|
-
"youtubeViewCount",
|
|
736
697
|
"twitter",
|
|
737
|
-
"twitterVerifiedAt",
|
|
738
698
|
"linkedin",
|
|
739
|
-
"linkedinVerifiedAt",
|
|
740
699
|
"instagram",
|
|
741
|
-
"instagramVerifiedAt",
|
|
742
700
|
"tiktok",
|
|
743
|
-
"tiktokVerifiedAt",
|
|
744
701
|
]
|
|
745
702
|
nullable_fields = [
|
|
703
|
+
"companyName",
|
|
746
704
|
"email",
|
|
747
705
|
"image",
|
|
748
706
|
"description",
|
|
@@ -761,20 +719,11 @@ class CreatePartnerResponseBody(BaseModel):
|
|
|
761
719
|
"bannedAt",
|
|
762
720
|
"bannedReason",
|
|
763
721
|
"website",
|
|
764
|
-
"websiteTxtRecord",
|
|
765
|
-
"websiteVerifiedAt",
|
|
766
722
|
"youtube",
|
|
767
|
-
"youtubeVerifiedAt",
|
|
768
|
-
"youtubeSubscriberCount",
|
|
769
|
-
"youtubeViewCount",
|
|
770
723
|
"twitter",
|
|
771
|
-
"twitterVerifiedAt",
|
|
772
724
|
"linkedin",
|
|
773
|
-
"linkedinVerifiedAt",
|
|
774
725
|
"instagram",
|
|
775
|
-
"instagramVerifiedAt",
|
|
776
726
|
"tiktok",
|
|
777
|
-
"tiktokVerifiedAt",
|
|
778
727
|
]
|
|
779
728
|
null_default_fields = []
|
|
780
729
|
|
|
@@ -191,9 +191,9 @@ class GetCustomerDiscount(BaseModel):
|
|
|
191
191
|
optional_fields = ["description", "partnersCount"]
|
|
192
192
|
nullable_fields = [
|
|
193
193
|
"maxDuration",
|
|
194
|
-
"description",
|
|
195
194
|
"couponId",
|
|
196
195
|
"couponTestId",
|
|
196
|
+
"description",
|
|
197
197
|
"partnersCount",
|
|
198
198
|
]
|
|
199
199
|
null_default_fields = []
|
|
@@ -275,9 +275,9 @@ class Discount(BaseModel):
|
|
|
275
275
|
optional_fields = ["description", "partnersCount"]
|
|
276
276
|
nullable_fields = [
|
|
277
277
|
"maxDuration",
|
|
278
|
-
"description",
|
|
279
278
|
"couponId",
|
|
280
279
|
"couponTestId",
|
|
280
|
+
"description",
|
|
281
281
|
"partnersCount",
|
|
282
282
|
]
|
|
283
283
|
null_default_fields = []
|
|
@@ -64,7 +64,9 @@ class ListCommissionsRequestTypedDict(TypedDict):
|
|
|
64
64
|
payout_id: NotRequired[str]
|
|
65
65
|
r"""Filter the list of commissions by the associated payout."""
|
|
66
66
|
partner_id: NotRequired[str]
|
|
67
|
-
r"""Filter the list of commissions by the associated partner."""
|
|
67
|
+
r"""Filter the list of commissions by the associated partner. When specified, takes precedence over `tenantId`."""
|
|
68
|
+
tenant_id: NotRequired[str]
|
|
69
|
+
r"""Filter the list of commissions by the associated partner's `tenantId` (their unique ID within your database)."""
|
|
68
70
|
group_id: NotRequired[str]
|
|
69
71
|
r"""Filter the list of commissions by the associated partner group."""
|
|
70
72
|
invoice_id: NotRequired[str]
|
|
@@ -112,7 +114,14 @@ class ListCommissionsRequest(BaseModel):
|
|
|
112
114
|
pydantic.Field(alias="partnerId"),
|
|
113
115
|
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
114
116
|
] = None
|
|
115
|
-
r"""Filter the list of commissions by the associated partner."""
|
|
117
|
+
r"""Filter the list of commissions by the associated partner. When specified, takes precedence over `tenantId`."""
|
|
118
|
+
|
|
119
|
+
tenant_id: Annotated[
|
|
120
|
+
Optional[str],
|
|
121
|
+
pydantic.Field(alias="tenantId"),
|
|
122
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
123
|
+
] = None
|
|
124
|
+
r"""Filter the list of commissions by the associated partner's `tenantId` (their unique ID within your database)."""
|
|
116
125
|
|
|
117
126
|
group_id: Annotated[
|
|
118
127
|
Optional[str],
|
|
@@ -168,6 +168,8 @@ class ListEventsRequestTypedDict(TypedDict):
|
|
|
168
168
|
r"""The UTM term of the short link."""
|
|
169
169
|
utm_content: NotRequired[Nullable[str]]
|
|
170
170
|
r"""The UTM content of the short link."""
|
|
171
|
+
ref: NotRequired[Nullable[str]]
|
|
172
|
+
r"""The ref of the short link."""
|
|
171
173
|
page: NotRequired[float]
|
|
172
174
|
limit: NotRequired[float]
|
|
173
175
|
sort_order: NotRequired[QueryParamSortOrder]
|
|
@@ -406,6 +408,12 @@ class ListEventsRequest(BaseModel):
|
|
|
406
408
|
] = UNSET
|
|
407
409
|
r"""The UTM content of the short link."""
|
|
408
410
|
|
|
411
|
+
ref: Annotated[
|
|
412
|
+
OptionalNullable[str],
|
|
413
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
414
|
+
] = UNSET
|
|
415
|
+
r"""The ref of the short link."""
|
|
416
|
+
|
|
409
417
|
page: Annotated[
|
|
410
418
|
Optional[float],
|
|
411
419
|
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
@@ -475,6 +483,7 @@ class ListEventsRequest(BaseModel):
|
|
|
475
483
|
"utm_campaign",
|
|
476
484
|
"utm_term",
|
|
477
485
|
"utm_content",
|
|
486
|
+
"ref",
|
|
478
487
|
"page",
|
|
479
488
|
"limit",
|
|
480
489
|
"sortOrder",
|
|
@@ -487,6 +496,7 @@ class ListEventsRequest(BaseModel):
|
|
|
487
496
|
"utm_campaign",
|
|
488
497
|
"utm_term",
|
|
489
498
|
"utm_content",
|
|
499
|
+
"ref",
|
|
490
500
|
]
|
|
491
501
|
null_default_fields = []
|
|
492
502
|
|
|
@@ -18,6 +18,7 @@ class ListPartnersQueryParamStatus(str, Enum):
|
|
|
18
18
|
REJECTED = "rejected"
|
|
19
19
|
INVITED = "invited"
|
|
20
20
|
DECLINED = "declined"
|
|
21
|
+
DEACTIVATED = "deactivated"
|
|
21
22
|
BANNED = "banned"
|
|
22
23
|
ARCHIVED = "archived"
|
|
23
24
|
|
|
@@ -31,7 +32,7 @@ class ListPartnersQueryParamSortBy(str, Enum):
|
|
|
31
32
|
CONVERSIONS = "conversions"
|
|
32
33
|
SALES = "sales"
|
|
33
34
|
SALE_AMOUNT = "saleAmount"
|
|
34
|
-
|
|
35
|
+
TOTAL_COMMISSIONS = "totalCommissions"
|
|
35
36
|
NET_REVENUE = "netRevenue"
|
|
36
37
|
|
|
37
38
|
|
|
@@ -51,12 +52,14 @@ class ListPartnersRequestTypedDict(TypedDict):
|
|
|
51
52
|
r"""The field to sort the partners by. The default is `saleAmount`."""
|
|
52
53
|
sort_order: NotRequired[ListPartnersQueryParamSortOrder]
|
|
53
54
|
r"""The sort order. The default is `desc`."""
|
|
55
|
+
email: NotRequired[str]
|
|
56
|
+
r"""Filter the partner list based on the partner's `email`. The value must be a string. Takes precedence over `search`."""
|
|
54
57
|
tenant_id: NotRequired[str]
|
|
55
|
-
r"""
|
|
58
|
+
r"""Filter the partner list based on the partner's `tenantId`. The value must be a string. Takes precedence over `email` and `search`."""
|
|
59
|
+
search: NotRequired[str]
|
|
60
|
+
r"""A search query to filter partners by ID, name, email, or link."""
|
|
56
61
|
include_expanded_fields: NotRequired[bool]
|
|
57
62
|
r"""Whether to include stats fields on the partner (`clicks`, `leads`, `conversions`, `sales`, `saleAmount`, `commissions`, `netRevenue`). If false, those fields will be returned as 0."""
|
|
58
|
-
search: NotRequired[str]
|
|
59
|
-
r"""A search query to filter partners by name, email, or tenantId."""
|
|
60
63
|
page: NotRequired[float]
|
|
61
64
|
r"""The page number for pagination."""
|
|
62
65
|
page_size: NotRequired[float]
|
|
@@ -90,12 +93,24 @@ class ListPartnersRequest(BaseModel):
|
|
|
90
93
|
] = ListPartnersQueryParamSortOrder.DESC
|
|
91
94
|
r"""The sort order. The default is `desc`."""
|
|
92
95
|
|
|
96
|
+
email: Annotated[
|
|
97
|
+
Optional[str],
|
|
98
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
99
|
+
] = None
|
|
100
|
+
r"""Filter the partner list based on the partner's `email`. The value must be a string. Takes precedence over `search`."""
|
|
101
|
+
|
|
93
102
|
tenant_id: Annotated[
|
|
94
103
|
Optional[str],
|
|
95
104
|
pydantic.Field(alias="tenantId"),
|
|
96
105
|
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
97
106
|
] = None
|
|
98
|
-
r"""
|
|
107
|
+
r"""Filter the partner list based on the partner's `tenantId`. The value must be a string. Takes precedence over `email` and `search`."""
|
|
108
|
+
|
|
109
|
+
search: Annotated[
|
|
110
|
+
Optional[str],
|
|
111
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
112
|
+
] = None
|
|
113
|
+
r"""A search query to filter partners by ID, name, email, or link."""
|
|
99
114
|
|
|
100
115
|
include_expanded_fields: Annotated[
|
|
101
116
|
Optional[bool],
|
|
@@ -104,12 +119,6 @@ class ListPartnersRequest(BaseModel):
|
|
|
104
119
|
] = None
|
|
105
120
|
r"""Whether to include stats fields on the partner (`clicks`, `leads`, `conversions`, `sales`, `saleAmount`, `commissions`, `netRevenue`). If false, those fields will be returned as 0."""
|
|
106
121
|
|
|
107
|
-
search: Annotated[
|
|
108
|
-
Optional[str],
|
|
109
|
-
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
110
|
-
] = None
|
|
111
|
-
r"""A search query to filter partners by name, email, or tenantId."""
|
|
112
|
-
|
|
113
122
|
page: Annotated[
|
|
114
123
|
Optional[float],
|
|
115
124
|
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
@@ -132,6 +141,7 @@ class ListPartnersStatus(str, Enum):
|
|
|
132
141
|
REJECTED = "rejected"
|
|
133
142
|
INVITED = "invited"
|
|
134
143
|
DECLINED = "declined"
|
|
144
|
+
DEACTIVATED = "deactivated"
|
|
135
145
|
BANNED = "banned"
|
|
136
146
|
ARCHIVED = "archived"
|
|
137
147
|
|
|
@@ -151,6 +161,8 @@ class ListPartnersLinkTypedDict(TypedDict):
|
|
|
151
161
|
r"""The number of clicks on the short link."""
|
|
152
162
|
leads: NotRequired[float]
|
|
153
163
|
r"""The number of leads the short link has generated."""
|
|
164
|
+
conversions: NotRequired[float]
|
|
165
|
+
r"""The number of leads that converted to paying customers."""
|
|
154
166
|
sales: NotRequired[float]
|
|
155
167
|
r"""The total number of sales (includes recurring sales) generated by the short link."""
|
|
156
168
|
sale_amount: NotRequired[float]
|
|
@@ -179,6 +191,9 @@ class ListPartnersLink(BaseModel):
|
|
|
179
191
|
leads: Optional[float] = 0
|
|
180
192
|
r"""The number of leads the short link has generated."""
|
|
181
193
|
|
|
194
|
+
conversions: Optional[float] = 0
|
|
195
|
+
r"""The number of leads that converted to paying customers."""
|
|
196
|
+
|
|
182
197
|
sales: Optional[float] = 0
|
|
183
198
|
r"""The total number of sales (includes recurring sales) generated by the short link."""
|
|
184
199
|
|
|
@@ -202,6 +217,8 @@ class ListPartnersResponseBodyTypedDict(TypedDict):
|
|
|
202
217
|
r"""The partner's unique ID on Dub."""
|
|
203
218
|
name: str
|
|
204
219
|
r"""The partner's full legal name."""
|
|
220
|
+
company_name: Nullable[str]
|
|
221
|
+
r"""If the partner profile type is a company, this is the partner's legal company name."""
|
|
205
222
|
email: Nullable[str]
|
|
206
223
|
r"""The partner's email address. Should be a unique value across Dub."""
|
|
207
224
|
image: Nullable[str]
|
|
@@ -255,25 +272,16 @@ class ListPartnersResponseBodyTypedDict(TypedDict):
|
|
|
255
272
|
r"""The total net revenue generated by the partner. Defaults to 0 if `includeExpandedFields` is false."""
|
|
256
273
|
website: NotRequired[Nullable[str]]
|
|
257
274
|
r"""The partner's website URL (including the https protocol)."""
|
|
258
|
-
website_txt_record: NotRequired[Nullable[str]]
|
|
259
|
-
website_verified_at: NotRequired[Nullable[str]]
|
|
260
275
|
youtube: NotRequired[Nullable[str]]
|
|
261
276
|
r"""The partner's YouTube channel username (e.g. `johndoe`)."""
|
|
262
|
-
youtube_verified_at: NotRequired[Nullable[str]]
|
|
263
|
-
youtube_subscriber_count: NotRequired[Nullable[float]]
|
|
264
|
-
youtube_view_count: NotRequired[Nullable[float]]
|
|
265
277
|
twitter: NotRequired[Nullable[str]]
|
|
266
278
|
r"""The partner's Twitter username (e.g. `johndoe`)."""
|
|
267
|
-
twitter_verified_at: NotRequired[Nullable[str]]
|
|
268
279
|
linkedin: NotRequired[Nullable[str]]
|
|
269
280
|
r"""The partner's LinkedIn username (e.g. `johndoe`)."""
|
|
270
|
-
linkedin_verified_at: NotRequired[Nullable[str]]
|
|
271
281
|
instagram: NotRequired[Nullable[str]]
|
|
272
282
|
r"""The partner's Instagram username (e.g. `johndoe`)."""
|
|
273
|
-
instagram_verified_at: NotRequired[Nullable[str]]
|
|
274
283
|
tiktok: NotRequired[Nullable[str]]
|
|
275
284
|
r"""The partner's TikTok username (e.g. `johndoe`)."""
|
|
276
|
-
tiktok_verified_at: NotRequired[Nullable[str]]
|
|
277
285
|
|
|
278
286
|
|
|
279
287
|
class ListPartnersResponseBody(BaseModel):
|
|
@@ -283,6 +291,9 @@ class ListPartnersResponseBody(BaseModel):
|
|
|
283
291
|
name: str
|
|
284
292
|
r"""The partner's full legal name."""
|
|
285
293
|
|
|
294
|
+
company_name: Annotated[Nullable[str], pydantic.Field(alias="companyName")]
|
|
295
|
+
r"""If the partner profile type is a company, this is the partner's legal company name."""
|
|
296
|
+
|
|
286
297
|
email: Nullable[str]
|
|
287
298
|
r"""The partner's email address. Should be a unique value across Dub."""
|
|
288
299
|
|
|
@@ -383,57 +394,21 @@ class ListPartnersResponseBody(BaseModel):
|
|
|
383
394
|
website: OptionalNullable[str] = UNSET
|
|
384
395
|
r"""The partner's website URL (including the https protocol)."""
|
|
385
396
|
|
|
386
|
-
website_txt_record: Annotated[
|
|
387
|
-
OptionalNullable[str], pydantic.Field(alias="websiteTxtRecord")
|
|
388
|
-
] = UNSET
|
|
389
|
-
|
|
390
|
-
website_verified_at: Annotated[
|
|
391
|
-
OptionalNullable[str], pydantic.Field(alias="websiteVerifiedAt")
|
|
392
|
-
] = UNSET
|
|
393
|
-
|
|
394
397
|
youtube: OptionalNullable[str] = UNSET
|
|
395
398
|
r"""The partner's YouTube channel username (e.g. `johndoe`)."""
|
|
396
399
|
|
|
397
|
-
youtube_verified_at: Annotated[
|
|
398
|
-
OptionalNullable[str], pydantic.Field(alias="youtubeVerifiedAt")
|
|
399
|
-
] = UNSET
|
|
400
|
-
|
|
401
|
-
youtube_subscriber_count: Annotated[
|
|
402
|
-
OptionalNullable[float], pydantic.Field(alias="youtubeSubscriberCount")
|
|
403
|
-
] = UNSET
|
|
404
|
-
|
|
405
|
-
youtube_view_count: Annotated[
|
|
406
|
-
OptionalNullable[float], pydantic.Field(alias="youtubeViewCount")
|
|
407
|
-
] = UNSET
|
|
408
|
-
|
|
409
400
|
twitter: OptionalNullable[str] = UNSET
|
|
410
401
|
r"""The partner's Twitter username (e.g. `johndoe`)."""
|
|
411
402
|
|
|
412
|
-
twitter_verified_at: Annotated[
|
|
413
|
-
OptionalNullable[str], pydantic.Field(alias="twitterVerifiedAt")
|
|
414
|
-
] = UNSET
|
|
415
|
-
|
|
416
403
|
linkedin: OptionalNullable[str] = UNSET
|
|
417
404
|
r"""The partner's LinkedIn username (e.g. `johndoe`)."""
|
|
418
405
|
|
|
419
|
-
linkedin_verified_at: Annotated[
|
|
420
|
-
OptionalNullable[str], pydantic.Field(alias="linkedinVerifiedAt")
|
|
421
|
-
] = UNSET
|
|
422
|
-
|
|
423
406
|
instagram: OptionalNullable[str] = UNSET
|
|
424
407
|
r"""The partner's Instagram username (e.g. `johndoe`)."""
|
|
425
408
|
|
|
426
|
-
instagram_verified_at: Annotated[
|
|
427
|
-
OptionalNullable[str], pydantic.Field(alias="instagramVerifiedAt")
|
|
428
|
-
] = UNSET
|
|
429
|
-
|
|
430
409
|
tiktok: OptionalNullable[str] = UNSET
|
|
431
410
|
r"""The partner's TikTok username (e.g. `johndoe`)."""
|
|
432
411
|
|
|
433
|
-
tiktok_verified_at: Annotated[
|
|
434
|
-
OptionalNullable[str], pydantic.Field(alias="tiktokVerifiedAt")
|
|
435
|
-
] = UNSET
|
|
436
|
-
|
|
437
412
|
@model_serializer(mode="wrap")
|
|
438
413
|
def serialize_model(self, handler):
|
|
439
414
|
optional_fields = [
|
|
@@ -454,22 +429,14 @@ class ListPartnersResponseBody(BaseModel):
|
|
|
454
429
|
"saleAmount",
|
|
455
430
|
"netRevenue",
|
|
456
431
|
"website",
|
|
457
|
-
"websiteTxtRecord",
|
|
458
|
-
"websiteVerifiedAt",
|
|
459
432
|
"youtube",
|
|
460
|
-
"youtubeVerifiedAt",
|
|
461
|
-
"youtubeSubscriberCount",
|
|
462
|
-
"youtubeViewCount",
|
|
463
433
|
"twitter",
|
|
464
|
-
"twitterVerifiedAt",
|
|
465
434
|
"linkedin",
|
|
466
|
-
"linkedinVerifiedAt",
|
|
467
435
|
"instagram",
|
|
468
|
-
"instagramVerifiedAt",
|
|
469
436
|
"tiktok",
|
|
470
|
-
"tiktokVerifiedAt",
|
|
471
437
|
]
|
|
472
438
|
nullable_fields = [
|
|
439
|
+
"companyName",
|
|
473
440
|
"email",
|
|
474
441
|
"image",
|
|
475
442
|
"description",
|
|
@@ -488,20 +455,11 @@ class ListPartnersResponseBody(BaseModel):
|
|
|
488
455
|
"bannedAt",
|
|
489
456
|
"bannedReason",
|
|
490
457
|
"website",
|
|
491
|
-
"websiteTxtRecord",
|
|
492
|
-
"websiteVerifiedAt",
|
|
493
458
|
"youtube",
|
|
494
|
-
"youtubeVerifiedAt",
|
|
495
|
-
"youtubeSubscriberCount",
|
|
496
|
-
"youtubeViewCount",
|
|
497
459
|
"twitter",
|
|
498
|
-
"twitterVerifiedAt",
|
|
499
460
|
"linkedin",
|
|
500
|
-
"linkedinVerifiedAt",
|
|
501
461
|
"instagram",
|
|
502
|
-
"instagramVerifiedAt",
|
|
503
462
|
"tiktok",
|
|
504
|
-
"tiktokVerifiedAt",
|
|
505
463
|
]
|
|
506
464
|
null_default_fields = []
|
|
507
465
|
|
|
@@ -179,6 +179,8 @@ class RetrieveAnalyticsRequestTypedDict(TypedDict):
|
|
|
179
179
|
r"""The UTM term of the short link."""
|
|
180
180
|
utm_content: NotRequired[Nullable[str]]
|
|
181
181
|
r"""The UTM content of the short link."""
|
|
182
|
+
ref: NotRequired[Nullable[str]]
|
|
183
|
+
r"""The ref of the short link."""
|
|
182
184
|
|
|
183
185
|
|
|
184
186
|
class RetrieveAnalyticsRequest(BaseModel):
|
|
@@ -416,6 +418,12 @@ class RetrieveAnalyticsRequest(BaseModel):
|
|
|
416
418
|
] = UNSET
|
|
417
419
|
r"""The UTM content of the short link."""
|
|
418
420
|
|
|
421
|
+
ref: Annotated[
|
|
422
|
+
OptionalNullable[str],
|
|
423
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
424
|
+
] = UNSET
|
|
425
|
+
r"""The ref of the short link."""
|
|
426
|
+
|
|
419
427
|
@model_serializer(mode="wrap")
|
|
420
428
|
def serialize_model(self, handler):
|
|
421
429
|
optional_fields = [
|
|
@@ -456,6 +464,7 @@ class RetrieveAnalyticsRequest(BaseModel):
|
|
|
456
464
|
"utm_campaign",
|
|
457
465
|
"utm_term",
|
|
458
466
|
"utm_content",
|
|
467
|
+
"ref",
|
|
459
468
|
]
|
|
460
469
|
nullable_fields = [
|
|
461
470
|
"utm_source",
|
|
@@ -463,6 +472,7 @@ class RetrieveAnalyticsRequest(BaseModel):
|
|
|
463
472
|
"utm_campaign",
|
|
464
473
|
"utm_term",
|
|
465
474
|
"utm_content",
|
|
475
|
+
"ref",
|
|
466
476
|
]
|
|
467
477
|
null_default_fields = []
|
|
468
478
|
|
|
@@ -42,6 +42,8 @@ class LinkTypedDict(TypedDict):
|
|
|
42
42
|
r"""The number of clicks on the short link."""
|
|
43
43
|
leads: NotRequired[float]
|
|
44
44
|
r"""The number of leads the short link has generated."""
|
|
45
|
+
conversions: NotRequired[float]
|
|
46
|
+
r"""The number of leads that converted to paying customers."""
|
|
45
47
|
sales: NotRequired[float]
|
|
46
48
|
r"""The total number of sales (includes recurring sales) generated by the short link."""
|
|
47
49
|
sale_amount: NotRequired[float]
|
|
@@ -70,6 +72,9 @@ class Link(BaseModel):
|
|
|
70
72
|
leads: Optional[float] = 0
|
|
71
73
|
r"""The number of leads the short link has generated."""
|
|
72
74
|
|
|
75
|
+
conversions: Optional[float] = 0
|
|
76
|
+
r"""The number of leads that converted to paying customers."""
|
|
77
|
+
|
|
73
78
|
sales: Optional[float] = 0
|
|
74
79
|
r"""The total number of sales (includes recurring sales) generated by the short link."""
|
|
75
80
|
|
|
@@ -24,6 +24,8 @@ class UpdateCustomerRequestBodyTypedDict(TypedDict):
|
|
|
24
24
|
r"""Avatar URL of the customer in the client's app."""
|
|
25
25
|
external_id: NotRequired[str]
|
|
26
26
|
r"""Unique identifier for the customer in the client's app."""
|
|
27
|
+
stripe_customer_id: NotRequired[Nullable[str]]
|
|
28
|
+
r"""The customer's Stripe customer ID. Useful for attribution recurring sale events to the partner who referred the customer."""
|
|
27
29
|
|
|
28
30
|
|
|
29
31
|
class UpdateCustomerRequestBody(BaseModel):
|
|
@@ -39,10 +41,15 @@ class UpdateCustomerRequestBody(BaseModel):
|
|
|
39
41
|
external_id: Annotated[Optional[str], pydantic.Field(alias="externalId")] = None
|
|
40
42
|
r"""Unique identifier for the customer in the client's app."""
|
|
41
43
|
|
|
44
|
+
stripe_customer_id: Annotated[
|
|
45
|
+
OptionalNullable[str], pydantic.Field(alias="stripeCustomerId")
|
|
46
|
+
] = UNSET
|
|
47
|
+
r"""The customer's Stripe customer ID. Useful for attribution recurring sale events to the partner who referred the customer."""
|
|
48
|
+
|
|
42
49
|
@model_serializer(mode="wrap")
|
|
43
50
|
def serialize_model(self, handler):
|
|
44
|
-
optional_fields = ["email", "name", "avatar", "externalId"]
|
|
45
|
-
nullable_fields = ["email", "name", "avatar"]
|
|
51
|
+
optional_fields = ["email", "name", "avatar", "externalId", "stripeCustomerId"]
|
|
52
|
+
nullable_fields = ["email", "name", "avatar", "stripeCustomerId"]
|
|
46
53
|
null_default_fields = []
|
|
47
54
|
|
|
48
55
|
serialized = handler(self)
|
|
@@ -257,9 +264,9 @@ class UpdateCustomerDiscount(BaseModel):
|
|
|
257
264
|
optional_fields = ["description", "partnersCount"]
|
|
258
265
|
nullable_fields = [
|
|
259
266
|
"maxDuration",
|
|
260
|
-
"description",
|
|
261
267
|
"couponId",
|
|
262
268
|
"couponTestId",
|
|
269
|
+
"description",
|
|
263
270
|
"partnersCount",
|
|
264
271
|
]
|
|
265
272
|
null_default_fields = []
|
dub/partners.py
CHANGED
|
@@ -24,9 +24,9 @@ class Partners(BaseSDK):
|
|
|
24
24
|
timeout_ms: Optional[int] = None,
|
|
25
25
|
http_headers: Optional[Mapping[str, str]] = None,
|
|
26
26
|
) -> Optional[operations.CreatePartnerResponseBody]:
|
|
27
|
-
r"""Create a partner
|
|
27
|
+
r"""Create or update a partner
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
Creates or updates a partner record (upsert behavior). If a partner with the same email already exists, their program enrollment will be updated with the provided tenantId. If no existing partner is found, a new partner will be created using the supplied information.
|
|
30
30
|
|
|
31
31
|
:param request: The request object to send.
|
|
32
32
|
:param retries: Override the default retry configuration for this method
|
|
@@ -167,9 +167,9 @@ class Partners(BaseSDK):
|
|
|
167
167
|
timeout_ms: Optional[int] = None,
|
|
168
168
|
http_headers: Optional[Mapping[str, str]] = None,
|
|
169
169
|
) -> Optional[operations.CreatePartnerResponseBody]:
|
|
170
|
-
r"""Create a partner
|
|
170
|
+
r"""Create or update a partner
|
|
171
171
|
|
|
172
|
-
|
|
172
|
+
Creates or updates a partner record (upsert behavior). If a partner with the same email already exists, their program enrollment will be updated with the provided tenantId. If no existing partner is found, a new partner will be created using the supplied information.
|
|
173
173
|
|
|
174
174
|
:param request: The request object to send.
|
|
175
175
|
:param retries: Override the default retry configuration for this method
|
dub/sdk.py
CHANGED
|
@@ -88,7 +88,7 @@ class Dub(BaseSDK):
|
|
|
88
88
|
"""
|
|
89
89
|
client_supplied = True
|
|
90
90
|
if client is None:
|
|
91
|
-
client = httpx.Client()
|
|
91
|
+
client = httpx.Client(follow_redirects=True)
|
|
92
92
|
client_supplied = False
|
|
93
93
|
|
|
94
94
|
assert issubclass(
|
|
@@ -97,7 +97,7 @@ class Dub(BaseSDK):
|
|
|
97
97
|
|
|
98
98
|
async_client_supplied = True
|
|
99
99
|
if async_client is None:
|
|
100
|
-
async_client = httpx.AsyncClient()
|
|
100
|
+
async_client = httpx.AsyncClient(follow_redirects=True)
|
|
101
101
|
async_client_supplied = False
|
|
102
102
|
|
|
103
103
|
if debug_logger is None:
|