dub 0.34.0__py3-none-any.whl → 0.35.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. dub/_version.py +3 -3
  2. dub/basesdk.py +20 -6
  3. dub/{workspaces.py → bounties.py} +349 -69
  4. dub/models/components/__init__.py +114 -26
  5. dub/models/components/analyticsbrowsers.py +18 -1
  6. dub/models/components/analyticscities.py +18 -1
  7. dub/models/components/analyticscontinents.py +18 -1
  8. dub/models/components/analyticscount.py +18 -1
  9. dub/models/components/analyticscountries.py +20 -1
  10. dub/models/components/analyticsdevices.py +18 -1
  11. dub/models/components/analyticsos.py +18 -1
  12. dub/models/components/analyticsreferers.py +18 -1
  13. dub/models/components/analyticsrefererurls.py +18 -1
  14. dub/models/components/analyticsregions.py +18 -1
  15. dub/models/components/analyticstimeseries.py +18 -1
  16. dub/models/components/analyticstoplinks.py +16 -26
  17. dub/models/components/analyticstopurls.py +18 -1
  18. dub/models/components/analyticstriggers.py +18 -1
  19. dub/models/components/commissioncreatedevent.py +123 -63
  20. dub/models/components/domainschema.py +31 -50
  21. dub/models/components/folderschema.py +18 -19
  22. dub/models/components/leadcreatedevent.py +151 -134
  23. dub/models/components/linkclickedevent.py +57 -70
  24. dub/models/components/linkschema.py +63 -64
  25. dub/models/components/linkwebhookevent.py +43 -51
  26. dub/models/components/partneranalyticscount.py +18 -1
  27. dub/models/components/partneranalyticstimeseries.py +18 -1
  28. dub/models/components/partneranalyticstoplinks.py +16 -27
  29. dub/models/components/partnerapplicationsubmittedevent.py +42 -75
  30. dub/models/components/partnerenrolledevent.py +477 -83
  31. dub/models/components/salecreatedevent.py +152 -151
  32. dub/models/errors/badrequest.py +18 -1
  33. dub/models/errors/conflict.py +18 -1
  34. dub/models/errors/forbidden.py +18 -1
  35. dub/models/errors/internalservererror.py +18 -1
  36. dub/models/errors/inviteexpired.py +18 -1
  37. dub/models/errors/notfound.py +18 -1
  38. dub/models/errors/ratelimitexceeded.py +18 -1
  39. dub/models/errors/unauthorized.py +18 -1
  40. dub/models/errors/unprocessableentity.py +18 -1
  41. dub/models/operations/__init__.py +323 -19
  42. dub/models/operations/approvebountysubmission.py +211 -0
  43. dub/models/operations/banpartner.py +14 -19
  44. dub/models/operations/bulkcreatelinks.py +86 -87
  45. dub/models/operations/bulkupdatelinks.py +97 -82
  46. dub/models/operations/checkdomainstatus.py +1 -17
  47. dub/models/operations/createdomain.py +33 -34
  48. dub/models/operations/createfolder.py +18 -19
  49. dub/models/operations/createlink.py +86 -87
  50. dub/models/operations/createpartner.py +560 -168
  51. dub/models/operations/createpartnerlink.py +74 -85
  52. dub/models/operations/createreferralsembedtoken.py +99 -87
  53. dub/models/operations/createtag.py +18 -1
  54. dub/models/operations/deactivatepartner.py +65 -0
  55. dub/models/operations/getcustomer.py +106 -105
  56. dub/models/operations/getcustomers.py +123 -105
  57. dub/models/operations/getlinkinfo.py +18 -1
  58. dub/models/operations/getlinks.py +36 -1
  59. dub/models/operations/getlinkscount.py +32 -1
  60. dub/models/operations/getqrcode.py +29 -1
  61. dub/models/operations/gettags.py +20 -1
  62. dub/models/operations/listbountysubmissions.py +249 -0
  63. dub/models/operations/listcommissions.py +129 -64
  64. dub/models/operations/listdomains.py +18 -1
  65. dub/models/operations/listevents.py +414 -389
  66. dub/models/operations/listfolders.py +18 -1
  67. dub/models/operations/listpartners.py +510 -84
  68. dub/models/operations/registerdomain.py +1 -17
  69. dub/models/operations/rejectbountysubmission.py +219 -0
  70. dub/models/operations/retrieveanalytics.py +65 -66
  71. dub/models/operations/retrievelinks.py +30 -19
  72. dub/models/operations/retrievepartneranalytics.py +25 -28
  73. dub/models/operations/tracklead.py +38 -83
  74. dub/models/operations/tracksale.py +52 -95
  75. dub/models/operations/updatecommission.py +126 -64
  76. dub/models/operations/updatecustomer.py +122 -131
  77. dub/models/operations/updatedomain.py +50 -35
  78. dub/models/operations/updatefolder.py +34 -19
  79. dub/models/operations/updatelink.py +101 -86
  80. dub/models/operations/updatetag.py +34 -1
  81. dub/models/operations/upsertlink.py +86 -87
  82. dub/models/operations/upsertpartnerlink.py +77 -90
  83. dub/partners.py +288 -0
  84. dub/sdk.py +3 -3
  85. dub/utils/__init__.py +10 -1
  86. {dub-0.34.0.dist-info → dub-0.35.0.dist-info}/METADATA +10 -8
  87. dub-0.35.0.dist-info/RECORD +143 -0
  88. dub/models/components/workspaceschema.py +0 -328
  89. dub/models/operations/getworkspace.py +0 -21
  90. dub/models/operations/updateworkspace.py +0 -78
  91. dub-0.34.0.dist-info/RECORD +0 -142
  92. {dub-0.34.0.dist-info → dub-0.35.0.dist-info}/WHEEL +0 -0
  93. {dub-0.34.0.dist-info → dub-0.35.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,8 +1,9 @@
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, UNSET_SENTINEL
5
5
  import pydantic
6
+ from pydantic import model_serializer
6
7
  from typing import Optional
7
8
  from typing_extensions import Annotated, NotRequired, TypedDict
8
9
 
@@ -35,3 +36,19 @@ class AnalyticsTopUrls(BaseModel):
35
36
 
36
37
  sale_amount: Annotated[Optional[float], pydantic.Field(alias="saleAmount")] = 0
37
38
  r"""The total amount of sales from this URL, in cents"""
39
+
40
+ @model_serializer(mode="wrap")
41
+ def serialize_model(self, handler):
42
+ optional_fields = set(["clicks", "leads", "sales", "saleAmount"])
43
+ serialized = handler(self)
44
+ m = {}
45
+
46
+ for n, f in type(self).model_fields.items():
47
+ k = f.alias or n
48
+ val = serialized.get(k)
49
+
50
+ if val != UNSET_SENTINEL:
51
+ if val is not None or k not in optional_fields:
52
+ m[k] = val
53
+
54
+ return m
@@ -1,9 +1,10 @@
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, UNSET_SENTINEL
5
5
  from enum import Enum
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
 
@@ -45,3 +46,19 @@ class AnalyticsTriggers(BaseModel):
45
46
 
46
47
  sale_amount: Annotated[Optional[float], pydantic.Field(alias="saleAmount")] = 0
47
48
  r"""The total amount of sales from this trigger method, in cents"""
49
+
50
+ @model_serializer(mode="wrap")
51
+ def serialize_model(self, handler):
52
+ optional_fields = set(["clicks", "leads", "sales", "saleAmount"])
53
+ serialized = handler(self)
54
+ m = {}
55
+
56
+ for n, f in type(self).model_fields.items():
57
+ k = f.alias or n
58
+ val = serialized.get(k)
59
+
60
+ if val != UNSET_SENTINEL:
61
+ if val is not None or k not in optional_fields:
62
+ m[k] = val
63
+
64
+ return m
@@ -89,31 +89,28 @@ class CommissionCreatedEventPartner(BaseModel):
89
89
 
90
90
  @model_serializer(mode="wrap")
91
91
  def serialize_model(self, handler):
92
- optional_fields = ["groupId"]
93
- nullable_fields = ["email", "image", "payoutsEnabledAt", "country", "groupId"]
94
- null_default_fields = []
95
-
92
+ optional_fields = set(["groupId"])
93
+ nullable_fields = set(
94
+ ["email", "image", "payoutsEnabledAt", "country", "groupId"]
95
+ )
96
96
  serialized = handler(self)
97
-
98
97
  m = {}
99
98
 
100
99
  for n, f in type(self).model_fields.items():
101
100
  k = f.alias or n
102
101
  val = serialized.get(k)
103
- serialized.pop(k, None)
104
-
105
- optional_nullable = k in optional_fields and k in nullable_fields
106
- is_set = (
107
- self.__pydantic_fields_set__.intersection({n})
108
- or k in null_default_fields
109
- ) # pylint: disable=no-member
110
-
111
- if val is not None and val != UNSET_SENTINEL:
112
- m[k] = val
113
- elif val != UNSET_SENTINEL and (
114
- not k in optional_fields or (optional_nullable and is_set)
115
- ):
116
- m[k] = val
102
+ is_nullable_and_explicitly_set = (
103
+ k in nullable_fields
104
+ and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
105
+ )
106
+
107
+ if val != UNSET_SENTINEL:
108
+ if (
109
+ val is not None
110
+ or k not in optional_fields
111
+ or is_nullable_and_explicitly_set
112
+ ):
113
+ m[k] = val
117
114
 
118
115
  return m
119
116
 
@@ -121,36 +118,42 @@ class CommissionCreatedEventPartner(BaseModel):
121
118
  class CommissionCreatedEventCustomerTypedDict(TypedDict):
122
119
  id: str
123
120
  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`)."""
124
- external_id: str
125
- r"""Unique identifier for the customer in the client's app."""
126
121
  name: str
127
122
  r"""Name of the customer."""
123
+ external_id: str
124
+ r"""Unique identifier for the customer in the client's app."""
128
125
  created_at: str
129
- r"""The date the customer was created."""
126
+ r"""The date the customer was created (usually the signup date or trial start date)."""
130
127
  email: NotRequired[Nullable[str]]
131
128
  r"""Email of the customer."""
132
129
  avatar: NotRequired[Nullable[str]]
133
130
  r"""Avatar URL of the customer."""
131
+ stripe_customer_id: NotRequired[Nullable[str]]
132
+ r"""The customer's Stripe customer ID. This is useful for attributing recurring sale events to the partner who referred the customer."""
134
133
  country: NotRequired[Nullable[str]]
135
134
  r"""Country of the customer."""
136
135
  sales: NotRequired[Nullable[float]]
137
136
  r"""Total number of sales for the customer."""
138
137
  sale_amount: NotRequired[Nullable[float]]
139
138
  r"""Total amount of sales for the customer."""
139
+ first_sale_at: NotRequired[Nullable[str]]
140
+ r"""The date the customer made their first sale. Useful for calculating the time to first sale and LTV."""
141
+ subscription_canceled_at: NotRequired[Nullable[str]]
142
+ r"""The date the customer canceled their subscription. Useful for calculating LTV and churn rate."""
140
143
 
141
144
 
142
145
  class CommissionCreatedEventCustomer(BaseModel):
143
146
  id: str
144
147
  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`)."""
145
148
 
146
- external_id: Annotated[str, pydantic.Field(alias="externalId")]
147
- r"""Unique identifier for the customer in the client's app."""
148
-
149
149
  name: str
150
150
  r"""Name of the customer."""
151
151
 
152
+ external_id: Annotated[str, pydantic.Field(alias="externalId")]
153
+ r"""Unique identifier for the customer in the client's app."""
154
+
152
155
  created_at: Annotated[str, pydantic.Field(alias="createdAt")]
153
- r"""The date the customer was created."""
156
+ r"""The date the customer was created (usually the signup date or trial start date)."""
154
157
 
155
158
  email: OptionalNullable[str] = UNSET
156
159
  r"""Email of the customer."""
@@ -158,6 +161,11 @@ class CommissionCreatedEventCustomer(BaseModel):
158
161
  avatar: OptionalNullable[str] = UNSET
159
162
  r"""Avatar URL of the customer."""
160
163
 
164
+ stripe_customer_id: Annotated[
165
+ OptionalNullable[str], pydantic.Field(alias="stripeCustomerId")
166
+ ] = UNSET
167
+ r"""The customer's Stripe customer ID. This is useful for attributing recurring sale events to the partner who referred the customer."""
168
+
161
169
  country: OptionalNullable[str] = UNSET
162
170
  r"""Country of the customer."""
163
171
 
@@ -169,35 +177,87 @@ class CommissionCreatedEventCustomer(BaseModel):
169
177
  ] = UNSET
170
178
  r"""Total amount of sales for the customer."""
171
179
 
180
+ first_sale_at: Annotated[
181
+ OptionalNullable[str], pydantic.Field(alias="firstSaleAt")
182
+ ] = UNSET
183
+ r"""The date the customer made their first sale. Useful for calculating the time to first sale and LTV."""
184
+
185
+ subscription_canceled_at: Annotated[
186
+ OptionalNullable[str], pydantic.Field(alias="subscriptionCanceledAt")
187
+ ] = UNSET
188
+ r"""The date the customer canceled their subscription. Useful for calculating LTV and churn rate."""
189
+
172
190
  @model_serializer(mode="wrap")
173
191
  def serialize_model(self, handler):
174
- optional_fields = ["email", "avatar", "country", "sales", "saleAmount"]
175
- nullable_fields = ["email", "avatar", "country", "sales", "saleAmount"]
176
- null_default_fields = []
177
-
192
+ optional_fields = set(
193
+ [
194
+ "email",
195
+ "avatar",
196
+ "stripeCustomerId",
197
+ "country",
198
+ "sales",
199
+ "saleAmount",
200
+ "firstSaleAt",
201
+ "subscriptionCanceledAt",
202
+ ]
203
+ )
204
+ nullable_fields = set(
205
+ [
206
+ "email",
207
+ "avatar",
208
+ "stripeCustomerId",
209
+ "country",
210
+ "sales",
211
+ "saleAmount",
212
+ "firstSaleAt",
213
+ "subscriptionCanceledAt",
214
+ ]
215
+ )
178
216
  serialized = handler(self)
179
-
180
217
  m = {}
181
218
 
182
219
  for n, f in type(self).model_fields.items():
183
220
  k = f.alias or n
184
221
  val = serialized.get(k)
185
- serialized.pop(k, None)
222
+ is_nullable_and_explicitly_set = (
223
+ k in nullable_fields
224
+ and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
225
+ )
226
+
227
+ if val != UNSET_SENTINEL:
228
+ if (
229
+ val is not None
230
+ or k not in optional_fields
231
+ or is_nullable_and_explicitly_set
232
+ ):
233
+ m[k] = val
186
234
 
187
- optional_nullable = k in optional_fields and k in nullable_fields
188
- is_set = (
189
- self.__pydantic_fields_set__.intersection({n})
190
- or k in null_default_fields
191
- ) # pylint: disable=no-member
235
+ return m
192
236
 
193
- if val is not None and val != UNSET_SENTINEL:
194
- m[k] = val
195
- elif val != UNSET_SENTINEL and (
196
- not k in optional_fields or (optional_nullable and is_set)
197
- ):
198
- m[k] = val
199
237
 
200
- return m
238
+ class CommissionCreatedEventLinkTypedDict(TypedDict):
239
+ id: str
240
+ r"""The unique ID of the short link."""
241
+ short_link: str
242
+ r"""The full URL of the short link, including the https protocol (e.g. `https://dub.sh/try`)."""
243
+ domain: str
244
+ r"""The domain of the short link. If not provided, the primary domain for the workspace will be used (or `dub.sh` if the workspace has no domains)."""
245
+ key: str
246
+ r"""The short link slug. If not provided, a random 7-character slug will be generated."""
247
+
248
+
249
+ class CommissionCreatedEventLink(BaseModel):
250
+ id: str
251
+ r"""The unique ID of the short link."""
252
+
253
+ short_link: Annotated[str, pydantic.Field(alias="shortLink")]
254
+ r"""The full URL of the short link, including the https protocol (e.g. `https://dub.sh/try`)."""
255
+
256
+ domain: str
257
+ r"""The domain of the short link. If not provided, the primary domain for the workspace will be used (or `dub.sh` if the workspace has no domains)."""
258
+
259
+ key: str
260
+ r"""The short link slug. If not provided, a random 7-character slug will be generated."""
201
261
 
202
262
 
203
263
  class CommissionCreatedEventDataTypedDict(TypedDict):
@@ -213,6 +273,7 @@ class CommissionCreatedEventDataTypedDict(TypedDict):
213
273
  created_at: str
214
274
  updated_at: str
215
275
  partner: CommissionCreatedEventPartnerTypedDict
276
+ link: Nullable[CommissionCreatedEventLinkTypedDict]
216
277
  type: NotRequired[CommissionCreatedEventType]
217
278
  user_id: NotRequired[Nullable[str]]
218
279
  r"""The user who created the manual commission."""
@@ -243,6 +304,8 @@ class CommissionCreatedEventData(BaseModel):
243
304
 
244
305
  partner: CommissionCreatedEventPartner
245
306
 
307
+ link: Nullable[CommissionCreatedEventLink]
308
+
246
309
  type: Optional[CommissionCreatedEventType] = None
247
310
 
248
311
  user_id: Annotated[OptionalNullable[str], pydantic.Field(alias="userId")] = UNSET
@@ -252,31 +315,28 @@ class CommissionCreatedEventData(BaseModel):
252
315
 
253
316
  @model_serializer(mode="wrap")
254
317
  def serialize_model(self, handler):
255
- optional_fields = ["type", "userId", "customer"]
256
- nullable_fields = ["invoiceId", "description", "userId", "customer"]
257
- null_default_fields = []
258
-
318
+ optional_fields = set(["type", "userId", "customer"])
319
+ nullable_fields = set(
320
+ ["invoiceId", "description", "userId", "customer", "link"]
321
+ )
259
322
  serialized = handler(self)
260
-
261
323
  m = {}
262
324
 
263
325
  for n, f in type(self).model_fields.items():
264
326
  k = f.alias or n
265
327
  val = serialized.get(k)
266
- serialized.pop(k, None)
267
-
268
- optional_nullable = k in optional_fields and k in nullable_fields
269
- is_set = (
270
- self.__pydantic_fields_set__.intersection({n})
271
- or k in null_default_fields
272
- ) # pylint: disable=no-member
273
-
274
- if val is not None and val != UNSET_SENTINEL:
275
- m[k] = val
276
- elif val != UNSET_SENTINEL and (
277
- not k in optional_fields or (optional_nullable and is_set)
278
- ):
279
- m[k] = val
328
+ is_nullable_and_explicitly_set = (
329
+ k in nullable_fields
330
+ and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
331
+ )
332
+
333
+ if val != UNSET_SENTINEL:
334
+ if (
335
+ val is not None
336
+ or k not in optional_fields
337
+ or is_nullable_and_explicitly_set
338
+ ):
339
+ m[k] = val
280
340
 
281
341
  return m
282
342
 
@@ -45,30 +45,14 @@ class RegisteredDomain(BaseModel):
45
45
 
46
46
  @model_serializer(mode="wrap")
47
47
  def serialize_model(self, handler):
48
- optional_fields = []
49
- nullable_fields = ["autoRenewalDisabledAt"]
50
- null_default_fields = []
51
-
52
48
  serialized = handler(self)
53
-
54
49
  m = {}
55
50
 
56
51
  for n, f in type(self).model_fields.items():
57
52
  k = f.alias or n
58
53
  val = serialized.get(k)
59
- serialized.pop(k, None)
60
-
61
- optional_nullable = k in optional_fields and k in nullable_fields
62
- is_set = (
63
- self.__pydantic_fields_set__.intersection({n})
64
- or k in null_default_fields
65
- ) # pylint: disable=no-member
66
54
 
67
- if val is not None and val != UNSET_SENTINEL:
68
- m[k] = val
69
- elif val != UNSET_SENTINEL and (
70
- not k in optional_fields or (optional_nullable and is_set)
71
- ):
55
+ if val != UNSET_SENTINEL:
72
56
  m[k] = val
73
57
 
74
58
  return m
@@ -156,44 +140,41 @@ class DomainSchema(BaseModel):
156
140
 
157
141
  @model_serializer(mode="wrap")
158
142
  def serialize_model(self, handler):
159
- optional_fields = [
160
- "verified",
161
- "primary",
162
- "archived",
163
- "assetLinks",
164
- "appleAppSiteAssociation",
165
- ]
166
- nullable_fields = [
167
- "placeholder",
168
- "expiredUrl",
169
- "notFoundUrl",
170
- "logo",
171
- "assetLinks",
172
- "appleAppSiteAssociation",
173
- "registeredDomain",
174
- ]
175
- null_default_fields = ["assetLinks", "appleAppSiteAssociation"]
176
-
143
+ optional_fields = set(
144
+ ["verified", "primary", "archived", "assetLinks", "appleAppSiteAssociation"]
145
+ )
146
+ nullable_fields = set(
147
+ [
148
+ "placeholder",
149
+ "expiredUrl",
150
+ "notFoundUrl",
151
+ "logo",
152
+ "assetLinks",
153
+ "appleAppSiteAssociation",
154
+ "registeredDomain",
155
+ ]
156
+ )
157
+ null_default_fields = set(["assetLinks", "appleAppSiteAssociation"])
177
158
  serialized = handler(self)
178
-
179
159
  m = {}
180
160
 
181
161
  for n, f in type(self).model_fields.items():
182
162
  k = f.alias or n
183
163
  val = serialized.get(k)
184
- serialized.pop(k, None)
185
-
186
- optional_nullable = k in optional_fields and k in nullable_fields
187
- is_set = (
188
- self.__pydantic_fields_set__.intersection({n})
189
- or k in null_default_fields
190
- ) # pylint: disable=no-member
191
-
192
- if val is not None and val != UNSET_SENTINEL:
193
- m[k] = val
194
- elif val != UNSET_SENTINEL and (
195
- not k in optional_fields or (optional_nullable and is_set)
196
- ):
197
- m[k] = val
164
+ is_nullable_and_explicitly_set = (
165
+ k in nullable_fields
166
+ and (
167
+ self.__pydantic_fields_set__.intersection({n})
168
+ or k in null_default_fields
169
+ ) # pylint: disable=no-member
170
+ )
171
+
172
+ if val != UNSET_SENTINEL:
173
+ if (
174
+ val is not None
175
+ or k not in optional_fields
176
+ or is_nullable_and_explicitly_set
177
+ ):
178
+ m[k] = val
198
179
 
199
180
  return m
@@ -61,30 +61,29 @@ class FolderSchema(BaseModel):
61
61
 
62
62
  @model_serializer(mode="wrap")
63
63
  def serialize_model(self, handler):
64
- optional_fields = ["accessLevel"]
65
- nullable_fields = ["description", "accessLevel"]
66
- null_default_fields = ["accessLevel"]
67
-
64
+ optional_fields = set(["accessLevel"])
65
+ nullable_fields = set(["description", "accessLevel"])
66
+ null_default_fields = set(["accessLevel"])
68
67
  serialized = handler(self)
69
-
70
68
  m = {}
71
69
 
72
70
  for n, f in type(self).model_fields.items():
73
71
  k = f.alias or n
74
72
  val = serialized.get(k)
75
- serialized.pop(k, None)
76
-
77
- optional_nullable = k in optional_fields and k in nullable_fields
78
- is_set = (
79
- self.__pydantic_fields_set__.intersection({n})
80
- or k in null_default_fields
81
- ) # pylint: disable=no-member
82
-
83
- if val is not None and val != UNSET_SENTINEL:
84
- m[k] = val
85
- elif val != UNSET_SENTINEL and (
86
- not k in optional_fields or (optional_nullable and is_set)
87
- ):
88
- m[k] = val
73
+ is_nullable_and_explicitly_set = (
74
+ k in nullable_fields
75
+ and (
76
+ self.__pydantic_fields_set__.intersection({n})
77
+ or k in null_default_fields
78
+ ) # pylint: disable=no-member
79
+ )
80
+
81
+ if val != UNSET_SENTINEL:
82
+ if (
83
+ val is not None
84
+ or k not in optional_fields
85
+ or is_nullable_and_explicitly_set
86
+ ):
87
+ m[k] = val
89
88
 
90
89
  return m