dub 0.34.1__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/models/components/__init__.py +108 -26
  4. dub/models/components/analyticsbrowsers.py +18 -1
  5. dub/models/components/analyticscities.py +18 -1
  6. dub/models/components/analyticscontinents.py +18 -1
  7. dub/models/components/analyticscount.py +18 -1
  8. dub/models/components/analyticscountries.py +20 -1
  9. dub/models/components/analyticsdevices.py +18 -1
  10. dub/models/components/analyticsos.py +18 -1
  11. dub/models/components/analyticsreferers.py +18 -1
  12. dub/models/components/analyticsrefererurls.py +18 -1
  13. dub/models/components/analyticsregions.py +18 -1
  14. dub/models/components/analyticstimeseries.py +18 -1
  15. dub/models/components/analyticstoplinks.py +16 -26
  16. dub/models/components/analyticstopurls.py +18 -1
  17. dub/models/components/analyticstriggers.py +18 -1
  18. dub/models/components/commissioncreatedevent.py +96 -64
  19. dub/models/components/domainschema.py +31 -50
  20. dub/models/components/folderschema.py +18 -19
  21. dub/models/components/leadcreatedevent.py +151 -134
  22. dub/models/components/linkclickedevent.py +57 -70
  23. dub/models/components/linkschema.py +63 -64
  24. dub/models/components/linkwebhookevent.py +43 -51
  25. dub/models/components/partneranalyticscount.py +18 -1
  26. dub/models/components/partneranalyticstimeseries.py +18 -1
  27. dub/models/components/partneranalyticstoplinks.py +16 -27
  28. dub/models/components/partnerapplicationsubmittedevent.py +42 -75
  29. dub/models/components/partnerenrolledevent.py +477 -83
  30. dub/models/components/salecreatedevent.py +152 -151
  31. dub/models/errors/badrequest.py +18 -1
  32. dub/models/errors/conflict.py +18 -1
  33. dub/models/errors/forbidden.py +18 -1
  34. dub/models/errors/internalservererror.py +18 -1
  35. dub/models/errors/inviteexpired.py +18 -1
  36. dub/models/errors/notfound.py +18 -1
  37. dub/models/errors/ratelimitexceeded.py +18 -1
  38. dub/models/errors/unauthorized.py +18 -1
  39. dub/models/errors/unprocessableentity.py +18 -1
  40. dub/models/operations/__init__.py +230 -19
  41. dub/models/operations/approvebountysubmission.py +71 -45
  42. dub/models/operations/banpartner.py +14 -19
  43. dub/models/operations/bulkcreatelinks.py +86 -87
  44. dub/models/operations/bulkupdatelinks.py +97 -82
  45. dub/models/operations/checkdomainstatus.py +1 -17
  46. dub/models/operations/createdomain.py +33 -34
  47. dub/models/operations/createfolder.py +18 -19
  48. dub/models/operations/createlink.py +86 -87
  49. dub/models/operations/createpartner.py +560 -168
  50. dub/models/operations/createpartnerlink.py +74 -85
  51. dub/models/operations/createreferralsembedtoken.py +99 -87
  52. dub/models/operations/createtag.py +18 -1
  53. dub/models/operations/deactivatepartner.py +65 -0
  54. dub/models/operations/getcustomer.py +106 -105
  55. dub/models/operations/getcustomers.py +123 -105
  56. dub/models/operations/getlinkinfo.py +18 -1
  57. dub/models/operations/getlinks.py +36 -1
  58. dub/models/operations/getlinkscount.py +32 -1
  59. dub/models/operations/getqrcode.py +29 -1
  60. dub/models/operations/gettags.py +20 -1
  61. dub/models/operations/listbountysubmissions.py +63 -26
  62. dub/models/operations/listcommissions.py +129 -64
  63. dub/models/operations/listdomains.py +18 -1
  64. dub/models/operations/listevents.py +414 -389
  65. dub/models/operations/listfolders.py +18 -1
  66. dub/models/operations/listpartners.py +510 -84
  67. dub/models/operations/registerdomain.py +1 -17
  68. dub/models/operations/rejectbountysubmission.py +71 -26
  69. dub/models/operations/retrieveanalytics.py +65 -66
  70. dub/models/operations/retrievelinks.py +30 -19
  71. dub/models/operations/retrievepartneranalytics.py +25 -28
  72. dub/models/operations/tracklead.py +38 -83
  73. dub/models/operations/tracksale.py +52 -95
  74. dub/models/operations/updatecommission.py +126 -64
  75. dub/models/operations/updatecustomer.py +122 -131
  76. dub/models/operations/updatedomain.py +50 -35
  77. dub/models/operations/updatefolder.py +34 -19
  78. dub/models/operations/updatelink.py +101 -86
  79. dub/models/operations/updatetag.py +34 -1
  80. dub/models/operations/upsertlink.py +86 -87
  81. dub/models/operations/upsertpartnerlink.py +72 -78
  82. dub/partners.py +288 -0
  83. dub/sdk.py +0 -3
  84. dub/utils/__init__.py +10 -1
  85. {dub-0.34.1.dist-info → dub-0.35.0.dist-info}/METADATA +4 -8
  86. dub-0.35.0.dist-info/RECORD +143 -0
  87. dub/models/components/workspaceschema.py +0 -328
  88. dub/models/operations/getworkspace.py +0 -21
  89. dub/models/operations/updateworkspace.py +0 -78
  90. dub/workspaces.py +0 -561
  91. dub-0.34.1.dist-info/RECORD +0 -146
  92. {dub-0.34.1.dist-info → dub-0.35.0.dist-info}/WHEEL +0 -0
  93. {dub-0.34.1.dist-info → dub-0.35.0.dist-info}/licenses/LICENSE +0 -0
@@ -53,38 +53,28 @@ class UpdateCustomerRequestBody(BaseModel):
53
53
 
54
54
  @model_serializer(mode="wrap")
55
55
  def serialize_model(self, handler):
56
- optional_fields = [
57
- "email",
58
- "name",
59
- "avatar",
60
- "externalId",
61
- "stripeCustomerId",
62
- "country",
63
- ]
64
- nullable_fields = ["email", "name", "avatar", "stripeCustomerId"]
65
- null_default_fields = []
66
-
56
+ optional_fields = set(
57
+ ["email", "name", "avatar", "externalId", "stripeCustomerId", "country"]
58
+ )
59
+ nullable_fields = set(["email", "name", "avatar", "stripeCustomerId"])
67
60
  serialized = handler(self)
68
-
69
61
  m = {}
70
62
 
71
63
  for n, f in type(self).model_fields.items():
72
64
  k = f.alias or n
73
65
  val = serialized.get(k)
74
- serialized.pop(k, None)
75
-
76
- optional_nullable = k in optional_fields and k in nullable_fields
77
- is_set = (
78
- self.__pydantic_fields_set__.intersection({n})
79
- or k in null_default_fields
80
- ) # pylint: disable=no-member
81
-
82
- if val is not None and val != UNSET_SENTINEL:
83
- m[k] = val
84
- elif val != UNSET_SENTINEL and (
85
- not k in optional_fields or (optional_nullable and is_set)
86
- ):
87
- m[k] = val
66
+ is_nullable_and_explicitly_set = (
67
+ k in nullable_fields
68
+ and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
69
+ )
70
+
71
+ if val != UNSET_SENTINEL:
72
+ if (
73
+ val is not None
74
+ or k not in optional_fields
75
+ or is_nullable_and_explicitly_set
76
+ ):
77
+ m[k] = val
88
78
 
89
79
  return m
90
80
 
@@ -115,6 +105,22 @@ class UpdateCustomerRequest(BaseModel):
115
105
  FieldMetadata(request=RequestMetadata(media_type="application/json")),
116
106
  ] = None
117
107
 
108
+ @model_serializer(mode="wrap")
109
+ def serialize_model(self, handler):
110
+ optional_fields = set(["includeExpandedFields", "RequestBody"])
111
+ serialized = handler(self)
112
+ m = {}
113
+
114
+ for n, f in type(self).model_fields.items():
115
+ k = f.alias or n
116
+ val = serialized.get(k)
117
+
118
+ if val != UNSET_SENTINEL:
119
+ if val is not None or k not in optional_fields:
120
+ m[k] = val
121
+
122
+ return m
123
+
118
124
 
119
125
  class UpdateCustomerLinkTypedDict(TypedDict):
120
126
  id: str
@@ -152,30 +158,14 @@ class UpdateCustomerLink(BaseModel):
152
158
 
153
159
  @model_serializer(mode="wrap")
154
160
  def serialize_model(self, handler):
155
- optional_fields = []
156
- nullable_fields = ["programId"]
157
- null_default_fields = []
158
-
159
161
  serialized = handler(self)
160
-
161
162
  m = {}
162
163
 
163
164
  for n, f in type(self).model_fields.items():
164
165
  k = f.alias or n
165
166
  val = serialized.get(k)
166
- serialized.pop(k, None)
167
-
168
- optional_nullable = k in optional_fields and k in nullable_fields
169
- is_set = (
170
- self.__pydantic_fields_set__.intersection({n})
171
- or k in null_default_fields
172
- ) # pylint: disable=no-member
173
167
 
174
- if val is not None and val != UNSET_SENTINEL:
175
- m[k] = val
176
- elif val != UNSET_SENTINEL and (
177
- not k in optional_fields or (optional_nullable and is_set)
178
- ):
168
+ if val != UNSET_SENTINEL:
179
169
  m[k] = val
180
170
 
181
171
  return m
@@ -207,30 +197,14 @@ class UpdateCustomerPartner(BaseModel):
207
197
 
208
198
  @model_serializer(mode="wrap")
209
199
  def serialize_model(self, handler):
210
- optional_fields = []
211
- nullable_fields = ["email", "image"]
212
- null_default_fields = []
213
-
214
200
  serialized = handler(self)
215
-
216
201
  m = {}
217
202
 
218
203
  for n, f in type(self).model_fields.items():
219
204
  k = f.alias or n
220
205
  val = serialized.get(k)
221
- serialized.pop(k, None)
222
-
223
- optional_nullable = k in optional_fields and k in nullable_fields
224
- is_set = (
225
- self.__pydantic_fields_set__.intersection({n})
226
- or k in null_default_fields
227
- ) # pylint: disable=no-member
228
206
 
229
- if val is not None and val != UNSET_SENTINEL:
230
- m[k] = val
231
- elif val != UNSET_SENTINEL and (
232
- not k in optional_fields or (optional_nullable and is_set)
233
- ):
207
+ if val != UNSET_SENTINEL:
234
208
  m[k] = val
235
209
 
236
210
  return m
@@ -273,37 +247,28 @@ class UpdateCustomerDiscount(BaseModel):
273
247
 
274
248
  @model_serializer(mode="wrap")
275
249
  def serialize_model(self, handler):
276
- optional_fields = ["description", "partnersCount"]
277
- nullable_fields = [
278
- "maxDuration",
279
- "couponId",
280
- "couponTestId",
281
- "description",
282
- "partnersCount",
283
- ]
284
- null_default_fields = []
285
-
250
+ optional_fields = set(["description", "partnersCount"])
251
+ nullable_fields = set(
252
+ ["maxDuration", "couponId", "couponTestId", "description", "partnersCount"]
253
+ )
286
254
  serialized = handler(self)
287
-
288
255
  m = {}
289
256
 
290
257
  for n, f in type(self).model_fields.items():
291
258
  k = f.alias or n
292
259
  val = serialized.get(k)
293
- serialized.pop(k, None)
294
-
295
- optional_nullable = k in optional_fields and k in nullable_fields
296
- is_set = (
297
- self.__pydantic_fields_set__.intersection({n})
298
- or k in null_default_fields
299
- ) # pylint: disable=no-member
300
-
301
- if val is not None and val != UNSET_SENTINEL:
302
- m[k] = val
303
- elif val != UNSET_SENTINEL and (
304
- not k in optional_fields or (optional_nullable and is_set)
305
- ):
306
- m[k] = val
260
+ is_nullable_and_explicitly_set = (
261
+ k in nullable_fields
262
+ and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
263
+ )
264
+
265
+ if val != UNSET_SENTINEL:
266
+ if (
267
+ val is not None
268
+ or k not in optional_fields
269
+ or is_nullable_and_explicitly_set
270
+ ):
271
+ m[k] = val
307
272
 
308
273
  return m
309
274
 
@@ -313,22 +278,28 @@ class UpdateCustomerResponseBodyTypedDict(TypedDict):
313
278
 
314
279
  id: str
315
280
  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`)."""
316
- external_id: str
317
- r"""Unique identifier for the customer in the client's app."""
318
281
  name: str
319
282
  r"""Name of the customer."""
283
+ external_id: str
284
+ r"""Unique identifier for the customer in the client's app."""
320
285
  created_at: str
321
- r"""The date the customer was created."""
286
+ r"""The date the customer was created (usually the signup date or trial start date)."""
322
287
  email: NotRequired[Nullable[str]]
323
288
  r"""Email of the customer."""
324
289
  avatar: NotRequired[Nullable[str]]
325
290
  r"""Avatar URL of the customer."""
291
+ stripe_customer_id: NotRequired[Nullable[str]]
292
+ r"""The customer's Stripe customer ID. This is useful for attributing recurring sale events to the partner who referred the customer."""
326
293
  country: NotRequired[Nullable[str]]
327
294
  r"""Country of the customer."""
328
295
  sales: NotRequired[Nullable[float]]
329
296
  r"""Total number of sales for the customer."""
330
297
  sale_amount: NotRequired[Nullable[float]]
331
298
  r"""Total amount of sales for the customer."""
299
+ first_sale_at: NotRequired[Nullable[str]]
300
+ r"""The date the customer made their first sale. Useful for calculating the time to first sale and LTV."""
301
+ subscription_canceled_at: NotRequired[Nullable[str]]
302
+ r"""The date the customer canceled their subscription. Useful for calculating LTV and churn rate."""
332
303
  link: NotRequired[Nullable[UpdateCustomerLinkTypedDict]]
333
304
  program_id: NotRequired[Nullable[str]]
334
305
  partner: NotRequired[Nullable[UpdateCustomerPartnerTypedDict]]
@@ -341,14 +312,14 @@ class UpdateCustomerResponseBody(BaseModel):
341
312
  id: str
342
313
  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`)."""
343
314
 
344
- external_id: Annotated[str, pydantic.Field(alias="externalId")]
345
- r"""Unique identifier for the customer in the client's app."""
346
-
347
315
  name: str
348
316
  r"""Name of the customer."""
349
317
 
318
+ external_id: Annotated[str, pydantic.Field(alias="externalId")]
319
+ r"""Unique identifier for the customer in the client's app."""
320
+
350
321
  created_at: Annotated[str, pydantic.Field(alias="createdAt")]
351
- r"""The date the customer was created."""
322
+ r"""The date the customer was created (usually the signup date or trial start date)."""
352
323
 
353
324
  email: OptionalNullable[str] = UNSET
354
325
  r"""Email of the customer."""
@@ -356,6 +327,11 @@ class UpdateCustomerResponseBody(BaseModel):
356
327
  avatar: OptionalNullable[str] = UNSET
357
328
  r"""Avatar URL of the customer."""
358
329
 
330
+ stripe_customer_id: Annotated[
331
+ OptionalNullable[str], pydantic.Field(alias="stripeCustomerId")
332
+ ] = UNSET
333
+ r"""The customer's Stripe customer ID. This is useful for attributing recurring sale events to the partner who referred the customer."""
334
+
359
335
  country: OptionalNullable[str] = UNSET
360
336
  r"""Country of the customer."""
361
337
 
@@ -367,6 +343,16 @@ class UpdateCustomerResponseBody(BaseModel):
367
343
  ] = UNSET
368
344
  r"""Total amount of sales for the customer."""
369
345
 
346
+ first_sale_at: Annotated[
347
+ OptionalNullable[str], pydantic.Field(alias="firstSaleAt")
348
+ ] = UNSET
349
+ r"""The date the customer made their first sale. Useful for calculating the time to first sale and LTV."""
350
+
351
+ subscription_canceled_at: Annotated[
352
+ OptionalNullable[str], pydantic.Field(alias="subscriptionCanceledAt")
353
+ ] = UNSET
354
+ r"""The date the customer canceled their subscription. Useful for calculating LTV and churn rate."""
355
+
370
356
  link: OptionalNullable[UpdateCustomerLink] = UNSET
371
357
 
372
358
  program_id: Annotated[OptionalNullable[str], pydantic.Field(alias="programId")] = (
@@ -379,50 +365,55 @@ class UpdateCustomerResponseBody(BaseModel):
379
365
 
380
366
  @model_serializer(mode="wrap")
381
367
  def serialize_model(self, handler):
382
- optional_fields = [
383
- "email",
384
- "avatar",
385
- "country",
386
- "sales",
387
- "saleAmount",
388
- "link",
389
- "programId",
390
- "partner",
391
- "discount",
392
- ]
393
- nullable_fields = [
394
- "email",
395
- "avatar",
396
- "country",
397
- "sales",
398
- "saleAmount",
399
- "link",
400
- "programId",
401
- "partner",
402
- "discount",
403
- ]
404
- null_default_fields = []
405
-
368
+ optional_fields = set(
369
+ [
370
+ "email",
371
+ "avatar",
372
+ "stripeCustomerId",
373
+ "country",
374
+ "sales",
375
+ "saleAmount",
376
+ "firstSaleAt",
377
+ "subscriptionCanceledAt",
378
+ "link",
379
+ "programId",
380
+ "partner",
381
+ "discount",
382
+ ]
383
+ )
384
+ nullable_fields = set(
385
+ [
386
+ "email",
387
+ "avatar",
388
+ "stripeCustomerId",
389
+ "country",
390
+ "sales",
391
+ "saleAmount",
392
+ "firstSaleAt",
393
+ "subscriptionCanceledAt",
394
+ "link",
395
+ "programId",
396
+ "partner",
397
+ "discount",
398
+ ]
399
+ )
406
400
  serialized = handler(self)
407
-
408
401
  m = {}
409
402
 
410
403
  for n, f in type(self).model_fields.items():
411
404
  k = f.alias or n
412
405
  val = serialized.get(k)
413
- serialized.pop(k, None)
414
-
415
- optional_nullable = k in optional_fields and k in nullable_fields
416
- is_set = (
417
- self.__pydantic_fields_set__.intersection({n})
418
- or k in null_default_fields
419
- ) # pylint: disable=no-member
420
-
421
- if val is not None and val != UNSET_SENTINEL:
422
- m[k] = val
423
- elif val != UNSET_SENTINEL and (
424
- not k in optional_fields or (optional_nullable and is_set)
425
- ):
426
- m[k] = val
406
+ is_nullable_and_explicitly_set = (
407
+ k in nullable_fields
408
+ and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
409
+ )
410
+
411
+ if val != UNSET_SENTINEL:
412
+ if (
413
+ val is not None
414
+ or k not in optional_fields
415
+ or is_nullable_and_explicitly_set
416
+ ):
417
+ m[k] = val
427
418
 
428
419
  return m
@@ -63,47 +63,46 @@ class UpdateDomainRequestBody(BaseModel):
63
63
 
64
64
  @model_serializer(mode="wrap")
65
65
  def serialize_model(self, handler):
66
- optional_fields = [
67
- "slug",
68
- "expiredUrl",
69
- "notFoundUrl",
70
- "archived",
71
- "placeholder",
72
- "logo",
73
- "assetLinks",
74
- "appleAppSiteAssociation",
75
- ]
76
- nullable_fields = [
77
- "expiredUrl",
78
- "notFoundUrl",
79
- "placeholder",
80
- "logo",
81
- "assetLinks",
82
- "appleAppSiteAssociation",
83
- ]
84
- null_default_fields = []
85
-
66
+ optional_fields = set(
67
+ [
68
+ "slug",
69
+ "expiredUrl",
70
+ "notFoundUrl",
71
+ "archived",
72
+ "placeholder",
73
+ "logo",
74
+ "assetLinks",
75
+ "appleAppSiteAssociation",
76
+ ]
77
+ )
78
+ nullable_fields = set(
79
+ [
80
+ "expiredUrl",
81
+ "notFoundUrl",
82
+ "placeholder",
83
+ "logo",
84
+ "assetLinks",
85
+ "appleAppSiteAssociation",
86
+ ]
87
+ )
86
88
  serialized = handler(self)
87
-
88
89
  m = {}
89
90
 
90
91
  for n, f in type(self).model_fields.items():
91
92
  k = f.alias or n
92
93
  val = serialized.get(k)
93
- serialized.pop(k, None)
94
-
95
- optional_nullable = k in optional_fields and k in nullable_fields
96
- is_set = (
97
- self.__pydantic_fields_set__.intersection({n})
98
- or k in null_default_fields
99
- ) # pylint: disable=no-member
100
-
101
- if val is not None and val != UNSET_SENTINEL:
102
- m[k] = val
103
- elif val != UNSET_SENTINEL and (
104
- not k in optional_fields or (optional_nullable and is_set)
105
- ):
106
- m[k] = val
94
+ is_nullable_and_explicitly_set = (
95
+ k in nullable_fields
96
+ and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
97
+ )
98
+
99
+ if val != UNSET_SENTINEL:
100
+ if (
101
+ val is not None
102
+ or k not in optional_fields
103
+ or is_nullable_and_explicitly_set
104
+ ):
105
+ m[k] = val
107
106
 
108
107
  return m
109
108
 
@@ -124,3 +123,19 @@ class UpdateDomainRequest(BaseModel):
124
123
  Optional[UpdateDomainRequestBody],
125
124
  FieldMetadata(request=RequestMetadata(media_type="application/json")),
126
125
  ] = None
126
+
127
+ @model_serializer(mode="wrap")
128
+ def serialize_model(self, handler):
129
+ optional_fields = set(["RequestBody"])
130
+ serialized = handler(self)
131
+ m = {}
132
+
133
+ for n, f in type(self).model_fields.items():
134
+ k = f.alias or n
135
+ val = serialized.get(k)
136
+
137
+ if val != UNSET_SENTINEL:
138
+ if val is not None or k not in optional_fields:
139
+ m[k] = val
140
+
141
+ return m
@@ -40,31 +40,30 @@ class UpdateFolderRequestBody(BaseModel):
40
40
 
41
41
  @model_serializer(mode="wrap")
42
42
  def serialize_model(self, handler):
43
- optional_fields = ["name", "description", "accessLevel"]
44
- nullable_fields = ["description", "accessLevel"]
45
- null_default_fields = ["accessLevel"]
46
-
43
+ optional_fields = set(["name", "description", "accessLevel"])
44
+ nullable_fields = set(["description", "accessLevel"])
45
+ null_default_fields = set(["accessLevel"])
47
46
  serialized = handler(self)
48
-
49
47
  m = {}
50
48
 
51
49
  for n, f in type(self).model_fields.items():
52
50
  k = f.alias or n
53
51
  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
52
+ is_nullable_and_explicitly_set = (
53
+ k in nullable_fields
54
+ and (
55
+ self.__pydantic_fields_set__.intersection({n})
56
+ or k in null_default_fields
57
+ ) # pylint: disable=no-member
58
+ )
59
+
60
+ if val != UNSET_SENTINEL:
61
+ if (
62
+ val is not None
63
+ or k not in optional_fields
64
+ or is_nullable_and_explicitly_set
65
+ ):
66
+ m[k] = val
68
67
 
69
68
  return m
70
69
 
@@ -85,3 +84,19 @@ class UpdateFolderRequest(BaseModel):
85
84
  Optional[UpdateFolderRequestBody],
86
85
  FieldMetadata(request=RequestMetadata(media_type="application/json")),
87
86
  ] = None
87
+
88
+ @model_serializer(mode="wrap")
89
+ def serialize_model(self, handler):
90
+ optional_fields = set(["RequestBody"])
91
+ serialized = handler(self)
92
+ m = {}
93
+
94
+ for n, f in type(self).model_fields.items():
95
+ k = f.alias or n
96
+ val = serialized.get(k)
97
+
98
+ if val != UNSET_SENTINEL:
99
+ if val is not None or k not in optional_fields:
100
+ m[k] = val
101
+
102
+ return m