dub 0.33.0__py3-none-any.whl → 0.34.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 (59) hide show
  1. dub/_version.py +3 -3
  2. dub/analytics.py +2 -0
  3. dub/basesdk.py +6 -0
  4. dub/commissions.py +4 -0
  5. dub/customers.py +8 -0
  6. dub/domains.py +12 -0
  7. dub/embed_tokens.py +2 -0
  8. dub/events.py +2 -0
  9. dub/folders.py +8 -0
  10. dub/links.py +20 -0
  11. dub/models/components/__init__.py +49 -149
  12. dub/models/components/leadcreatedevent.py +8 -8
  13. dub/models/components/linkclickedevent.py +12 -12
  14. dub/models/components/linkerrorschema.py +12 -12
  15. dub/models/components/linkschema.py +3 -3
  16. dub/models/components/linktagschema.py +3 -3
  17. dub/models/components/linktagschemaoutput.py +38 -0
  18. dub/models/components/linkwebhookevent.py +8 -10
  19. dub/models/components/partnerenrolledevent.py +4 -4
  20. dub/models/components/salecreatedevent.py +8 -8
  21. dub/models/operations/__init__.py +130 -22
  22. dub/models/operations/createpartner.py +4 -55
  23. dub/models/operations/createpartnerlink.py +0 -51
  24. dub/models/operations/createreferralsembedtoken.py +0 -51
  25. dub/models/operations/getcustomers.py +18 -0
  26. dub/models/operations/getlinkinfo.py +0 -2
  27. dub/models/operations/getlinks.py +2 -2
  28. dub/models/operations/getlinkscount.py +2 -2
  29. dub/models/operations/getqrcode.py +1 -1
  30. dub/models/operations/listdomains.py +1 -1
  31. dub/models/operations/listevents.py +2016 -21
  32. dub/models/operations/listpartners.py +4 -4
  33. dub/models/operations/retrieveanalytics.py +16 -5
  34. dub/models/operations/retrievelinks.py +2 -2
  35. dub/models/operations/tracklead.py +4 -4
  36. dub/models/operations/updatecustomer.py +23 -11
  37. dub/models/operations/updatelink.py +0 -2
  38. dub/models/operations/updateworkspace.py +3 -3
  39. dub/models/operations/upsertpartnerlink.py +0 -51
  40. dub/partners.py +22 -4
  41. dub/qr_codes.py +2 -0
  42. dub/tags.py +24 -12
  43. dub/track.py +4 -0
  44. dub/types/basemodel.py +41 -3
  45. dub/utils/__init__.py +0 -3
  46. dub/utils/enums.py +60 -0
  47. dub/utils/forms.py +21 -10
  48. dub/utils/queryparams.py +14 -2
  49. dub/utils/requestbodies.py +3 -3
  50. dub/utils/serializers.py +0 -20
  51. dub/workspaces.py +4 -0
  52. {dub-0.33.0.dist-info → dub-0.34.0.dist-info}/METADATA +14 -14
  53. {dub-0.33.0.dist-info → dub-0.34.0.dist-info}/RECORD +55 -58
  54. dub/models/components/clickevent.py +0 -557
  55. dub/models/components/continentcode.py +0 -16
  56. dub/models/components/leadevent.py +0 -681
  57. dub/models/components/saleevent.py +0 -780
  58. {dub-0.33.0.dist-info → dub-0.34.0.dist-info}/WHEEL +0 -0
  59. {dub-0.33.0.dist-info → dub-0.34.0.dist-info}/licenses/LICENSE +0 -0
dub/tags.py CHANGED
@@ -23,7 +23,7 @@ class Tags(BaseSDK):
23
23
  server_url: Optional[str] = None,
24
24
  timeout_ms: Optional[int] = None,
25
25
  http_headers: Optional[Mapping[str, str]] = None,
26
- ) -> components.LinkTagSchema:
26
+ ) -> components.LinkTagSchemaOutput:
27
27
  r"""Create a tag
28
28
 
29
29
  Create a tag for the authenticated workspace.
@@ -66,6 +66,7 @@ class Tags(BaseSDK):
66
66
  get_serialized_body=lambda: utils.serialize_request_body(
67
67
  request, False, True, "json", Optional[operations.CreateTagRequestBody]
68
68
  ),
69
+ allow_empty_value=None,
69
70
  timeout_ms=timeout_ms,
70
71
  )
71
72
 
@@ -104,7 +105,7 @@ class Tags(BaseSDK):
104
105
 
105
106
  response_data: Any = None
106
107
  if utils.match_response(http_res, "201", "application/json"):
107
- return unmarshal_json_response(components.LinkTagSchema, http_res)
108
+ return unmarshal_json_response(components.LinkTagSchemaOutput, http_res)
108
109
  if utils.match_response(http_res, "400", "application/json"):
109
110
  response_data = unmarshal_json_response(errors.BadRequestData, http_res)
110
111
  raise errors.BadRequest(response_data, http_res)
@@ -160,7 +161,7 @@ class Tags(BaseSDK):
160
161
  server_url: Optional[str] = None,
161
162
  timeout_ms: Optional[int] = None,
162
163
  http_headers: Optional[Mapping[str, str]] = None,
163
- ) -> components.LinkTagSchema:
164
+ ) -> components.LinkTagSchemaOutput:
164
165
  r"""Create a tag
165
166
 
166
167
  Create a tag for the authenticated workspace.
@@ -203,6 +204,7 @@ class Tags(BaseSDK):
203
204
  get_serialized_body=lambda: utils.serialize_request_body(
204
205
  request, False, True, "json", Optional[operations.CreateTagRequestBody]
205
206
  ),
207
+ allow_empty_value=None,
206
208
  timeout_ms=timeout_ms,
207
209
  )
208
210
 
@@ -241,7 +243,7 @@ class Tags(BaseSDK):
241
243
 
242
244
  response_data: Any = None
243
245
  if utils.match_response(http_res, "201", "application/json"):
244
- return unmarshal_json_response(components.LinkTagSchema, http_res)
246
+ return unmarshal_json_response(components.LinkTagSchemaOutput, http_res)
245
247
  if utils.match_response(http_res, "400", "application/json"):
246
248
  response_data = unmarshal_json_response(errors.BadRequestData, http_res)
247
249
  raise errors.BadRequest(response_data, http_res)
@@ -292,7 +294,7 @@ class Tags(BaseSDK):
292
294
  server_url: Optional[str] = None,
293
295
  timeout_ms: Optional[int] = None,
294
296
  http_headers: Optional[Mapping[str, str]] = None,
295
- ) -> List[components.LinkTagSchema]:
297
+ ) -> List[components.LinkTagSchemaOutput]:
296
298
  r"""Retrieve a list of tags
297
299
 
298
300
  Retrieve a list of tags for the authenticated workspace.
@@ -330,6 +332,7 @@ class Tags(BaseSDK):
330
332
  accept_header_value="application/json",
331
333
  http_headers=http_headers,
332
334
  security=self.sdk_configuration.security,
335
+ allow_empty_value=None,
333
336
  timeout_ms=timeout_ms,
334
337
  )
335
338
 
@@ -368,7 +371,9 @@ class Tags(BaseSDK):
368
371
 
369
372
  response_data: Any = None
370
373
  if utils.match_response(http_res, "200", "application/json"):
371
- return unmarshal_json_response(List[components.LinkTagSchema], http_res)
374
+ return unmarshal_json_response(
375
+ List[components.LinkTagSchemaOutput], http_res
376
+ )
372
377
  if utils.match_response(http_res, "400", "application/json"):
373
378
  response_data = unmarshal_json_response(errors.BadRequestData, http_res)
374
379
  raise errors.BadRequest(response_data, http_res)
@@ -419,7 +424,7 @@ class Tags(BaseSDK):
419
424
  server_url: Optional[str] = None,
420
425
  timeout_ms: Optional[int] = None,
421
426
  http_headers: Optional[Mapping[str, str]] = None,
422
- ) -> List[components.LinkTagSchema]:
427
+ ) -> List[components.LinkTagSchemaOutput]:
423
428
  r"""Retrieve a list of tags
424
429
 
425
430
  Retrieve a list of tags for the authenticated workspace.
@@ -457,6 +462,7 @@ class Tags(BaseSDK):
457
462
  accept_header_value="application/json",
458
463
  http_headers=http_headers,
459
464
  security=self.sdk_configuration.security,
465
+ allow_empty_value=None,
460
466
  timeout_ms=timeout_ms,
461
467
  )
462
468
 
@@ -495,7 +501,9 @@ class Tags(BaseSDK):
495
501
 
496
502
  response_data: Any = None
497
503
  if utils.match_response(http_res, "200", "application/json"):
498
- return unmarshal_json_response(List[components.LinkTagSchema], http_res)
504
+ return unmarshal_json_response(
505
+ List[components.LinkTagSchemaOutput], http_res
506
+ )
499
507
  if utils.match_response(http_res, "400", "application/json"):
500
508
  response_data = unmarshal_json_response(errors.BadRequestData, http_res)
501
509
  raise errors.BadRequest(response_data, http_res)
@@ -552,7 +560,7 @@ class Tags(BaseSDK):
552
560
  server_url: Optional[str] = None,
553
561
  timeout_ms: Optional[int] = None,
554
562
  http_headers: Optional[Mapping[str, str]] = None,
555
- ) -> components.LinkTagSchema:
563
+ ) -> components.LinkTagSchemaOutput:
556
564
  r"""Update a tag
557
565
 
558
566
  Update a tag in the workspace.
@@ -601,6 +609,7 @@ class Tags(BaseSDK):
601
609
  "json",
602
610
  Optional[operations.UpdateTagRequestBody],
603
611
  ),
612
+ allow_empty_value=None,
604
613
  timeout_ms=timeout_ms,
605
614
  )
606
615
 
@@ -639,7 +648,7 @@ class Tags(BaseSDK):
639
648
 
640
649
  response_data: Any = None
641
650
  if utils.match_response(http_res, "200", "application/json"):
642
- return unmarshal_json_response(components.LinkTagSchema, http_res)
651
+ return unmarshal_json_response(components.LinkTagSchemaOutput, http_res)
643
652
  if utils.match_response(http_res, "400", "application/json"):
644
653
  response_data = unmarshal_json_response(errors.BadRequestData, http_res)
645
654
  raise errors.BadRequest(response_data, http_res)
@@ -696,7 +705,7 @@ class Tags(BaseSDK):
696
705
  server_url: Optional[str] = None,
697
706
  timeout_ms: Optional[int] = None,
698
707
  http_headers: Optional[Mapping[str, str]] = None,
699
- ) -> components.LinkTagSchema:
708
+ ) -> components.LinkTagSchemaOutput:
700
709
  r"""Update a tag
701
710
 
702
711
  Update a tag in the workspace.
@@ -745,6 +754,7 @@ class Tags(BaseSDK):
745
754
  "json",
746
755
  Optional[operations.UpdateTagRequestBody],
747
756
  ),
757
+ allow_empty_value=None,
748
758
  timeout_ms=timeout_ms,
749
759
  )
750
760
 
@@ -783,7 +793,7 @@ class Tags(BaseSDK):
783
793
 
784
794
  response_data: Any = None
785
795
  if utils.match_response(http_res, "200", "application/json"):
786
- return unmarshal_json_response(components.LinkTagSchema, http_res)
796
+ return unmarshal_json_response(components.LinkTagSchemaOutput, http_res)
787
797
  if utils.match_response(http_res, "400", "application/json"):
788
798
  response_data = unmarshal_json_response(errors.BadRequestData, http_res)
789
799
  raise errors.BadRequest(response_data, http_res)
@@ -872,6 +882,7 @@ class Tags(BaseSDK):
872
882
  accept_header_value="application/json",
873
883
  http_headers=http_headers,
874
884
  security=self.sdk_configuration.security,
885
+ allow_empty_value=None,
875
886
  timeout_ms=timeout_ms,
876
887
  )
877
888
 
@@ -999,6 +1010,7 @@ class Tags(BaseSDK):
999
1010
  accept_header_value="application/json",
1000
1011
  http_headers=http_headers,
1001
1012
  security=self.sdk_configuration.security,
1013
+ allow_empty_value=None,
1002
1014
  timeout_ms=timeout_ms,
1003
1015
  )
1004
1016
 
dub/track.py CHANGED
@@ -66,6 +66,7 @@ class Track(BaseSDK):
66
66
  get_serialized_body=lambda: utils.serialize_request_body(
67
67
  request, False, True, "json", Optional[operations.TrackLeadRequestBody]
68
68
  ),
69
+ allow_empty_value=None,
69
70
  timeout_ms=timeout_ms,
70
71
  )
71
72
 
@@ -203,6 +204,7 @@ class Track(BaseSDK):
203
204
  get_serialized_body=lambda: utils.serialize_request_body(
204
205
  request, False, True, "json", Optional[operations.TrackLeadRequestBody]
205
206
  ),
207
+ allow_empty_value=None,
206
208
  timeout_ms=timeout_ms,
207
209
  )
208
210
 
@@ -340,6 +342,7 @@ class Track(BaseSDK):
340
342
  get_serialized_body=lambda: utils.serialize_request_body(
341
343
  request, False, True, "json", Optional[operations.TrackSaleRequestBody]
342
344
  ),
345
+ allow_empty_value=None,
343
346
  timeout_ms=timeout_ms,
344
347
  )
345
348
 
@@ -477,6 +480,7 @@ class Track(BaseSDK):
477
480
  get_serialized_body=lambda: utils.serialize_request_body(
478
481
  request, False, True, "json", Optional[operations.TrackSaleRequestBody]
479
482
  ),
483
+ allow_empty_value=None,
480
484
  timeout_ms=timeout_ms,
481
485
  )
482
486
 
dub/types/basemodel.py CHANGED
@@ -2,7 +2,8 @@
2
2
 
3
3
  from pydantic import ConfigDict, model_serializer
4
4
  from pydantic import BaseModel as PydanticBaseModel
5
- from typing import TYPE_CHECKING, Literal, Optional, TypeVar, Union
5
+ from pydantic_core import core_schema
6
+ from typing import TYPE_CHECKING, Any, Literal, Optional, TypeVar, Union
6
7
  from typing_extensions import TypeAliasType, TypeAlias
7
8
 
8
9
 
@@ -35,5 +36,42 @@ else:
35
36
  "OptionalNullable", Union[Optional[Nullable[T]], Unset], type_params=(T,)
36
37
  )
37
38
 
38
- UnrecognizedInt: TypeAlias = int
39
- UnrecognizedStr: TypeAlias = str
39
+
40
+ class UnrecognizedStr(str):
41
+ @classmethod
42
+ def __get_pydantic_core_schema__(cls, _source_type: Any, _handler: Any) -> core_schema.CoreSchema:
43
+ # Make UnrecognizedStr only work in lax mode, not strict mode
44
+ # This makes it a "fallback" option when more specific types (like Literals) don't match
45
+ def validate_lax(v: Any) -> 'UnrecognizedStr':
46
+ if isinstance(v, cls):
47
+ return v
48
+ return cls(str(v))
49
+
50
+ # Use lax_or_strict_schema where strict always fails
51
+ # This forces Pydantic to prefer other union members in strict mode
52
+ # and only fall back to UnrecognizedStr in lax mode
53
+ return core_schema.lax_or_strict_schema(
54
+ lax_schema=core_schema.chain_schema([
55
+ core_schema.str_schema(),
56
+ core_schema.no_info_plain_validator_function(validate_lax)
57
+ ]),
58
+ strict_schema=core_schema.none_schema(), # Always fails in strict mode
59
+ )
60
+
61
+
62
+ class UnrecognizedInt(int):
63
+ @classmethod
64
+ def __get_pydantic_core_schema__(cls, _source_type: Any, _handler: Any) -> core_schema.CoreSchema:
65
+ # Make UnrecognizedInt only work in lax mode, not strict mode
66
+ # This makes it a "fallback" option when more specific types (like Literals) don't match
67
+ def validate_lax(v: Any) -> 'UnrecognizedInt':
68
+ if isinstance(v, cls):
69
+ return v
70
+ return cls(int(v))
71
+ return core_schema.lax_or_strict_schema(
72
+ lax_schema=core_schema.chain_schema([
73
+ core_schema.int_schema(),
74
+ core_schema.no_info_plain_validator_function(validate_lax)
75
+ ]),
76
+ strict_schema=core_schema.none_schema(), # Always fails in strict mode
77
+ )
dub/utils/__init__.py CHANGED
@@ -41,7 +41,6 @@ if TYPE_CHECKING:
41
41
  validate_decimal,
42
42
  validate_float,
43
43
  validate_int,
44
- validate_open_enum,
45
44
  )
46
45
  from .url import generate_url, template_url, remove_suffix
47
46
  from .values import (
@@ -102,7 +101,6 @@ __all__ = [
102
101
  "validate_const",
103
102
  "validate_float",
104
103
  "validate_int",
105
- "validate_open_enum",
106
104
  "cast_partial",
107
105
  ]
108
106
 
@@ -155,7 +153,6 @@ _dynamic_imports: dict[str, str] = {
155
153
  "validate_const": ".serializers",
156
154
  "validate_float": ".serializers",
157
155
  "validate_int": ".serializers",
158
- "validate_open_enum": ".serializers",
159
156
  "cast_partial": ".values",
160
157
  }
161
158
 
dub/utils/enums.py CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  import enum
4
4
  import sys
5
+ from typing import Any
6
+
7
+ from pydantic_core import core_schema
8
+
5
9
 
6
10
  class OpenEnumMeta(enum.EnumMeta):
7
11
  # The __call__ method `boundary` kwarg was added in 3.11 and must be present
@@ -72,3 +76,59 @@ class OpenEnumMeta(enum.EnumMeta):
72
76
  )
73
77
  except ValueError:
74
78
  return value
79
+
80
+ def __new__(mcs, name, bases, namespace, **kwargs):
81
+ cls = super().__new__(mcs, name, bases, namespace, **kwargs)
82
+
83
+ # Add __get_pydantic_core_schema__ to make open enums work correctly
84
+ # in union discrimination. In strict mode (used by Pydantic for unions),
85
+ # only known enum values match. In lax mode, unknown values are accepted.
86
+ def __get_pydantic_core_schema__(
87
+ cls_inner: Any, _source_type: Any, _handler: Any
88
+ ) -> core_schema.CoreSchema:
89
+ # Create a validator that only accepts known enum values (for strict mode)
90
+ def validate_strict(v: Any) -> Any:
91
+ if isinstance(v, cls_inner):
92
+ return v
93
+ # Use the parent EnumMeta's __call__ which raises ValueError for unknown values
94
+ return enum.EnumMeta.__call__(cls_inner, v)
95
+
96
+ # Create a lax validator that accepts unknown values
97
+ def validate_lax(v: Any) -> Any:
98
+ if isinstance(v, cls_inner):
99
+ return v
100
+ try:
101
+ return enum.EnumMeta.__call__(cls_inner, v)
102
+ except ValueError:
103
+ # Return the raw value for unknown enum values
104
+ return v
105
+
106
+ # Determine the base type schema (str or int)
107
+ is_int_enum = False
108
+ for base in cls_inner.__mro__:
109
+ if base is int:
110
+ is_int_enum = True
111
+ break
112
+ if base is str:
113
+ break
114
+
115
+ base_schema = (
116
+ core_schema.int_schema()
117
+ if is_int_enum
118
+ else core_schema.str_schema()
119
+ )
120
+
121
+ # Use lax_or_strict_schema:
122
+ # - strict mode: only known enum values match (raises ValueError for unknown)
123
+ # - lax mode: accept any value, return enum member or raw value
124
+ return core_schema.lax_or_strict_schema(
125
+ lax_schema=core_schema.chain_schema(
126
+ [base_schema, core_schema.no_info_plain_validator_function(validate_lax)]
127
+ ),
128
+ strict_schema=core_schema.chain_schema(
129
+ [base_schema, core_schema.no_info_plain_validator_function(validate_strict)]
130
+ ),
131
+ )
132
+
133
+ setattr(cls, "__get_pydantic_core_schema__", classmethod(__get_pydantic_core_schema__))
134
+ return cls
dub/utils/forms.py CHANGED
@@ -142,16 +142,21 @@ def serialize_multipart_form(
142
142
  if field_metadata.file:
143
143
  if isinstance(val, List):
144
144
  # Handle array of files
145
+ array_field_name = f_name + "[]"
145
146
  for file_obj in val:
146
147
  if not _is_set(file_obj):
147
148
  continue
148
-
149
- file_name, content, content_type = _extract_file_properties(file_obj)
149
+
150
+ file_name, content, content_type = _extract_file_properties(
151
+ file_obj
152
+ )
150
153
 
151
154
  if content_type is not None:
152
- files.append((f_name + "[]", (file_name, content, content_type)))
155
+ files.append(
156
+ (array_field_name, (file_name, content, content_type))
157
+ )
153
158
  else:
154
- files.append((f_name + "[]", (file_name, content)))
159
+ files.append((array_field_name, (file_name, content)))
155
160
  else:
156
161
  # Handle single file
157
162
  file_name, content, content_type = _extract_file_properties(val)
@@ -161,11 +166,16 @@ def serialize_multipart_form(
161
166
  else:
162
167
  files.append((f_name, (file_name, content)))
163
168
  elif field_metadata.json:
164
- files.append((f_name, (
165
- None,
166
- marshal_json(val, request_field_types[name]),
167
- "application/json",
168
- )))
169
+ files.append(
170
+ (
171
+ f_name,
172
+ (
173
+ None,
174
+ marshal_json(val, request_field_types[name]),
175
+ "application/json",
176
+ ),
177
+ )
178
+ )
169
179
  else:
170
180
  if isinstance(val, List):
171
181
  values = []
@@ -175,7 +185,8 @@ def serialize_multipart_form(
175
185
  continue
176
186
  values.append(_val_to_string(value))
177
187
 
178
- form[f_name + "[]"] = values
188
+ array_field_name = f_name + "[]"
189
+ form[array_field_name] = values
179
190
  else:
180
191
  form[f_name] = _val_to_string(val)
181
192
  return media_type, form, files
dub/utils/queryparams.py CHANGED
@@ -27,12 +27,13 @@ from .forms import _populate_form
27
27
  def get_query_params(
28
28
  query_params: Any,
29
29
  gbls: Optional[Any] = None,
30
+ allow_empty_value: Optional[List[str]] = None,
30
31
  ) -> Dict[str, List[str]]:
31
32
  params: Dict[str, List[str]] = {}
32
33
 
33
- globals_already_populated = _populate_query_params(query_params, gbls, params, [])
34
+ globals_already_populated = _populate_query_params(query_params, gbls, params, [], allow_empty_value)
34
35
  if _is_set(gbls):
35
- _populate_query_params(gbls, None, params, globals_already_populated)
36
+ _populate_query_params(gbls, None, params, globals_already_populated, allow_empty_value)
36
37
 
37
38
  return params
38
39
 
@@ -42,6 +43,7 @@ def _populate_query_params(
42
43
  gbls: Any,
43
44
  query_param_values: Dict[str, List[str]],
44
45
  skip_fields: List[str],
46
+ allow_empty_value: Optional[List[str]] = None,
45
47
  ) -> List[str]:
46
48
  globals_already_populated: List[str] = []
47
49
 
@@ -69,6 +71,16 @@ def _populate_query_params(
69
71
  globals_already_populated.append(name)
70
72
 
71
73
  f_name = field.alias if field.alias is not None else name
74
+
75
+ allow_empty_set = set(allow_empty_value or [])
76
+ should_include_empty = f_name in allow_empty_set and (
77
+ value is None or value == [] or value == ""
78
+ )
79
+
80
+ if should_include_empty:
81
+ query_param_values[f_name] = [""]
82
+ continue
83
+
72
84
  serialization = metadata.serialization
73
85
  if serialization is not None:
74
86
  serialized_parms = _get_serialized_params(
@@ -44,15 +44,15 @@ def serialize_request_body(
44
44
 
45
45
  serialized_request_body = SerializedRequestBody(media_type)
46
46
 
47
- if re.match(r"(application|text)\/.*?\+*json.*", media_type) is not None:
47
+ if re.match(r"^(application|text)\/([^+]+\+)*json.*", media_type) is not None:
48
48
  serialized_request_body.content = marshal_json(request_body, request_body_type)
49
- elif re.match(r"multipart\/.*", media_type) is not None:
49
+ elif re.match(r"^multipart\/.*", media_type) is not None:
50
50
  (
51
51
  serialized_request_body.media_type,
52
52
  serialized_request_body.data,
53
53
  serialized_request_body.files,
54
54
  ) = serialize_multipart_form(media_type, request_body)
55
- elif re.match(r"application\/x-www-form-urlencoded.*", media_type) is not None:
55
+ elif re.match(r"^application\/x-www-form-urlencoded.*", media_type) is not None:
56
56
  serialized_request_body.data = serialize_form_data(request_body)
57
57
  elif isinstance(request_body, (bytes, bytearray, io.BytesIO, io.BufferedReader)):
58
58
  serialized_request_body.content = request_body
dub/utils/serializers.py CHANGED
@@ -102,26 +102,6 @@ def validate_int(b):
102
102
  return int(b)
103
103
 
104
104
 
105
- def validate_open_enum(is_int: bool):
106
- def validate(e):
107
- if e is None:
108
- return None
109
-
110
- if isinstance(e, Unset):
111
- return e
112
-
113
- if is_int:
114
- if not isinstance(e, int):
115
- raise ValueError("Expected int")
116
- else:
117
- if not isinstance(e, str):
118
- raise ValueError("Expected string")
119
-
120
- return e
121
-
122
- return validate
123
-
124
-
125
105
  def validate_const(v):
126
106
  def validate(c):
127
107
  # Optional[T] is a Union[T, None]
dub/workspaces.py CHANGED
@@ -58,6 +58,7 @@ class Workspaces(BaseSDK):
58
58
  accept_header_value="application/json",
59
59
  http_headers=http_headers,
60
60
  security=self.sdk_configuration.security,
61
+ allow_empty_value=None,
61
62
  timeout_ms=timeout_ms,
62
63
  )
63
64
 
@@ -187,6 +188,7 @@ class Workspaces(BaseSDK):
187
188
  accept_header_value="application/json",
188
189
  http_headers=http_headers,
189
190
  security=self.sdk_configuration.security,
191
+ allow_empty_value=None,
190
192
  timeout_ms=timeout_ms,
191
193
  )
192
194
 
@@ -331,6 +333,7 @@ class Workspaces(BaseSDK):
331
333
  "json",
332
334
  Optional[operations.UpdateWorkspaceRequestBody],
333
335
  ),
336
+ allow_empty_value=None,
334
337
  timeout_ms=timeout_ms,
335
338
  )
336
339
 
@@ -475,6 +478,7 @@ class Workspaces(BaseSDK):
475
478
  "json",
476
479
  Optional[operations.UpdateWorkspaceRequestBody],
477
480
  ),
481
+ allow_empty_value=None,
478
482
  timeout_ms=timeout_ms,
479
483
  )
480
484
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dub
3
- Version: 0.33.0
3
+ Version: 0.34.0
4
4
  Summary: Python Client SDK Generated by Speakeasy
5
5
  License-File: LICENSE
6
6
  Author: Speakeasy
@@ -277,23 +277,23 @@ asyncio.run(main())
277
277
  <details open>
278
278
  <summary>Available methods</summary>
279
279
 
280
- ### [analytics](https://github.com/dubinc/dub-python/blob/master/docs/sdks/analytics/README.md)
280
+ ### [Analytics](https://github.com/dubinc/dub-python/blob/master/docs/sdks/analytics/README.md)
281
281
 
282
282
  * [retrieve](https://github.com/dubinc/dub-python/blob/master/docs/sdks/analytics/README.md#retrieve) - Retrieve analytics for a link, a domain, or the authenticated workspace.
283
283
 
284
- ### [commissions](https://github.com/dubinc/dub-python/blob/master/docs/sdks/commissions/README.md)
284
+ ### [Commissions](https://github.com/dubinc/dub-python/blob/master/docs/sdks/commissions/README.md)
285
285
 
286
286
  * [list](https://github.com/dubinc/dub-python/blob/master/docs/sdks/commissions/README.md#list) - Get commissions for a program.
287
287
  * [update](https://github.com/dubinc/dub-python/blob/master/docs/sdks/commissions/README.md#update) - Update a commission.
288
288
 
289
- ### [customers](https://github.com/dubinc/dub-python/blob/master/docs/sdks/customers/README.md)
289
+ ### [Customers](https://github.com/dubinc/dub-python/blob/master/docs/sdks/customers/README.md)
290
290
 
291
291
  * [list](https://github.com/dubinc/dub-python/blob/master/docs/sdks/customers/README.md#list) - Retrieve a list of customers
292
292
  * [get](https://github.com/dubinc/dub-python/blob/master/docs/sdks/customers/README.md#get) - Retrieve a customer
293
293
  * [update](https://github.com/dubinc/dub-python/blob/master/docs/sdks/customers/README.md#update) - Update a customer
294
294
  * [delete](https://github.com/dubinc/dub-python/blob/master/docs/sdks/customers/README.md#delete) - Delete a customer
295
295
 
296
- ### [domains](https://github.com/dubinc/dub-python/blob/master/docs/sdks/domains/README.md)
296
+ ### [Domains](https://github.com/dubinc/dub-python/blob/master/docs/sdks/domains/README.md)
297
297
 
298
298
  * [create](https://github.com/dubinc/dub-python/blob/master/docs/sdks/domains/README.md#create) - Create a domain
299
299
  * [list](https://github.com/dubinc/dub-python/blob/master/docs/sdks/domains/README.md#list) - Retrieve a list of domains
@@ -302,22 +302,22 @@ asyncio.run(main())
302
302
  * [register](https://github.com/dubinc/dub-python/blob/master/docs/sdks/domains/README.md#register) - Register a domain
303
303
  * [check_status](https://github.com/dubinc/dub-python/blob/master/docs/sdks/domains/README.md#check_status) - Check the availability of one or more domains
304
304
 
305
- ### [embed_tokens](https://github.com/dubinc/dub-python/blob/master/docs/sdks/embedtokens/README.md)
305
+ ### [EmbedTokens](https://github.com/dubinc/dub-python/blob/master/docs/sdks/embedtokens/README.md)
306
306
 
307
307
  * [referrals](https://github.com/dubinc/dub-python/blob/master/docs/sdks/embedtokens/README.md#referrals) - Create a referrals embed token
308
308
 
309
- ### [events](https://github.com/dubinc/dub-python/blob/master/docs/sdks/events/README.md)
309
+ ### [Events](https://github.com/dubinc/dub-python/blob/master/docs/sdks/events/README.md)
310
310
 
311
311
  * [list](https://github.com/dubinc/dub-python/blob/master/docs/sdks/events/README.md#list) - Retrieve a list of events
312
312
 
313
- ### [folders](https://github.com/dubinc/dub-python/blob/master/docs/sdks/folders/README.md)
313
+ ### [Folders](https://github.com/dubinc/dub-python/blob/master/docs/sdks/folders/README.md)
314
314
 
315
315
  * [create](https://github.com/dubinc/dub-python/blob/master/docs/sdks/folders/README.md#create) - Create a folder
316
316
  * [list](https://github.com/dubinc/dub-python/blob/master/docs/sdks/folders/README.md#list) - Retrieve a list of folders
317
317
  * [update](https://github.com/dubinc/dub-python/blob/master/docs/sdks/folders/README.md#update) - Update a folder
318
318
  * [delete](https://github.com/dubinc/dub-python/blob/master/docs/sdks/folders/README.md#delete) - Delete a folder
319
319
 
320
- ### [links](https://github.com/dubinc/dub-python/blob/master/docs/sdks/links/README.md)
320
+ ### [Links](https://github.com/dubinc/dub-python/blob/master/docs/sdks/links/README.md)
321
321
 
322
322
  * [create](https://github.com/dubinc/dub-python/blob/master/docs/sdks/links/README.md#create) - Create a link
323
323
  * [list](https://github.com/dubinc/dub-python/blob/master/docs/sdks/links/README.md#list) - Retrieve a list of links
@@ -330,7 +330,7 @@ asyncio.run(main())
330
330
  * [delete_many](https://github.com/dubinc/dub-python/blob/master/docs/sdks/links/README.md#delete_many) - Bulk delete links
331
331
  * [upsert](https://github.com/dubinc/dub-python/blob/master/docs/sdks/links/README.md#upsert) - Upsert a link
332
332
 
333
- ### [partners](https://github.com/dubinc/dub-python/blob/master/docs/sdks/partners/README.md)
333
+ ### [Partners](https://github.com/dubinc/dub-python/blob/master/docs/sdks/partners/README.md)
334
334
 
335
335
  * [create](https://github.com/dubinc/dub-python/blob/master/docs/sdks/partners/README.md#create) - Create or update a partner
336
336
  * [list](https://github.com/dubinc/dub-python/blob/master/docs/sdks/partners/README.md#list) - List all partners
@@ -340,23 +340,23 @@ asyncio.run(main())
340
340
  * [analytics](https://github.com/dubinc/dub-python/blob/master/docs/sdks/partners/README.md#analytics) - Retrieve analytics for a partner
341
341
  * [ban](https://github.com/dubinc/dub-python/blob/master/docs/sdks/partners/README.md#ban) - Ban a partner
342
342
 
343
- ### [qr_codes](https://github.com/dubinc/dub-python/blob/master/docs/sdks/qrcodes/README.md)
343
+ ### [QRCodes](https://github.com/dubinc/dub-python/blob/master/docs/sdks/qrcodes/README.md)
344
344
 
345
345
  * [get](https://github.com/dubinc/dub-python/blob/master/docs/sdks/qrcodes/README.md#get) - Retrieve a QR code
346
346
 
347
- ### [tags](https://github.com/dubinc/dub-python/blob/master/docs/sdks/tags/README.md)
347
+ ### [Tags](https://github.com/dubinc/dub-python/blob/master/docs/sdks/tags/README.md)
348
348
 
349
349
  * [create](https://github.com/dubinc/dub-python/blob/master/docs/sdks/tags/README.md#create) - Create a tag
350
350
  * [list](https://github.com/dubinc/dub-python/blob/master/docs/sdks/tags/README.md#list) - Retrieve a list of tags
351
351
  * [update](https://github.com/dubinc/dub-python/blob/master/docs/sdks/tags/README.md#update) - Update a tag
352
352
  * [delete](https://github.com/dubinc/dub-python/blob/master/docs/sdks/tags/README.md#delete) - Delete a tag
353
353
 
354
- ### [track](https://github.com/dubinc/dub-python/blob/master/docs/sdks/track/README.md)
354
+ ### [Track](https://github.com/dubinc/dub-python/blob/master/docs/sdks/track/README.md)
355
355
 
356
356
  * [lead](https://github.com/dubinc/dub-python/blob/master/docs/sdks/track/README.md#lead) - Track a lead
357
357
  * [sale](https://github.com/dubinc/dub-python/blob/master/docs/sdks/track/README.md#sale) - Track a sale
358
358
 
359
- ### [workspaces](https://github.com/dubinc/dub-python/blob/master/docs/sdks/workspaces/README.md)
359
+ ### [Workspaces](https://github.com/dubinc/dub-python/blob/master/docs/sdks/workspaces/README.md)
360
360
 
361
361
  * [get](https://github.com/dubinc/dub-python/blob/master/docs/sdks/workspaces/README.md#get) - Retrieve a workspace
362
362
  * [update](https://github.com/dubinc/dub-python/blob/master/docs/sdks/workspaces/README.md#update) - Update a workspace