dub 0.26.5__tar.gz → 0.26.7__tar.gz

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 (141) hide show
  1. {dub-0.26.5 → dub-0.26.7}/PKG-INFO +1 -1
  2. {dub-0.26.5 → dub-0.26.7}/pyproject.toml +3 -1
  3. {dub-0.26.5 → dub-0.26.7}/src/dub/_version.py +3 -3
  4. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/partnerenrolledevent.py +15 -9
  5. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/createpartner.py +15 -9
  6. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/listcommissions.py +2 -0
  7. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/listevents.py +6 -6
  8. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/retrieveanalytics.py +6 -6
  9. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/updatecommission.py +1 -0
  10. {dub-0.26.5 → dub-0.26.7}/src/dub/utils/forms.py +49 -28
  11. {dub-0.26.5 → dub-0.26.7}/LICENSE +0 -0
  12. {dub-0.26.5 → dub-0.26.7}/README-PYPI.md +0 -0
  13. {dub-0.26.5 → dub-0.26.7}/py.typed +0 -0
  14. {dub-0.26.5 → dub-0.26.7}/src/dub/__init__.py +0 -0
  15. {dub-0.26.5 → dub-0.26.7}/src/dub/_hooks/__init__.py +0 -0
  16. {dub-0.26.5 → dub-0.26.7}/src/dub/_hooks/registration.py +0 -0
  17. {dub-0.26.5 → dub-0.26.7}/src/dub/_hooks/sdkhooks.py +0 -0
  18. {dub-0.26.5 → dub-0.26.7}/src/dub/_hooks/types.py +0 -0
  19. {dub-0.26.5 → dub-0.26.7}/src/dub/analytics.py +0 -0
  20. {dub-0.26.5 → dub-0.26.7}/src/dub/basesdk.py +0 -0
  21. {dub-0.26.5 → dub-0.26.7}/src/dub/commissions.py +0 -0
  22. {dub-0.26.5 → dub-0.26.7}/src/dub/customers.py +0 -0
  23. {dub-0.26.5 → dub-0.26.7}/src/dub/domains.py +0 -0
  24. {dub-0.26.5 → dub-0.26.7}/src/dub/embed_tokens.py +0 -0
  25. {dub-0.26.5 → dub-0.26.7}/src/dub/events.py +0 -0
  26. {dub-0.26.5 → dub-0.26.7}/src/dub/folders.py +0 -0
  27. {dub-0.26.5 → dub-0.26.7}/src/dub/httpclient.py +0 -0
  28. {dub-0.26.5 → dub-0.26.7}/src/dub/links.py +0 -0
  29. {dub-0.26.5 → dub-0.26.7}/src/dub/models/__init__.py +0 -0
  30. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/__init__.py +0 -0
  31. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/analyticsbrowsers.py +0 -0
  32. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/analyticscities.py +0 -0
  33. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/analyticscontinents.py +0 -0
  34. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/analyticscount.py +0 -0
  35. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/analyticscountries.py +0 -0
  36. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/analyticsdevices.py +0 -0
  37. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/analyticsos.py +0 -0
  38. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/analyticsreferers.py +0 -0
  39. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/analyticsrefererurls.py +0 -0
  40. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/analyticsregions.py +0 -0
  41. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/analyticstimeseries.py +0 -0
  42. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/analyticstoplinks.py +0 -0
  43. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/analyticstopurls.py +0 -0
  44. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/analyticstriggers.py +0 -0
  45. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/clickevent.py +0 -0
  46. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/continentcode.py +0 -0
  47. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/countrycode.py +0 -0
  48. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/domainschema.py +0 -0
  49. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/folderschema.py +0 -0
  50. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/leadcreatedevent.py +0 -0
  51. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/leadevent.py +0 -0
  52. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/linkclickedevent.py +0 -0
  53. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/linkerrorschema.py +0 -0
  54. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/linkgeotargeting.py +0 -0
  55. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/linkschema.py +0 -0
  56. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/linkwebhookevent.py +0 -0
  57. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/partneranalyticscount.py +0 -0
  58. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/partneranalyticstimeseries.py +0 -0
  59. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/partneranalyticstoplinks.py +0 -0
  60. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/salecreatedevent.py +0 -0
  61. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/saleevent.py +0 -0
  62. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/security.py +0 -0
  63. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/tagschema.py +0 -0
  64. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/webhookevent.py +0 -0
  65. {dub-0.26.5 → dub-0.26.7}/src/dub/models/components/workspaceschema.py +0 -0
  66. {dub-0.26.5 → dub-0.26.7}/src/dub/models/errors/__init__.py +0 -0
  67. {dub-0.26.5 → dub-0.26.7}/src/dub/models/errors/badrequest.py +0 -0
  68. {dub-0.26.5 → dub-0.26.7}/src/dub/models/errors/conflict.py +0 -0
  69. {dub-0.26.5 → dub-0.26.7}/src/dub/models/errors/forbidden.py +0 -0
  70. {dub-0.26.5 → dub-0.26.7}/src/dub/models/errors/internalservererror.py +0 -0
  71. {dub-0.26.5 → dub-0.26.7}/src/dub/models/errors/inviteexpired.py +0 -0
  72. {dub-0.26.5 → dub-0.26.7}/src/dub/models/errors/notfound.py +0 -0
  73. {dub-0.26.5 → dub-0.26.7}/src/dub/models/errors/ratelimitexceeded.py +0 -0
  74. {dub-0.26.5 → dub-0.26.7}/src/dub/models/errors/sdkerror.py +0 -0
  75. {dub-0.26.5 → dub-0.26.7}/src/dub/models/errors/unauthorized.py +0 -0
  76. {dub-0.26.5 → dub-0.26.7}/src/dub/models/errors/unprocessableentity.py +0 -0
  77. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/__init__.py +0 -0
  78. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/bulkcreatelinks.py +0 -0
  79. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/bulkdeletelinks.py +0 -0
  80. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/bulkupdatelinks.py +0 -0
  81. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/checkdomainstatus.py +0 -0
  82. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/createcustomer.py +0 -0
  83. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/createdomain.py +0 -0
  84. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/createfolder.py +0 -0
  85. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/createlink.py +0 -0
  86. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/createpartnerlink.py +0 -0
  87. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/createreferralsembedtoken.py +0 -0
  88. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/createtag.py +0 -0
  89. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/deletecustomer.py +0 -0
  90. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/deletedomain.py +0 -0
  91. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/deletefolder.py +0 -0
  92. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/deletelink.py +0 -0
  93. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/deletetag.py +0 -0
  94. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/getcustomer.py +0 -0
  95. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/getcustomers.py +0 -0
  96. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/getlinkinfo.py +0 -0
  97. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/getlinks.py +0 -0
  98. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/getlinkscount.py +0 -0
  99. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/getqrcode.py +0 -0
  100. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/gettags.py +0 -0
  101. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/getworkspace.py +0 -0
  102. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/listdomains.py +0 -0
  103. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/listfolders.py +0 -0
  104. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/registerdomain.py +0 -0
  105. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/retrievelinks.py +0 -0
  106. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/retrievepartneranalytics.py +0 -0
  107. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/tracklead.py +0 -0
  108. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/tracksale.py +0 -0
  109. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/updatecustomer.py +0 -0
  110. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/updatedomain.py +0 -0
  111. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/updatefolder.py +0 -0
  112. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/updatelink.py +0 -0
  113. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/updatetag.py +0 -0
  114. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/updateworkspace.py +0 -0
  115. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/upsertlink.py +0 -0
  116. {dub-0.26.5 → dub-0.26.7}/src/dub/models/operations/upsertpartnerlink.py +0 -0
  117. {dub-0.26.5 → dub-0.26.7}/src/dub/partners.py +0 -0
  118. {dub-0.26.5 → dub-0.26.7}/src/dub/py.typed +0 -0
  119. {dub-0.26.5 → dub-0.26.7}/src/dub/qr_codes.py +0 -0
  120. {dub-0.26.5 → dub-0.26.7}/src/dub/sdk.py +0 -0
  121. {dub-0.26.5 → dub-0.26.7}/src/dub/sdkconfiguration.py +0 -0
  122. {dub-0.26.5 → dub-0.26.7}/src/dub/tags.py +0 -0
  123. {dub-0.26.5 → dub-0.26.7}/src/dub/track.py +0 -0
  124. {dub-0.26.5 → dub-0.26.7}/src/dub/types/__init__.py +0 -0
  125. {dub-0.26.5 → dub-0.26.7}/src/dub/types/basemodel.py +0 -0
  126. {dub-0.26.5 → dub-0.26.7}/src/dub/utils/__init__.py +0 -0
  127. {dub-0.26.5 → dub-0.26.7}/src/dub/utils/annotations.py +0 -0
  128. {dub-0.26.5 → dub-0.26.7}/src/dub/utils/datetimes.py +0 -0
  129. {dub-0.26.5 → dub-0.26.7}/src/dub/utils/enums.py +0 -0
  130. {dub-0.26.5 → dub-0.26.7}/src/dub/utils/eventstreaming.py +0 -0
  131. {dub-0.26.5 → dub-0.26.7}/src/dub/utils/headers.py +0 -0
  132. {dub-0.26.5 → dub-0.26.7}/src/dub/utils/logger.py +0 -0
  133. {dub-0.26.5 → dub-0.26.7}/src/dub/utils/metadata.py +0 -0
  134. {dub-0.26.5 → dub-0.26.7}/src/dub/utils/queryparams.py +0 -0
  135. {dub-0.26.5 → dub-0.26.7}/src/dub/utils/requestbodies.py +0 -0
  136. {dub-0.26.5 → dub-0.26.7}/src/dub/utils/retries.py +0 -0
  137. {dub-0.26.5 → dub-0.26.7}/src/dub/utils/security.py +0 -0
  138. {dub-0.26.5 → dub-0.26.7}/src/dub/utils/serializers.py +0 -0
  139. {dub-0.26.5 → dub-0.26.7}/src/dub/utils/url.py +0 -0
  140. {dub-0.26.5 → dub-0.26.7}/src/dub/utils/values.py +0 -0
  141. {dub-0.26.5 → dub-0.26.7}/src/dub/workspaces.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: dub
3
- Version: 0.26.5
3
+ Version: 0.26.7
4
4
  Summary: Python Client SDK Generated by Speakeasy
5
5
  Author: Speakeasy
6
6
  Requires-Python: >=3.9.2
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "dub"
3
- version = "0.26.5"
3
+ version = "0.26.7"
4
4
  description = "Python Client SDK Generated by Speakeasy"
5
5
  authors = [{ name = "Speakeasy" },]
6
6
  readme = "README-PYPI.md"
@@ -39,6 +39,8 @@ pythonpath = ["src"]
39
39
 
40
40
  [tool.mypy]
41
41
  disable_error_code = "misc"
42
+ explicit_package_bases = true
43
+ mypy_path = "src"
42
44
 
43
45
  [[tool.mypy.overrides]]
44
46
  module = "typing_inspect"
@@ -3,10 +3,10 @@
3
3
  import importlib.metadata
4
4
 
5
5
  __title__: str = "dub"
6
- __version__: str = "0.26.5"
6
+ __version__: str = "0.26.7"
7
7
  __openapi_doc_version__: str = "0.0.1"
8
- __gen_version__: str = "2.621.3"
9
- __user_agent__: str = "speakeasy-sdk/python 0.26.5 2.621.3 0.0.1 dub"
8
+ __gen_version__: str = "2.628.0"
9
+ __user_agent__: str = "speakeasy-sdk/python 0.26.7 2.628.0 0.0.1 dub"
10
10
 
11
11
  try:
12
12
  if __package__ is not None:
@@ -22,6 +22,7 @@ class Status(str, Enum):
22
22
  INVITED = "invited"
23
23
  DECLINED = "declined"
24
24
  BANNED = "banned"
25
+ ARCHIVED = "archived"
25
26
 
26
27
 
27
28
  class PartnerEnrolledEventLinkTypedDict(TypedDict):
@@ -123,10 +124,12 @@ class PartnerEnrolledEventDataTypedDict(TypedDict):
123
124
  r"""The total number of sales generated by the partner's links."""
124
125
  sale_amount: NotRequired[float]
125
126
  r"""The total amount of sales (in cents) generated by the partner's links."""
127
+ total_commissions: NotRequired[float]
128
+ r"""The total commissions paid to the partner for their referrals."""
129
+ net_revenue: NotRequired[float]
130
+ r"""The total net revenue generated by the partner."""
126
131
  earnings: NotRequired[float]
127
132
  r"""DEPRECATED: The total earnings/commissions accrued by the partner's links."""
128
- application_id: NotRequired[Nullable[str]]
129
- r"""If the partner submitted an application to join the program, this is the ID of the application."""
130
133
 
131
134
 
132
135
  class PartnerEnrolledEventData(BaseModel):
@@ -204,6 +207,14 @@ class PartnerEnrolledEventData(BaseModel):
204
207
  sale_amount: Annotated[Optional[float], pydantic.Field(alias="saleAmount")] = 0
205
208
  r"""The total amount of sales (in cents) generated by the partner's links."""
206
209
 
210
+ total_commissions: Annotated[
211
+ Optional[float], pydantic.Field(alias="totalCommissions")
212
+ ] = 0
213
+ r"""The total commissions paid to the partner for their referrals."""
214
+
215
+ net_revenue: Annotated[Optional[float], pydantic.Field(alias="netRevenue")] = 0
216
+ r"""The total net revenue generated by the partner."""
217
+
207
218
  earnings: Annotated[
208
219
  Optional[float],
209
220
  pydantic.Field(
@@ -212,11 +223,6 @@ class PartnerEnrolledEventData(BaseModel):
212
223
  ] = 0
213
224
  r"""DEPRECATED: The total earnings/commissions accrued by the partner's links."""
214
225
 
215
- application_id: Annotated[
216
- OptionalNullable[str], pydantic.Field(alias="applicationId")
217
- ] = UNSET
218
- r"""If the partner submitted an application to join the program, this is the ID of the application."""
219
-
220
226
  @model_serializer(mode="wrap")
221
227
  def serialize_model(self, handler):
222
228
  optional_fields = [
@@ -225,8 +231,9 @@ class PartnerEnrolledEventData(BaseModel):
225
231
  "leads",
226
232
  "sales",
227
233
  "saleAmount",
234
+ "totalCommissions",
235
+ "netRevenue",
228
236
  "earnings",
229
- "applicationId",
230
237
  ]
231
238
  nullable_fields = [
232
239
  "email",
@@ -244,7 +251,6 @@ class PartnerEnrolledEventData(BaseModel):
244
251
  "payoutsEnabledAt",
245
252
  "tenantId",
246
253
  "links",
247
- "applicationId",
248
254
  ]
249
255
  null_default_fields = []
250
256
 
@@ -649,6 +649,7 @@ class CreatePartnerStatus(str, Enum):
649
649
  INVITED = "invited"
650
650
  DECLINED = "declined"
651
651
  BANNED = "banned"
652
+ ARCHIVED = "archived"
652
653
 
653
654
 
654
655
  class CreatePartnerLinkTypedDict(TypedDict):
@@ -752,10 +753,12 @@ class CreatePartnerResponseBodyTypedDict(TypedDict):
752
753
  r"""The total number of sales generated by the partner's links."""
753
754
  sale_amount: NotRequired[float]
754
755
  r"""The total amount of sales (in cents) generated by the partner's links."""
756
+ total_commissions: NotRequired[float]
757
+ r"""The total commissions paid to the partner for their referrals."""
758
+ net_revenue: NotRequired[float]
759
+ r"""The total net revenue generated by the partner."""
755
760
  earnings: NotRequired[float]
756
761
  r"""DEPRECATED: The total earnings/commissions accrued by the partner's links."""
757
- application_id: NotRequired[Nullable[str]]
758
- r"""If the partner submitted an application to join the program, this is the ID of the application."""
759
762
 
760
763
 
761
764
  class CreatePartnerResponseBody(BaseModel):
@@ -835,6 +838,14 @@ class CreatePartnerResponseBody(BaseModel):
835
838
  sale_amount: Annotated[Optional[float], pydantic.Field(alias="saleAmount")] = 0
836
839
  r"""The total amount of sales (in cents) generated by the partner's links."""
837
840
 
841
+ total_commissions: Annotated[
842
+ Optional[float], pydantic.Field(alias="totalCommissions")
843
+ ] = 0
844
+ r"""The total commissions paid to the partner for their referrals."""
845
+
846
+ net_revenue: Annotated[Optional[float], pydantic.Field(alias="netRevenue")] = 0
847
+ r"""The total net revenue generated by the partner."""
848
+
838
849
  earnings: Annotated[
839
850
  Optional[float],
840
851
  pydantic.Field(
@@ -843,11 +854,6 @@ class CreatePartnerResponseBody(BaseModel):
843
854
  ] = 0
844
855
  r"""DEPRECATED: The total earnings/commissions accrued by the partner's links."""
845
856
 
846
- application_id: Annotated[
847
- OptionalNullable[str], pydantic.Field(alias="applicationId")
848
- ] = UNSET
849
- r"""If the partner submitted an application to join the program, this is the ID of the application."""
850
-
851
857
  @model_serializer(mode="wrap")
852
858
  def serialize_model(self, handler):
853
859
  optional_fields = [
@@ -856,8 +862,9 @@ class CreatePartnerResponseBody(BaseModel):
856
862
  "leads",
857
863
  "sales",
858
864
  "saleAmount",
865
+ "totalCommissions",
866
+ "netRevenue",
859
867
  "earnings",
860
- "applicationId",
861
868
  ]
862
869
  nullable_fields = [
863
870
  "email",
@@ -875,7 +882,6 @@ class CreatePartnerResponseBody(BaseModel):
875
882
  "payoutsEnabledAt",
876
883
  "tenantId",
877
884
  "links",
878
- "applicationId",
879
885
  ]
880
886
  null_default_fields = []
881
887
 
@@ -14,6 +14,7 @@ class Type(str, Enum):
14
14
  CLICK = "click"
15
15
  LEAD = "lead"
16
16
  SALE = "sale"
17
+ CUSTOM = "custom"
17
18
 
18
19
 
19
20
  class QueryParamStatus(str, Enum):
@@ -174,6 +175,7 @@ class ListCommissionsType(str, Enum):
174
175
  CLICK = "click"
175
176
  LEAD = "lead"
176
177
  SALE = "sale"
178
+ CUSTOM = "custom"
177
179
 
178
180
 
179
181
  class ListCommissionsStatus(str, Enum):
@@ -93,11 +93,11 @@ class ListEventsRequestTypedDict(TypedDict):
93
93
  domain: NotRequired[str]
94
94
  r"""The domain to filter analytics for."""
95
95
  key: NotRequired[str]
96
- r"""The short link slug."""
96
+ r"""The slug of the short link to retrieve analytics for. Must be used along with the corresponding `domain` of the short link to fetch analytics for a specific short link."""
97
97
  link_id: NotRequired[str]
98
- r"""The unique ID of the short link on Dub."""
98
+ r"""The unique ID of the short link on Dub to retrieve analytics for."""
99
99
  external_id: NotRequired[str]
100
- r"""This is the ID of the link in the your database. Must be prefixed with 'ext_' when passed as a query parameter."""
100
+ r"""The ID of the link in the your database. Must be prefixed with 'ext_' when passed as a query parameter."""
101
101
  tenant_id: NotRequired[str]
102
102
  r"""The ID of the tenant that created the link inside your system."""
103
103
  program_id: NotRequired[str]
@@ -183,21 +183,21 @@ class ListEventsRequest(BaseModel):
183
183
  Optional[str],
184
184
  FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
185
185
  ] = None
186
- r"""The short link slug."""
186
+ r"""The slug of the short link to retrieve analytics for. Must be used along with the corresponding `domain` of the short link to fetch analytics for a specific short link."""
187
187
 
188
188
  link_id: Annotated[
189
189
  Optional[str],
190
190
  pydantic.Field(alias="linkId"),
191
191
  FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
192
192
  ] = None
193
- r"""The unique ID of the short link on Dub."""
193
+ r"""The unique ID of the short link on Dub to retrieve analytics for."""
194
194
 
195
195
  external_id: Annotated[
196
196
  Optional[str],
197
197
  pydantic.Field(alias="externalId"),
198
198
  FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
199
199
  ] = None
200
- r"""This is the ID of the link in the your database. Must be prefixed with 'ext_' when passed as a query parameter."""
200
+ r"""The ID of the link in the your database. Must be prefixed with 'ext_' when passed as a query parameter."""
201
201
 
202
202
  tenant_id: Annotated[
203
203
  Optional[str],
@@ -104,11 +104,11 @@ class RetrieveAnalyticsRequestTypedDict(TypedDict):
104
104
  domain: NotRequired[str]
105
105
  r"""The domain to filter analytics for."""
106
106
  key: NotRequired[str]
107
- r"""The short link slug."""
107
+ r"""The slug of the short link to retrieve analytics for. Must be used along with the corresponding `domain` of the short link to fetch analytics for a specific short link."""
108
108
  link_id: NotRequired[str]
109
- r"""The unique ID of the short link on Dub."""
109
+ r"""The unique ID of the short link on Dub to retrieve analytics for."""
110
110
  external_id: NotRequired[str]
111
- r"""This is the ID of the link in the your database. Must be prefixed with 'ext_' when passed as a query parameter."""
111
+ r"""The ID of the link in the your database. Must be prefixed with 'ext_' when passed as a query parameter."""
112
112
  tenant_id: NotRequired[str]
113
113
  r"""The ID of the tenant that created the link inside your system."""
114
114
  program_id: NotRequired[str]
@@ -193,21 +193,21 @@ class RetrieveAnalyticsRequest(BaseModel):
193
193
  Optional[str],
194
194
  FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
195
195
  ] = None
196
- r"""The short link slug."""
196
+ r"""The slug of the short link to retrieve analytics for. Must be used along with the corresponding `domain` of the short link to fetch analytics for a specific short link."""
197
197
 
198
198
  link_id: Annotated[
199
199
  Optional[str],
200
200
  pydantic.Field(alias="linkId"),
201
201
  FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
202
202
  ] = None
203
- r"""The unique ID of the short link on Dub."""
203
+ r"""The unique ID of the short link on Dub to retrieve analytics for."""
204
204
 
205
205
  external_id: Annotated[
206
206
  Optional[str],
207
207
  pydantic.Field(alias="externalId"),
208
208
  FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
209
209
  ] = None
210
- r"""This is the ID of the link in the your database. Must be prefixed with 'ext_' when passed as a query parameter."""
210
+ r"""The ID of the link in the your database. Must be prefixed with 'ext_' when passed as a query parameter."""
211
211
 
212
212
  tenant_id: Annotated[
213
213
  Optional[str],
@@ -68,6 +68,7 @@ class UpdateCommissionType(str, Enum):
68
68
  CLICK = "click"
69
69
  LEAD = "lead"
70
70
  SALE = "sale"
71
+ CUSTOM = "custom"
71
72
 
72
73
 
73
74
  class UpdateCommissionStatus(str, Enum):
@@ -86,11 +86,39 @@ def _populate_form(
86
86
  return form
87
87
 
88
88
 
89
+ def _extract_file_properties(file_obj: Any) -> Tuple[str, Any, Any]:
90
+ """Extract file name, content, and content type from a file object."""
91
+ file_fields: Dict[str, FieldInfo] = file_obj.__class__.model_fields
92
+
93
+ file_name = ""
94
+ content = None
95
+ content_type = None
96
+
97
+ for file_field_name in file_fields:
98
+ file_field = file_fields[file_field_name]
99
+
100
+ file_metadata = find_field_metadata(file_field, MultipartFormMetadata)
101
+ if file_metadata is None:
102
+ continue
103
+
104
+ if file_metadata.content:
105
+ content = getattr(file_obj, file_field_name, None)
106
+ elif file_field_name == "content_type":
107
+ content_type = getattr(file_obj, file_field_name, None)
108
+ else:
109
+ file_name = getattr(file_obj, file_field_name)
110
+
111
+ if file_name == "" or content is None:
112
+ raise ValueError("invalid multipart/form-data file")
113
+
114
+ return file_name, content, content_type
115
+
116
+
89
117
  def serialize_multipart_form(
90
118
  media_type: str, request: Any
91
- ) -> Tuple[str, Dict[str, Any], Dict[str, Any]]:
119
+ ) -> Tuple[str, Dict[str, Any], List[Tuple[str, Any]]]:
92
120
  form: Dict[str, Any] = {}
93
- files: Dict[str, Any] = {}
121
+ files: List[Tuple[str, Any]] = []
94
122
 
95
123
  if not isinstance(request, BaseModel):
96
124
  raise TypeError("invalid request body type")
@@ -112,39 +140,32 @@ def serialize_multipart_form(
112
140
  f_name = field.alias if field.alias else name
113
141
 
114
142
  if field_metadata.file:
115
- file_fields: Dict[str, FieldInfo] = val.__class__.model_fields
116
-
117
- file_name = ""
118
- content = None
119
- content_type = None
120
-
121
- for file_field_name in file_fields:
122
- file_field = file_fields[file_field_name]
143
+ if isinstance(val, List):
144
+ # Handle array of files
145
+ for file_obj in val:
146
+ if not _is_set(file_obj):
147
+ continue
148
+
149
+ file_name, content, content_type = _extract_file_properties(file_obj)
123
150
 
124
- file_metadata = find_field_metadata(file_field, MultipartFormMetadata)
125
- if file_metadata is None:
126
- continue
151
+ if content_type is not None:
152
+ files.append((f_name + "[]", (file_name, content, content_type)))
153
+ else:
154
+ files.append((f_name + "[]", (file_name, content)))
155
+ else:
156
+ # Handle single file
157
+ file_name, content, content_type = _extract_file_properties(val)
127
158
 
128
- if file_metadata.content:
129
- content = getattr(val, file_field_name, None)
130
- elif file_field_name == "content_type":
131
- content_type = getattr(val, file_field_name, None)
159
+ if content_type is not None:
160
+ files.append((f_name, (file_name, content, content_type)))
132
161
  else:
133
- file_name = getattr(val, file_field_name)
134
-
135
- if file_name == "" or content is None:
136
- raise ValueError("invalid multipart/form-data file")
137
-
138
- if content_type is not None:
139
- files[f_name] = (file_name, content, content_type)
140
- else:
141
- files[f_name] = (file_name, content)
162
+ files.append((f_name, (file_name, content)))
142
163
  elif field_metadata.json:
143
- files[f_name] = (
164
+ files.append((f_name, (
144
165
  None,
145
166
  marshal_json(val, request_field_types[name]),
146
167
  "application/json",
147
- )
168
+ )))
148
169
  else:
149
170
  if isinstance(val, List):
150
171
  values = []
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes