UncountablePythonSDK 0.0.33__py3-none-any.whl → 0.0.34__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.

Potentially problematic release.


This version of UncountablePythonSDK might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: UncountablePythonSDK
3
- Version: 0.0.33
3
+ Version: 0.0.34
4
4
  Summary: Uncountable SDK
5
5
  Project-URL: Homepage, https://github.com/uncountableinc/uncountable-python-sdk
6
6
  Project-URL: Repository, https://github.com/uncountableinc/uncountable-python-sdk.git
@@ -31,7 +31,7 @@ pkgs/serialization/serial_union.py,sha256=z8Ptj4bVHyb1ROfg0UPTwZ6Ef6iXLr0YJfAH5o
31
31
  pkgs/serialization_util/__init__.py,sha256=MVKqHTUl2YnWZAFG9xCxu1SgmkQ5xPofrAGlYg6h7rI,330
32
32
  pkgs/serialization_util/_get_type_for_serialization.py,sha256=dW5_W9MFd6wgWfW5qlWork-GBb-QFLtiOZkjk2Zqn2M,1177
33
33
  pkgs/serialization_util/convert_to_snakecase.py,sha256=H2BAo5ZdcCDN77RpLb-uP0s7-FQ5Ukwnsd3VYc1vD0M,583
34
- pkgs/serialization_util/serialization_helpers.py,sha256=byotZo00SVREW_aM0sbKQEzuI7O3zwjk_nB_OQ6S5M8,4999
34
+ pkgs/serialization_util/serialization_helpers.py,sha256=DpDrPMc0XS_dAvkLpiON0fVQHeU6t24jfRIeYUe3FJA,6916
35
35
  pkgs/strenum_compat/__init__.py,sha256=wXRFeNvBm8RU6dy1PFJ5sRLgUIEeH_DVR95Sv5qpGbk,59
36
36
  pkgs/strenum_compat/strenum_compat.py,sha256=uOUAgpYTjHs1MX8dG81jRlyTkt3KNbkV_25zp7xTX2s,36
37
37
  pkgs/type_spec/__init__.py,sha256=h5DmJTca4QVV10sZR1x0-MlkZfuGYDfapR3zHvXfzto,19
@@ -130,7 +130,7 @@ uncountable/types/api/field_options/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKH
130
130
  uncountable/types/api/field_options/upsert_field_options.py,sha256=xYtC68AabmTrYn_yV19C91yZv9tfohaRxmvCjMQ5vy8,1144
131
131
  uncountable/types/api/id_source/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr8APdZYUniAor8,55
132
132
  uncountable/types/api/id_source/list_id_source.py,sha256=S_NdAd1FIgMtCfpRK9bs4ZIJH7HdyHWImD1qiPuAKMg,1157
133
- uncountable/types/api/id_source/match_id_source.py,sha256=1Mlw0XGBw7UeWxmwelUEi7Co8Oy15jyhetfKG1BFpIM,1145
133
+ uncountable/types/api/id_source/match_id_source.py,sha256=6aaAXcuOIy0FqKw0CK4xde8o9YmryDNhX46WUEnMrRk,1048
134
134
  uncountable/types/api/input_groups/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr8APdZYUniAor8,55
135
135
  uncountable/types/api/input_groups/get_input_group_names.py,sha256=LdHWWEfVNGys6Tudienjich56Zz4bj7uXznpyYitCYA,1033
136
136
  uncountable/types/api/inputs/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr8APdZYUniAor8,55
@@ -171,7 +171,7 @@ uncountable/types/api/recipes/get_recipe_calculations.py,sha256=eQmkdZzCEuq8S2f_
171
171
  uncountable/types/api/recipes/get_recipe_links.py,sha256=hk5dfQjv7yU2r-S9b8vwWEJLPHqU0-M6SFiTLMR3fVk,985
172
172
  uncountable/types/api/recipes/get_recipe_names.py,sha256=uCpXZq5oWjr9a_Vf-yYPaVS72XOlLHgAlju6KHeQ3UA,986
173
173
  uncountable/types/api/recipes/get_recipe_output_metadata.py,sha256=L9s2ykPP4pd02Pc98LDisY8bgV8CToS6t6fXKTWqGRw,1464
174
- uncountable/types/api/recipes/get_recipes_data.py,sha256=TbJo4pkp5ePgbeH1oldThpq9jWLDYRUbrYMAv8T_LsI,5518
174
+ uncountable/types/api/recipes/get_recipes_data.py,sha256=nX4sCRY_RxztVqV-DGVpAvpayy6pn6cumS2pD1xmC5k,5429
175
175
  uncountable/types/api/recipes/remove_recipe_from_project.py,sha256=cr-VnqgBNek_WInmJln0UBn1GHMNQtRw3gsFTY_G91M,872
176
176
  uncountable/types/api/recipes/set_recipe_inputs.py,sha256=lFVfv-o_O5wHuMZdH63qlG4exFTlJM078oSAtb3XNxA,1426
177
177
  uncountable/types/api/recipes/set_recipe_metadata.py,sha256=Ba6ttd1JuS_Ypt-KpckSviWtOcQ-OTdTEJiaSYyoQL8,933
@@ -180,7 +180,7 @@ uncountable/types/api/recipes/set_recipe_tags.py,sha256=U710hgq9-t6QZGRB-ZGHskpt
180
180
  uncountable/types/api/recipes/unarchive_recipes.py,sha256=WcwFYbBsX2SKXnoBQ8locnRn7Bj1rHdtrURQVOfqgfU,814
181
181
  uncountable/types/api/triggers/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr8APdZYUniAor8,55
182
182
  uncountable/types/api/triggers/run_trigger.py,sha256=9m9M8-nlGB_sAU2Qm2lWugp4h4Osqj6QpjNfU8osd1U,901
183
- UncountablePythonSDK-0.0.33.dist-info/METADATA,sha256=bPMG0vmoieJ8foThqNXZK5DRWNQO0mZz3ypltJAx6Ck,1577
184
- UncountablePythonSDK-0.0.33.dist-info/WHEEL,sha256=cpQTJ5IWu9CdaPViMhC9YzF8gZuS5-vlfoFihTBC86A,91
185
- UncountablePythonSDK-0.0.33.dist-info/top_level.txt,sha256=1UVGjAU-6hJY9qw2iJ7nCBeEwZ793AEN5ZfKX9A1uj4,31
186
- UncountablePythonSDK-0.0.33.dist-info/RECORD,,
183
+ UncountablePythonSDK-0.0.34.dist-info/METADATA,sha256=ECBUfqxWJ1erx7_ZX0HEmWccgQVW7HD7U1MZigiJkLU,1577
184
+ UncountablePythonSDK-0.0.34.dist-info/WHEEL,sha256=mguMlWGMX-VHnMpKOjjQidIo1ssRlCFu4a4mBpz1s2M,91
185
+ UncountablePythonSDK-0.0.34.dist-info/top_level.txt,sha256=1UVGjAU-6hJY9qw2iJ7nCBeEwZ793AEN5ZfKX9A1uj4,31
186
+ UncountablePythonSDK-0.0.34.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (70.1.0)
2
+ Generator: setuptools (70.1.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,5 +1,7 @@
1
+ import dataclasses
1
2
  import datetime
2
3
  import enum
4
+ import functools
3
5
  from collections.abc import Callable, Mapping, Sequence
4
6
  from decimal import Decimal
5
7
  from typing import (
@@ -12,6 +14,11 @@ from typing import (
12
14
  overload,
13
15
  )
14
16
 
17
+ try:
18
+ import flask
19
+ except Exception:
20
+ pass
21
+
15
22
  from pkgs.argument_parser import snake_to_camel_case
16
23
  from pkgs.serialization import (
17
24
  MISSING_SENTRY,
@@ -42,10 +49,26 @@ def identity(x: T) -> T:
42
49
  def key_convert_to_camelcase(o: Any) -> str:
43
50
  if isinstance(o, OpaqueKey):
44
51
  return o
52
+ if isinstance(o, enum.StrEnum):
53
+ return o.value
45
54
  if isinstance(o, enum.Enum):
55
+ try:
56
+ print(
57
+ "DEPRECATED_SERIALIZATION--non-string-enum-used-as-key",
58
+ flask.request.path,
59
+ )
60
+ except Exception:
61
+ pass
46
62
  return o.value # type: ignore[no-any-return]
47
63
  if isinstance(o, str):
48
64
  return snake_to_camel_case(o)
65
+ if isinstance(o, int):
66
+ # temporary bypass to maintain behavior
67
+ return o # type: ignore[return-value]
68
+ try:
69
+ print("DEPRECATED_SERIALIZATION--non-string-used-as-key", o, flask.request.path)
70
+ except Exception:
71
+ pass
49
72
  return o # type: ignore[no-any-return]
50
73
 
51
74
 
@@ -61,30 +84,73 @@ def _serialize_dict(d: dict[str, Any]) -> dict[str, JsonValue]:
61
84
  return {k: serialize_for_storage(v) for k, v in d.items() if v != MISSING_SENTRY}
62
85
 
63
86
 
64
- def _convert_dataclass(d: Dataclass) -> dict[str, JsonValue]:
65
- dct = type(d)
66
- scd = get_serial_class_data(dct)
87
+ def _to_string_value(value: Any) -> str:
88
+ assert isinstance(value, (Decimal, int))
89
+ return str(value)
90
+
91
+
92
+ @dataclasses.dataclass(kw_only=True)
93
+ class DataclassConversions:
94
+ key_conversions: dict[str, str]
95
+ value_conversion_functions: dict[str, Callable[[Any], JsonValue]]
96
+
97
+
98
+ @functools.lru_cache(maxsize=10000)
99
+ def _get_dataclass_conversion_lookups(dataclass_type: Any) -> DataclassConversions:
100
+ scd = get_serial_class_data(dataclass_type)
67
101
 
68
- def key_convert(key: str) -> str:
102
+ key_conversions: dict[str, str] = {}
103
+ value_conversion_functions: dict[str, Callable[[Any], JsonValue]] = {}
104
+
105
+ for field in dataclasses.fields(dataclass_type):
106
+ key = field.name
69
107
  if scd.has_unconverted_key(key):
70
- return key
71
- return key_convert_to_camelcase(key)
108
+ key_conversions[key] = key
109
+ else:
110
+ key_conversions[key] = key_convert_to_camelcase(key)
72
111
 
73
- def value_convert(key: str, value: Any) -> JsonValue:
74
112
  if scd.has_to_string_value(key):
75
- # Limit to types we know we need to support to avoid surprises
76
- # Generics, like List/Dict would need to be per-value stringified
77
- assert isinstance(value, (Decimal, int))
78
- return str(value)
79
- if scd.has_unconverted_value(key):
80
- return value # type: ignore[no-any-return]
81
- return serialize_for_api(value) # type: ignore[no-any-return,unused-ignore]
82
-
83
- return {
84
- key_convert(k): (value_convert(k, v) if v is not None else None)
85
- for k, v in d.__dict__.items()
86
- if v != MISSING_SENTRY
87
- }
113
+ value_conversion_functions[key] = _to_string_value
114
+ elif scd.has_unconverted_value(key):
115
+ value_conversion_functions[key] = identity
116
+ else:
117
+ value_conversion_functions[key] = serialize_for_api
118
+
119
+ return DataclassConversions(
120
+ key_conversions=key_conversions,
121
+ value_conversion_functions=value_conversion_functions,
122
+ )
123
+
124
+
125
+ def _convert_dataclass(d: Any) -> dict[str, JsonValue]:
126
+ conversions = _get_dataclass_conversion_lookups(type(d)) # type: ignore[arg-type]
127
+ # return {
128
+ # conversions.key_conversions[k]: (
129
+ # conversions.value_conversion_functions[k](v) if v is not None else None
130
+ # )
131
+ # for k, v in d.__dict__.items()
132
+ # if v != MISSING_SENTRY
133
+ # }
134
+
135
+ serialized_data_class: dict[str, JsonValue] = {}
136
+ for k, v in d.__dict__.items():
137
+ if v == MISSING_SENTRY:
138
+ continue
139
+ if k not in conversions.key_conversions:
140
+ try:
141
+ print(
142
+ "DEPRECATED_SERIALIZATION--missing-dataclass-key",
143
+ k,
144
+ flask.request.path,
145
+ )
146
+ except Exception:
147
+ pass
148
+ continue
149
+ serialized_data_class[conversions.key_conversions[k]] = (
150
+ conversions.value_conversion_functions[k](v) if v is not None else None
151
+ )
152
+
153
+ return serialized_data_class
88
154
 
89
155
 
90
156
  _SERIALIZATION_FUNCS_STANDARD = {
@@ -8,7 +8,6 @@ import typing # noqa: F401
8
8
  import datetime # noqa: F401
9
9
  from decimal import Decimal # noqa: F401
10
10
  from dataclasses import dataclass
11
- from pkgs.serialization import serial_class
12
11
  from ... import base as base_t
13
12
  from ... import id_source as id_source_t
14
13
 
@@ -39,9 +38,6 @@ class Match:
39
38
 
40
39
 
41
40
  # DO NOT MODIFY -- This file is generated by type_spec
42
- @serial_class(
43
- unconverted_values={"results"},
44
- )
45
41
  @dataclass(kw_only=True)
46
42
  class Data:
47
43
  results: list[Match]
@@ -15,7 +15,6 @@ from ... import inputs as inputs_t
15
15
  from ... import outputs as outputs_t
16
16
  from ... import recipe_metadata as recipe_metadata_t
17
17
  from ... import recipe_tags as recipe_tags_t
18
- from ... import users as users_t
19
18
  from ... import workflows as workflows_t
20
19
 
21
20
  __all__: list[str] = [
@@ -97,7 +96,6 @@ class RecipeInput:
97
96
  quantity_json: base_t.JsonValue
98
97
  curve_id: typing.Optional[base_t.ObjectId]
99
98
  actual_quantity_json: base_t.JsonValue
100
- input_type: str
101
99
  behavior: str
102
100
  quantity_dec: typing.Optional[Decimal] = None
103
101
  actual_quantity_dec: typing.Optional[Decimal] = None
@@ -170,7 +168,6 @@ class Data:
170
168
  inputs: list[inputs_t.SimpleInput]
171
169
  outputs: list[outputs_t.SimpleOutput]
172
170
  output_conditions: list[SimpleOutputCondition]
173
- users: list[users_t.SimpleUser]
174
171
  recipe_tags: list[recipe_tags_t.SimpleRecipeTag]
175
172
  experiment_groups: list[experiment_groups_t.SimpleExperimentGroup]
176
173
  # DO NOT MODIFY -- This file is generated by type_spec