UncountablePythonSDK 0.0.6__py3-none-any.whl → 0.0.7__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.
- {UncountablePythonSDK-0.0.6.dist-info → UncountablePythonSDK-0.0.7.dist-info}/METADATA +1 -1
- {UncountablePythonSDK-0.0.6.dist-info → UncountablePythonSDK-0.0.7.dist-info}/RECORD +20 -17
- {UncountablePythonSDK-0.0.6.dist-info → UncountablePythonSDK-0.0.7.dist-info}/WHEEL +1 -1
- pkgs/type_spec/builder.py +0 -61
- pkgs/type_spec/config.py +3 -0
- pkgs/type_spec/emit_open_api.py +33 -22
- pkgs/type_spec/emit_open_api_util.py +6 -2
- pkgs/type_spec/emit_python.py +3 -2
- type_spec/external/api/entity/create_entities.yaml +3 -25
- type_spec/external/api/entity/create_entity.yaml +3 -13
- type_spec/external/api/recipes/get_recipe_links.yaml +2 -37
- uncountable/types/__init__.py +6 -0
- uncountable/types/api/entity/create_entities.py +5 -25
- uncountable/types/api/entity/create_entity.py +5 -11
- uncountable/types/api/recipes/get_recipe_links.py +3 -37
- uncountable/types/client_base.py +33 -30
- uncountable/types/entity.py +271 -0
- uncountable/types/field_values.py +28 -0
- uncountable/types/recipe_links.py +49 -0
- {UncountablePythonSDK-0.0.6.dist-info → UncountablePythonSDK-0.0.7.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: UncountablePythonSDK
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.7
|
|
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
|
|
@@ -17,12 +17,12 @@ pkgs/strenum_compat/__init__.py,sha256=wXRFeNvBm8RU6dy1PFJ5sRLgUIEeH_DVR95Sv5qpG
|
|
|
17
17
|
pkgs/strenum_compat/strenum_compat.py,sha256=vGJlrMZpOqiGXvv21IbS0amdB2xQ2CdYKvnfEfHLr8E,156
|
|
18
18
|
pkgs/type_spec/__init__.py,sha256=h5DmJTca4QVV10sZR1x0-MlkZfuGYDfapR3zHvXfzto,19
|
|
19
19
|
pkgs/type_spec/__main__.py,sha256=5bJaX9Y_-FavP0qwzhk-z-V97UY7uaezJTa1zhO_HHQ,1048
|
|
20
|
-
pkgs/type_spec/builder.py,sha256=
|
|
21
|
-
pkgs/type_spec/config.py,sha256=
|
|
20
|
+
pkgs/type_spec/builder.py,sha256=Pl3UzHYgci3XRYsJ-pEsrdKu26mrJeLQv66OS2KePGc,38993
|
|
21
|
+
pkgs/type_spec/config.py,sha256=wXALehQr_CcteOY_KbeI3rtmGgqVzHcveAhgKCDfQoQ,4934
|
|
22
22
|
pkgs/type_spec/emit_io_ts.py,sha256=gCEfS81w_ifqjLVJ3_cpy9Gq03o6H5nEsh35WAkqGGE,5606
|
|
23
|
-
pkgs/type_spec/emit_open_api.py,sha256=
|
|
24
|
-
pkgs/type_spec/emit_open_api_util.py,sha256=
|
|
25
|
-
pkgs/type_spec/emit_python.py,sha256=
|
|
23
|
+
pkgs/type_spec/emit_open_api.py,sha256=8tidMRWubBmiiq-XCu_2732IvwTc6R3miurdlBCv3-w,16939
|
|
24
|
+
pkgs/type_spec/emit_open_api_util.py,sha256=S4eHeryxiGUNujypmwn8UZQSlaCCWn7uMpiZzNJJqCg,2054
|
|
25
|
+
pkgs/type_spec/emit_python.py,sha256=Y-3eXhWwWns2wZQwcriMN3rgNN20ad5NDphKbGkdCwI,35459
|
|
26
26
|
pkgs/type_spec/emit_typescript.py,sha256=6tlzvyHc7iIEic01AtjYWuzy7Ac3KijtXRQ3IQSN7JE,18670
|
|
27
27
|
pkgs/type_spec/emit_typescript_util.py,sha256=MZMigIsYIYOXLjJqp-DSRYsztWbIKd9QQEmYRRqnGQ4,894
|
|
28
28
|
pkgs/type_spec/load_types.py,sha256=LMIkrk0n-Kh4I4CUOBzuboYtsAHBYuMrL9d2hkU83f4,2184
|
|
@@ -39,8 +39,8 @@ pkgs/type_spec/value_spec/convert_type.py,sha256=SAYyEV6orQJJbkXSE4hhtOQJ2vKUXJC
|
|
|
39
39
|
pkgs/type_spec/value_spec/emit_python.py,sha256=M9NyHi-akTw4cUsHCEK7rsFirb8ngYThiIW7xh2xSko,6943
|
|
40
40
|
pkgs/type_spec/value_spec/types.py,sha256=a2zxbbCRWepY1l8OtjeCDKgBKFPFHVgV99oP6pTtaro,441
|
|
41
41
|
type_spec/external/api/batch/execute_batch.yaml,sha256=gpdSev3sLEC_cMVSZdj-9bc_XDFDqdPdOII9Ojme2N8,1170
|
|
42
|
-
type_spec/external/api/entity/create_entities.yaml,sha256=
|
|
43
|
-
type_spec/external/api/entity/create_entity.yaml,sha256=
|
|
42
|
+
type_spec/external/api/entity/create_entities.yaml,sha256=7DqYSkUPUwAN6e6P9Nx8Fzl7I2xsV5qZZQiRAOsiWG4,1057
|
|
43
|
+
type_spec/external/api/entity/create_entity.yaml,sha256=yQpvVJJO7RnLCCpZTztTRmuQncIIobhEQYftLODTljE,1252
|
|
44
44
|
type_spec/external/api/entity/get_entities_data.yaml,sha256=-whdM4l4xsAb_kc-bHdNEwJr4pCN7WA4Y7z-CBJXRag,1470
|
|
45
45
|
type_spec/external/api/entity/list_entities.yaml,sha256=pMNfFIbnc8onE1I4yiCXJSAXGZa0IaiPTe_cQ1HM27I,2030
|
|
46
46
|
type_spec/external/api/entity/resolve_entity_ids.yaml,sha256=Of5zyjHYzxVZEjknTxVlJMnsAxdgOWWaerPdKwdybjc,720
|
|
@@ -60,7 +60,7 @@ type_spec/external/api/recipe_metadata/get_recipe_metadata_data.yaml,sha256=MbNI
|
|
|
60
60
|
type_spec/external/api/recipes/create_recipes.yaml,sha256=8JnRVjQ_vDKYKXbgZ6Z_RBcm5WechFvw_hg8oJ_6zcs,1930
|
|
61
61
|
type_spec/external/api/recipes/get_curve.yaml,sha256=Th1HDGN6EXLYAiOusnjAXylfgc6OpKbYlc9MpZnGujQ,1592
|
|
62
62
|
type_spec/external/api/recipes/get_recipe_calculations.yaml,sha256=pnZtQH4S8_tAL5a1laI3QhAugJU_AbqMyK7zszIHqj4,1440
|
|
63
|
-
type_spec/external/api/recipes/get_recipe_links.yaml,sha256=
|
|
63
|
+
type_spec/external/api/recipes/get_recipe_links.yaml,sha256=VXpJndQt04rmTvT7v7FdcyfBhg1u1B3_a7iGeeoSXWk,765
|
|
64
64
|
type_spec/external/api/recipes/get_recipe_names.yaml,sha256=lfZGDRl8__cjYPtH9fPFHRnOgmae192x2l5b4xTxBZo,894
|
|
65
65
|
type_spec/external/api/recipes/get_recipe_output_metadata.yaml,sha256=Y9fszN16FFnfxo9SfIkzS8fDnZ20L6_iBVyHaPN58uI,1584
|
|
66
66
|
type_spec/external/api/recipes/get_recipes_data.yaml,sha256=Q41ci5cbGPuEYR72HLu4f-0Kl_Za4QPmzNbtp2fZtJ0,16291
|
|
@@ -70,15 +70,18 @@ uncountable/__init__.py,sha256=281cC2hs8pbrD0jVKMol-tbWSh7Zcsc8oRT42dKteyE,102
|
|
|
70
70
|
uncountable/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
71
71
|
uncountable/core/__init__.py,sha256=GCXRRhhYv-yKzqKjAij7GcNiOr90BBbgdhhpusWtmUc,100
|
|
72
72
|
uncountable/core/client.py,sha256=jcJBGwe31fOqfGiUJzW_KMcfE0hax55jgVVliALBNLQ,4160
|
|
73
|
-
uncountable/types/__init__.py,sha256=
|
|
73
|
+
uncountable/types/__init__.py,sha256=NXgMS4P3ettpqcV1Hu96i8EliDd9SkcTt9tHU5jPdtg,2955
|
|
74
74
|
uncountable/types/base.py,sha256=7yMC3sCQ13wd92896Ga2XbZffCqq98SKv09rFGb1ulg,2682
|
|
75
|
-
uncountable/types/client_base.py,sha256=
|
|
75
|
+
uncountable/types/client_base.py,sha256=pf8vo7Bl55XCUbXiUmQ4q6JrWZ0qufj_TEP8zNMAw5E,20388
|
|
76
|
+
uncountable/types/entity.py,sha256=DypCKRn-xOOQoVkd3JpcEN9DbDZSAIgBVDziS6eM6GQ,11526
|
|
77
|
+
uncountable/types/field_values.py,sha256=kBFSZVEMvK-wr1YMyK5RD4mw4LEI6aRIySJstX32ol4,743
|
|
78
|
+
uncountable/types/recipe_links.py,sha256=8TfRnV8sWOQaZ57_2VGET5Avsa_k5hGlYqtGBdfEvjM,1353
|
|
76
79
|
uncountable/types/api/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr8APdZYUniAor8,55
|
|
77
80
|
uncountable/types/api/batch/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr8APdZYUniAor8,55
|
|
78
81
|
uncountable/types/api/batch/execute_batch.py,sha256=cCZo_akwJR4_ET6oOBChdlrCQlxUw8V9i8tDpv7JTIc,1696
|
|
79
82
|
uncountable/types/api/entity/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr8APdZYUniAor8,55
|
|
80
|
-
uncountable/types/api/entity/create_entities.py,sha256=
|
|
81
|
-
uncountable/types/api/entity/create_entity.py,sha256=
|
|
83
|
+
uncountable/types/api/entity/create_entities.py,sha256=ivhGU4pIVT09H4mtZ8yhBO2SyfbtcdM_hZN4-8KEYVI,1403
|
|
84
|
+
uncountable/types/api/entity/create_entity.py,sha256=xEmzm1H1LnMfSIUYvvfKgNKWaMFOBhFOctb1KPsEjdo,1604
|
|
82
85
|
uncountable/types/api/entity/get_entities_data.py,sha256=Bp4J_7Gqz-gZtps0ClNHGZti7aGmEmgpaqCWkiYHcc8,1500
|
|
83
86
|
uncountable/types/api/entity/list_entities.py,sha256=bCi3CRKw76-lK6qlMjva3ZHBDNnw2jMwjfTEzYAkULg,1542
|
|
84
87
|
uncountable/types/api/entity/resolve_entity_ids.py,sha256=HRkW-q5eoin73co-C58HWpHuaODgXimRi4OHsaWOkoQ,992
|
|
@@ -104,13 +107,13 @@ uncountable/types/api/recipes/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr8
|
|
|
104
107
|
uncountable/types/api/recipes/create_recipes.py,sha256=ZvepPEwH9z5x31G7hYBlaKnYPCBu5sCHWsTajUSs_aM,1765
|
|
105
108
|
uncountable/types/api/recipes/get_curve.py,sha256=-N5GUATarAR8eLzMCTuLz6VMx-dU6L741lBN2OzuO-4,1322
|
|
106
109
|
uncountable/types/api/recipes/get_recipe_calculations.py,sha256=BltC1nSL0x-mGS1Q7XXp8Eg9WsgXJfjAI4YlNaLDIek,1460
|
|
107
|
-
uncountable/types/api/recipes/get_recipe_links.py,sha256=
|
|
110
|
+
uncountable/types/api/recipes/get_recipe_links.py,sha256=pcET39vQrzXTjCDDYP-3_0T0vFCJy5EIy8CNUSyzzWw,942
|
|
108
111
|
uncountable/types/api/recipes/get_recipe_names.py,sha256=XC4FGUnRpvyGiQf3-1NbOD5ngBSpcSFHZ2dlIL6g2v8,931
|
|
109
112
|
uncountable/types/api/recipes/get_recipe_output_metadata.py,sha256=z9M3S8QQYi82S3HiDktMYNNdaF4dVNkoLh3tqp7HY1I,1533
|
|
110
113
|
uncountable/types/api/recipes/get_recipes_data.py,sha256=YPDNf2l6AdD0tEv2zqP3AK2bDLp7cGh2qiAdFiRWzeA,6608
|
|
111
114
|
uncountable/types/api/recipes/set_recipe_inputs.py,sha256=XCt4ZN__OqGkvdwh6C9tKbIwiEPeptnfQVAV2p0cGWs,1259
|
|
112
115
|
uncountable/types/api/recipes/set_recipe_outputs.py,sha256=rCs1Gayxon8UY4lTHiErJOLVAVCdMaUsevBX-d1gpo4,1560
|
|
113
|
-
UncountablePythonSDK-0.0.
|
|
114
|
-
UncountablePythonSDK-0.0.
|
|
115
|
-
UncountablePythonSDK-0.0.
|
|
116
|
-
UncountablePythonSDK-0.0.
|
|
116
|
+
UncountablePythonSDK-0.0.7.dist-info/METADATA,sha256=mtk2qN2P0ST2d_sIb6e6XxFOCmOaTFHcUW8_aOKNIZE,1125
|
|
117
|
+
UncountablePythonSDK-0.0.7.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
118
|
+
UncountablePythonSDK-0.0.7.dist-info/top_level.txt,sha256=8ga1DCSWt4Uc_XJ5cR0QrDQuyoeo2uoSzaAJdQT2KBo,36
|
|
119
|
+
UncountablePythonSDK-0.0.7.dist-info/RECORD,,
|
pkgs/type_spec/builder.py
CHANGED
|
@@ -949,52 +949,6 @@ class SpecNamespace:
|
|
|
949
949
|
)
|
|
950
950
|
self.types[name] = spec_type
|
|
951
951
|
|
|
952
|
-
def _validate_external_type_impl(
|
|
953
|
-
self, stype: SpecType, rec_stack: list[SpecType]
|
|
954
|
-
) -> bool:
|
|
955
|
-
if stype in rec_stack[:-1]:
|
|
956
|
-
# recursive type definition ignore this instance
|
|
957
|
-
return True
|
|
958
|
-
|
|
959
|
-
if isinstance(stype, SpecTypeDefn):
|
|
960
|
-
if stype.is_base or stype.is_predefined:
|
|
961
|
-
# predefined and base types are always allowed
|
|
962
|
-
return True
|
|
963
|
-
|
|
964
|
-
if stype.namespace != self:
|
|
965
|
-
# deny access to outside namespaces
|
|
966
|
-
return False
|
|
967
|
-
|
|
968
|
-
if isinstance(stype, SpecTypeDefnExternal):
|
|
969
|
-
# external type definitions not support for external endpoints
|
|
970
|
-
return False
|
|
971
|
-
|
|
972
|
-
# check that referenced types themselves are allowed
|
|
973
|
-
for child_type in stype.get_referenced_types():
|
|
974
|
-
if not self._validate_external_type_wrap(child_type, rec_stack):
|
|
975
|
-
return False
|
|
976
|
-
|
|
977
|
-
return True
|
|
978
|
-
|
|
979
|
-
def _print_external_type_stack(self, rec_stack: list[SpecType]) -> None:
|
|
980
|
-
print(" -> ".join([str(x) for x in rec_stack]))
|
|
981
|
-
|
|
982
|
-
def _validate_external_type_wrap(
|
|
983
|
-
self, stype: SpecType, rec_stack: list[SpecType]
|
|
984
|
-
) -> bool:
|
|
985
|
-
rec_stack.append(stype)
|
|
986
|
-
if not self._validate_external_type_impl(stype, rec_stack):
|
|
987
|
-
return False
|
|
988
|
-
rec_stack.pop()
|
|
989
|
-
return True
|
|
990
|
-
|
|
991
|
-
def _validate_external_type(self, stype: SpecType) -> bool:
|
|
992
|
-
rec_stack: list[SpecType] = []
|
|
993
|
-
if not self._validate_external_type_wrap(stype, rec_stack):
|
|
994
|
-
self._print_external_type_stack(rec_stack)
|
|
995
|
-
return False
|
|
996
|
-
return True
|
|
997
|
-
|
|
998
952
|
def process(self, builder: SpecBuilder, data: RawDict) -> None:
|
|
999
953
|
"""
|
|
1000
954
|
Complete the definition of each type.
|
|
@@ -1023,21 +977,6 @@ class SpecNamespace:
|
|
|
1023
977
|
|
|
1024
978
|
builder.pop_where()
|
|
1025
979
|
|
|
1026
|
-
# validate external endpoints
|
|
1027
|
-
if self.endpoint is not None and self.endpoint.is_external:
|
|
1028
|
-
# external endpoints are only allowed to reference types defined in the same namespace
|
|
1029
|
-
for name, defn in self.types.items():
|
|
1030
|
-
builder.push_where(name)
|
|
1031
|
-
|
|
1032
|
-
if not self._validate_external_type(defn):
|
|
1033
|
-
print(builder.where)
|
|
1034
|
-
print(
|
|
1035
|
-
f"Type '{name}' of external endpoint declaration references internal type definition!"
|
|
1036
|
-
)
|
|
1037
|
-
raise BuilderException()
|
|
1038
|
-
|
|
1039
|
-
builder.pop_where()
|
|
1040
|
-
|
|
1041
980
|
builder.pop_where()
|
|
1042
981
|
|
|
1043
982
|
|
pkgs/type_spec/config.py
CHANGED
|
@@ -74,6 +74,9 @@ class PythonConfig(BaseLanguageConfig):
|
|
|
74
74
|
class OpenAPIConfig(BaseLanguageConfig):
|
|
75
75
|
types_output: str # The folder to put generated openapi api yaml
|
|
76
76
|
description: str # Description of api documentation
|
|
77
|
+
static_url_path: (
|
|
78
|
+
str # the base path where the generated yaml are hosted, e.g. /static/docs
|
|
79
|
+
)
|
|
77
80
|
server_url: str | None = None
|
|
78
81
|
|
|
79
82
|
def __post_init__(self: Self) -> None:
|
pkgs/type_spec/emit_open_api.py
CHANGED
|
@@ -97,9 +97,6 @@ def emit_open_api(builder: builder.SpecBuilder, *, config: OpenAPIConfig) -> Non
|
|
|
97
97
|
)
|
|
98
98
|
|
|
99
99
|
for namespace in sorted(builder.namespaces.values(), key=lambda ns: ns.name):
|
|
100
|
-
if namespace.endpoint is None:
|
|
101
|
-
continue
|
|
102
|
-
|
|
103
100
|
ctx = EmitOpenAPIContext(namespace=namespace)
|
|
104
101
|
|
|
105
102
|
if ctx.namespace.name == "base":
|
|
@@ -111,7 +108,7 @@ def emit_open_api(builder: builder.SpecBuilder, *, config: OpenAPIConfig) -> Non
|
|
|
111
108
|
gctx,
|
|
112
109
|
ctx,
|
|
113
110
|
namespace=namespace,
|
|
114
|
-
|
|
111
|
+
config=config,
|
|
115
112
|
)
|
|
116
113
|
|
|
117
114
|
_rewrite_with_notice(
|
|
@@ -149,10 +146,10 @@ def _emit_namespace(
|
|
|
149
146
|
ctx: EmitOpenAPIContext,
|
|
150
147
|
namespace: builder.SpecNamespace,
|
|
151
148
|
*,
|
|
152
|
-
|
|
149
|
+
config: OpenAPIConfig,
|
|
153
150
|
) -> None:
|
|
154
151
|
for stype in namespace.types.values():
|
|
155
|
-
_emit_type(ctx, stype)
|
|
152
|
+
_emit_type(ctx, stype, config=config)
|
|
156
153
|
|
|
157
154
|
if namespace.endpoint is not None:
|
|
158
155
|
_emit_endpoint(gctx, ctx, namespace, namespace.endpoint)
|
|
@@ -218,12 +215,17 @@ def _emit_namespace(
|
|
|
218
215
|
},
|
|
219
216
|
)
|
|
220
217
|
|
|
221
|
-
path = f"{types_output}/common/{'/'.join(namespace.path)}.yaml"
|
|
218
|
+
path = f"{config.types_output}/common/{'/'.join(namespace.path)}.yaml"
|
|
222
219
|
oa_namespace = {"components": oa_components}
|
|
223
220
|
_rewrite_with_notice(path, yaml.dump(oa_namespace, sort_keys=False))
|
|
224
221
|
|
|
225
222
|
|
|
226
|
-
def _emit_type(
|
|
223
|
+
def _emit_type(
|
|
224
|
+
ctx: EmitOpenAPIContext,
|
|
225
|
+
stype: builder.SpecType,
|
|
226
|
+
*,
|
|
227
|
+
config: OpenAPIConfig,
|
|
228
|
+
) -> None:
|
|
227
229
|
if not isinstance(stype, builder.SpecTypeDefn):
|
|
228
230
|
return
|
|
229
231
|
if stype.is_base or stype.is_predefined:
|
|
@@ -239,7 +241,7 @@ def _emit_type(ctx: EmitOpenAPIContext, stype: builder.SpecType) -> None:
|
|
|
239
241
|
|
|
240
242
|
assert stype.is_exported, "expecting exported names"
|
|
241
243
|
if isinstance(stype, builder.SpecTypeDefnAlias):
|
|
242
|
-
ctx.types[stype.name] = open_api_type(ctx, stype.alias)
|
|
244
|
+
ctx.types[stype.name] = open_api_type(ctx, stype.alias, config=config)
|
|
243
245
|
return
|
|
244
246
|
|
|
245
247
|
if isinstance(stype, builder.SpecTypeDefnStringEnum):
|
|
@@ -259,14 +261,14 @@ def _emit_type(ctx: EmitOpenAPIContext, stype: builder.SpecType) -> None:
|
|
|
259
261
|
return
|
|
260
262
|
elif stype.properties is None:
|
|
261
263
|
# TODO: check if these are actually equivalent
|
|
262
|
-
ctx.types[stype.name] = open_api_type(ctx, stype.base)
|
|
264
|
+
ctx.types[stype.name] = open_api_type(ctx, stype.base, config=config)
|
|
263
265
|
return
|
|
264
266
|
else:
|
|
265
267
|
properties: dict[str, OpenAPIType] = dict()
|
|
266
268
|
property_desc: dict[str, str] = dict()
|
|
267
269
|
|
|
268
270
|
for prop in stype.properties.values():
|
|
269
|
-
ref_type = open_api_type(ctx, prop.spec_type)
|
|
271
|
+
ref_type = open_api_type(ctx, prop.spec_type, config=config)
|
|
270
272
|
prop_name = ts_name(prop.name, prop.name_case or stype.name_case)
|
|
271
273
|
if prop.desc:
|
|
272
274
|
property_desc[prop_name] = prop.desc
|
|
@@ -294,7 +296,10 @@ def _emit_type(ctx: EmitOpenAPIContext, stype: builder.SpecType) -> None:
|
|
|
294
296
|
|
|
295
297
|
if not stype.base.is_base:
|
|
296
298
|
# support inheritance via allOf
|
|
297
|
-
final_type = OpenAPIIntersectionType([
|
|
299
|
+
final_type = OpenAPIIntersectionType([
|
|
300
|
+
open_api_type(ctx, stype.base, config=config),
|
|
301
|
+
final_type,
|
|
302
|
+
])
|
|
298
303
|
|
|
299
304
|
ctx.types[stype.name] = final_type
|
|
300
305
|
|
|
@@ -398,31 +403,37 @@ def _emit_value(stype: builder.SpecType, value: object) -> str:
|
|
|
398
403
|
raise Exception("invalid constant type", value, stype)
|
|
399
404
|
|
|
400
405
|
|
|
401
|
-
def open_api_type(
|
|
406
|
+
def open_api_type(
|
|
407
|
+
ctx: EmitOpenAPIContext,
|
|
408
|
+
stype: builder.SpecType,
|
|
409
|
+
*,
|
|
410
|
+
config: OpenAPIConfig,
|
|
411
|
+
) -> OpenAPIType:
|
|
402
412
|
if isinstance(stype, builder.SpecTypeInstance):
|
|
403
413
|
if stype.defn_type.name == builder.BaseTypeName.s_list:
|
|
404
|
-
return OpenAPIArrayType(
|
|
414
|
+
return OpenAPIArrayType(
|
|
415
|
+
open_api_type(ctx, stype.parameters[0], config=config)
|
|
416
|
+
)
|
|
405
417
|
if stype.defn_type.name == builder.BaseTypeName.s_union:
|
|
406
|
-
return OpenAPIUnionType([
|
|
418
|
+
return OpenAPIUnionType([
|
|
419
|
+
open_api_type(ctx, p, config=config) for p in stype.parameters
|
|
420
|
+
])
|
|
407
421
|
if stype.defn_type.name == builder.BaseTypeName.s_literal:
|
|
408
422
|
# IMPROVE relax the string constraint for literals (for now treat as string)
|
|
409
423
|
parts = []
|
|
410
424
|
for parameter in stype.parameters:
|
|
411
425
|
assert isinstance(parameter, builder.SpecTypeLiteralWrapper)
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
assert isinstance(param_type, OpenAPIEnumType)
|
|
415
|
-
parts.extend(param_type.options)
|
|
426
|
+
parts.append(parameter.value)
|
|
416
427
|
|
|
417
428
|
return OpenAPIEnumType([str(x) for x in parts])
|
|
418
429
|
if stype.defn_type.name == builder.BaseTypeName.s_optional:
|
|
419
|
-
ref_type = open_api_type(ctx, stype.parameters[0])
|
|
430
|
+
ref_type = open_api_type(ctx, stype.parameters[0], config=config)
|
|
420
431
|
ref_type.nullable = True
|
|
421
432
|
return ref_type
|
|
422
433
|
if stype.defn_type.name == builder.BaseTypeName.s_tuple:
|
|
423
434
|
# IMPROVE potentially handle tuples better: for now map tupples to arrays of those types
|
|
424
435
|
return OpenAPIArrayType(
|
|
425
|
-
[open_api_type(ctx, p) for p in stype.parameters],
|
|
436
|
+
[open_api_type(ctx, p, config=config) for p in stype.parameters],
|
|
426
437
|
description="TupleType",
|
|
427
438
|
)
|
|
428
439
|
|
|
@@ -449,5 +460,5 @@ def open_api_type(ctx: EmitOpenAPIContext, stype: builder.SpecType) -> OpenAPITy
|
|
|
449
460
|
ctx.namespaces.add(stype.namespace)
|
|
450
461
|
# external namespace resolution
|
|
451
462
|
return OpenAPIRefType(
|
|
452
|
-
source=f"{resolve_namespace_ref(ctx, stype.namespace)}/{stype.name}"
|
|
463
|
+
source=f"{resolve_namespace_ref(ctx, stype.namespace, config=config)}/{stype.name}"
|
|
453
464
|
)
|
|
@@ -9,6 +9,7 @@ from dataclasses import dataclass, field
|
|
|
9
9
|
from typing import TypeAlias
|
|
10
10
|
|
|
11
11
|
from . import builder
|
|
12
|
+
from .config import OpenAPIConfig
|
|
12
13
|
from .open_api_util import OpenAPIType
|
|
13
14
|
|
|
14
15
|
MODIFY_NOTICE = "# DO NOT MODIFY -- This file is generated by type_spec"
|
|
@@ -74,9 +75,12 @@ class EmitOpenAPIContext:
|
|
|
74
75
|
|
|
75
76
|
|
|
76
77
|
def resolve_namespace_ref(
|
|
77
|
-
ctx: EmitOpenAPIContext,
|
|
78
|
+
ctx: EmitOpenAPIContext,
|
|
79
|
+
namespace: builder.SpecNamespace,
|
|
80
|
+
*,
|
|
81
|
+
config: OpenAPIConfig,
|
|
78
82
|
) -> str:
|
|
79
83
|
# TODO: Handle namespaces not in root directory
|
|
80
84
|
if len(ctx.namespace.path) == 1:
|
|
81
85
|
return f"{namespace.name}.yaml#/components/schema"
|
|
82
|
-
return f"/
|
|
86
|
+
return f"{config.static_url_path}/common/{namespace.name}.yaml#/components/schema"
|
pkgs/type_spec/emit_python.py
CHANGED
|
@@ -372,11 +372,12 @@ def _emit_endpoint_invocation_function(
|
|
|
372
372
|
arguments_type.properties is not None
|
|
373
373
|
and len(arguments_type.properties.values()) > 0
|
|
374
374
|
)
|
|
375
|
-
|
|
375
|
+
assert endpoint.function is not None
|
|
376
|
+
function_name = endpoint.function.split(".")[-1]
|
|
376
377
|
ctx.out.write("\n")
|
|
377
378
|
ctx.out.write(
|
|
378
379
|
f"""
|
|
379
|
-
def {
|
|
380
|
+
def {function_name}(
|
|
380
381
|
self,\n"""
|
|
381
382
|
)
|
|
382
383
|
if has_arguments:
|
|
@@ -5,24 +5,12 @@ $endpoint:
|
|
|
5
5
|
function: main.site.app.external.entity.create_entities.create_entities
|
|
6
6
|
desc: "Creates new Uncountable entities"
|
|
7
7
|
|
|
8
|
-
EntityFieldInitialValue:
|
|
9
|
-
type: Object
|
|
10
|
-
properties:
|
|
11
|
-
field_ref_name:
|
|
12
|
-
type: String
|
|
13
|
-
desc: "A unique identifer string for the field"
|
|
14
|
-
row_index?:
|
|
15
|
-
type: Optional<Integer>
|
|
16
|
-
desc: "The index in the table for the field"
|
|
17
|
-
value:
|
|
18
|
-
type: JsonValue
|
|
19
|
-
desc: "The value for the field"
|
|
20
8
|
|
|
21
9
|
EntityToCreate:
|
|
22
10
|
type: Object
|
|
23
11
|
properties:
|
|
24
12
|
field_values?:
|
|
25
|
-
type: Optional<List<
|
|
13
|
+
type: Optional<List<field_values.FieldRefNameValue>>
|
|
26
14
|
|
|
27
15
|
Arguments:
|
|
28
16
|
type: Object
|
|
@@ -31,25 +19,15 @@ Arguments:
|
|
|
31
19
|
type: Integer
|
|
32
20
|
desc: "Definition id for the entities to create"
|
|
33
21
|
entity_type:
|
|
34
|
-
type: Union<Literal<
|
|
22
|
+
type: Union<Literal<entity.EntityType.lab_request>, Literal<entity.EntityType.approval>, Literal<entity.EntityType.custom_entity>, Literal<entity.EntityType.task>, Literal<entity.EntityType.project>>
|
|
35
23
|
desc: "The type of the entities to create"
|
|
36
24
|
entities_to_create:
|
|
37
25
|
type: List<EntityToCreate>
|
|
38
26
|
desc: "A list of the entities to create"
|
|
39
27
|
|
|
40
|
-
Entity:
|
|
41
|
-
type: Object
|
|
42
|
-
properties:
|
|
43
|
-
id:
|
|
44
|
-
type: Integer
|
|
45
|
-
desc: "A unique identifier for the entity. Used in conjunction with entity type"
|
|
46
|
-
type:
|
|
47
|
-
type: String
|
|
48
|
-
desc: "The type of entity"
|
|
49
|
-
|
|
50
28
|
Data:
|
|
51
29
|
type: Object
|
|
52
30
|
properties:
|
|
53
31
|
entities:
|
|
54
|
-
type: List<Entity>
|
|
32
|
+
type: List<entity.Entity>
|
|
55
33
|
desc: The entities created
|
|
@@ -26,24 +26,14 @@ Arguments:
|
|
|
26
26
|
type: Integer
|
|
27
27
|
desc: "Definition id of the entity to create"
|
|
28
28
|
entity_type:
|
|
29
|
-
type: Union<Literal<
|
|
29
|
+
type: Union<Literal<entity.EntityType.lab_request>, Literal<entity.EntityType.approval>, Literal<entity.EntityType.custom_entity>, Literal<entity.EntityType.task>, Literal<entity.EntityType.project>>
|
|
30
30
|
desc: "The type of the entities requested"
|
|
31
31
|
field_values?:
|
|
32
|
-
type: Optional<List<
|
|
33
|
-
|
|
34
|
-
Entity:
|
|
35
|
-
type: Object
|
|
36
|
-
properties:
|
|
37
|
-
id:
|
|
38
|
-
type: Integer
|
|
39
|
-
desc: "A unique identifier for the entity. Used in conjunction with entity type"
|
|
40
|
-
type:
|
|
41
|
-
type: String
|
|
42
|
-
desc: "The type of entity"
|
|
32
|
+
type: Optional<List<field_values.FieldRefNameValue>>
|
|
43
33
|
|
|
44
34
|
Data:
|
|
45
35
|
type: Object
|
|
46
36
|
properties:
|
|
47
37
|
entity:
|
|
48
|
-
type: Entity
|
|
38
|
+
type: entity.Entity
|
|
49
39
|
desc: The entity created
|
|
@@ -5,24 +5,6 @@ $endpoint:
|
|
|
5
5
|
function: main.site.app.external.recipes.get_recipe_links.get_recipe_links
|
|
6
6
|
desc: "Gets the links for the passed recipes"
|
|
7
7
|
|
|
8
|
-
RecipeLinkType:
|
|
9
|
-
type: StringEnum
|
|
10
|
-
values:
|
|
11
|
-
user_link:
|
|
12
|
-
label: Manual Link
|
|
13
|
-
child:
|
|
14
|
-
label: "Test Sample"
|
|
15
|
-
self:
|
|
16
|
-
label: "Self Link"
|
|
17
|
-
recipe_as_output:
|
|
18
|
-
label: "Analytical Sample"
|
|
19
|
-
control:
|
|
20
|
-
label: "Control Link"
|
|
21
|
-
intermediate_recipe:
|
|
22
|
-
label: "Used as Component Link"
|
|
23
|
-
previous_experiment:
|
|
24
|
-
label: "Previous Sample"
|
|
25
|
-
|
|
26
8
|
Arguments:
|
|
27
9
|
type: Object
|
|
28
10
|
properties:
|
|
@@ -34,28 +16,11 @@ Arguments:
|
|
|
34
16
|
desc: "How many layers deep to look for links"
|
|
35
17
|
default: 1
|
|
36
18
|
link_types:
|
|
37
|
-
type: Optional<List<RecipeLinkType>>
|
|
19
|
+
type: Optional<List<recipe_links.RecipeLinkType>>
|
|
38
20
|
desc: "Optional filter to only desired link types"
|
|
39
21
|
|
|
40
|
-
RecipeLink:
|
|
41
|
-
type: Object
|
|
42
|
-
hashable: true
|
|
43
|
-
properties:
|
|
44
|
-
recipe_id_from:
|
|
45
|
-
type: Integer
|
|
46
|
-
desc: "Identifier for the recipe"
|
|
47
|
-
recipe_id_to:
|
|
48
|
-
type: Integer
|
|
49
|
-
desc: "Identifier for the calculation"
|
|
50
|
-
link_type:
|
|
51
|
-
type: String
|
|
52
|
-
desc: "The type of the link, e.g. child"
|
|
53
|
-
name:
|
|
54
|
-
type: String
|
|
55
|
-
desc: "The name used for the link. Max 20"
|
|
56
|
-
|
|
57
22
|
Data:
|
|
58
23
|
type: Object
|
|
59
24
|
properties:
|
|
60
25
|
recipe_links:
|
|
61
|
-
type: List<RecipeLink>
|
|
26
|
+
type: List<recipe_links.RecipeLink>
|
uncountable/types/__init__.py
CHANGED
|
@@ -8,7 +8,9 @@ from .api.entity import create_entities as create_entities_t
|
|
|
8
8
|
from .api.entity import create_entity as create_entity_t
|
|
9
9
|
from .api.inputs import create_inputs as create_inputs_t
|
|
10
10
|
from .api.recipes import create_recipes as create_recipes_t
|
|
11
|
+
from . import entity as entity_t
|
|
11
12
|
from .api.batch import execute_batch as execute_batch_t
|
|
13
|
+
from . import field_values as field_values_t
|
|
12
14
|
from .api.recipes import get_curve as get_curve_t
|
|
13
15
|
from .api.entity import get_entities_data as get_entities_data_t
|
|
14
16
|
from .api.inputs import get_input_data as get_input_data_t
|
|
@@ -26,6 +28,7 @@ from .api.recipes import get_recipe_names as get_recipe_names_t
|
|
|
26
28
|
from .api.recipes import get_recipe_output_metadata as get_recipe_output_metadata_t
|
|
27
29
|
from .api.recipes import get_recipes_data as get_recipes_data_t
|
|
28
30
|
from .api.entity import list_entities as list_entities_t
|
|
31
|
+
from . import recipe_links as recipe_links_t
|
|
29
32
|
from .api.entity import resolve_entity_ids as resolve_entity_ids_t
|
|
30
33
|
from .api.outputs import resolve_output_conditions as resolve_output_conditions_t
|
|
31
34
|
from .api.inputs import set_input_attribute_values as set_input_attribute_values_t
|
|
@@ -40,7 +43,9 @@ __all__: list[str] = [
|
|
|
40
43
|
"create_entity_t",
|
|
41
44
|
"create_inputs_t",
|
|
42
45
|
"create_recipes_t",
|
|
46
|
+
"entity_t",
|
|
43
47
|
"execute_batch_t",
|
|
48
|
+
"field_values_t",
|
|
44
49
|
"get_curve_t",
|
|
45
50
|
"get_entities_data_t",
|
|
46
51
|
"get_input_data_t",
|
|
@@ -58,6 +63,7 @@ __all__: list[str] = [
|
|
|
58
63
|
"get_recipe_output_metadata_t",
|
|
59
64
|
"get_recipes_data_t",
|
|
60
65
|
"list_entities_t",
|
|
66
|
+
"recipe_links_t",
|
|
61
67
|
"resolve_entity_ids_t",
|
|
62
68
|
"resolve_output_conditions_t",
|
|
63
69
|
"set_input_attribute_values_t",
|
|
@@ -8,16 +8,14 @@ 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
|
|
12
|
-
from ... import
|
|
11
|
+
from ... import entity as entity_t
|
|
12
|
+
from ... import field_values as field_values_t
|
|
13
13
|
|
|
14
14
|
__all__: list[str] = [
|
|
15
15
|
"Arguments",
|
|
16
16
|
"Data",
|
|
17
17
|
"ENDPOINT_METHOD",
|
|
18
18
|
"ENDPOINT_PATH",
|
|
19
|
-
"Entity",
|
|
20
|
-
"EntityFieldInitialValue",
|
|
21
19
|
"EntityToCreate",
|
|
22
20
|
]
|
|
23
21
|
|
|
@@ -25,40 +23,22 @@ ENDPOINT_METHOD = "POST"
|
|
|
25
23
|
ENDPOINT_PATH = "api/external/entity/external_create_entities"
|
|
26
24
|
|
|
27
25
|
|
|
28
|
-
# DO NOT MODIFY -- This file is generated by type_spec
|
|
29
|
-
@serial_class(
|
|
30
|
-
unconverted_values={"value"},
|
|
31
|
-
)
|
|
32
|
-
@dataclass(kw_only=True)
|
|
33
|
-
class EntityFieldInitialValue:
|
|
34
|
-
field_ref_name: str
|
|
35
|
-
value: base_t.JsonValue
|
|
36
|
-
row_index: typing.Optional[typing.Optional[int]] = None
|
|
37
|
-
|
|
38
|
-
|
|
39
26
|
# DO NOT MODIFY -- This file is generated by type_spec
|
|
40
27
|
@dataclass(kw_only=True)
|
|
41
28
|
class EntityToCreate:
|
|
42
|
-
field_values: typing.Optional[typing.Optional[list[
|
|
29
|
+
field_values: typing.Optional[typing.Optional[list[field_values_t.FieldRefNameValue]]] = None
|
|
43
30
|
|
|
44
31
|
|
|
45
32
|
# DO NOT MODIFY -- This file is generated by type_spec
|
|
46
33
|
@dataclass(kw_only=True)
|
|
47
34
|
class Arguments:
|
|
48
35
|
definition_id: int
|
|
49
|
-
entity_type: typing.Union[typing.Literal[
|
|
36
|
+
entity_type: typing.Union[typing.Literal[entity_t.EntityType.LAB_REQUEST], typing.Literal[entity_t.EntityType.APPROVAL], typing.Literal[entity_t.EntityType.CUSTOM_ENTITY], typing.Literal[entity_t.EntityType.TASK], typing.Literal[entity_t.EntityType.PROJECT]]
|
|
50
37
|
entities_to_create: list[EntityToCreate]
|
|
51
38
|
|
|
52
39
|
|
|
53
|
-
# DO NOT MODIFY -- This file is generated by type_spec
|
|
54
|
-
@dataclass(kw_only=True)
|
|
55
|
-
class Entity:
|
|
56
|
-
id: int
|
|
57
|
-
type: str
|
|
58
|
-
|
|
59
|
-
|
|
60
40
|
# DO NOT MODIFY -- This file is generated by type_spec
|
|
61
41
|
@dataclass(kw_only=True)
|
|
62
42
|
class Data:
|
|
63
|
-
entities: list[Entity]
|
|
43
|
+
entities: list[entity_t.Entity]
|
|
64
44
|
# DO NOT MODIFY -- This file is generated by type_spec
|
|
@@ -10,13 +10,14 @@ from decimal import Decimal # noqa: F401
|
|
|
10
10
|
from dataclasses import dataclass
|
|
11
11
|
from pkgs.serialization import serial_class
|
|
12
12
|
from ... import base as base_t
|
|
13
|
+
from ... import entity as entity_t
|
|
14
|
+
from ... import field_values as field_values_t
|
|
13
15
|
|
|
14
16
|
__all__: list[str] = [
|
|
15
17
|
"Arguments",
|
|
16
18
|
"Data",
|
|
17
19
|
"ENDPOINT_METHOD",
|
|
18
20
|
"ENDPOINT_PATH",
|
|
19
|
-
"Entity",
|
|
20
21
|
"EntityFieldInitialValue",
|
|
21
22
|
]
|
|
22
23
|
|
|
@@ -39,19 +40,12 @@ class EntityFieldInitialValue:
|
|
|
39
40
|
@dataclass(kw_only=True)
|
|
40
41
|
class Arguments:
|
|
41
42
|
definition_id: int
|
|
42
|
-
entity_type: typing.Union[typing.Literal[
|
|
43
|
-
field_values: typing.Optional[typing.Optional[list[
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
# DO NOT MODIFY -- This file is generated by type_spec
|
|
47
|
-
@dataclass(kw_only=True)
|
|
48
|
-
class Entity:
|
|
49
|
-
id: int
|
|
50
|
-
type: str
|
|
43
|
+
entity_type: typing.Union[typing.Literal[entity_t.EntityType.LAB_REQUEST], typing.Literal[entity_t.EntityType.APPROVAL], typing.Literal[entity_t.EntityType.CUSTOM_ENTITY], typing.Literal[entity_t.EntityType.TASK], typing.Literal[entity_t.EntityType.PROJECT]]
|
|
44
|
+
field_values: typing.Optional[typing.Optional[list[field_values_t.FieldRefNameValue]]] = None
|
|
51
45
|
|
|
52
46
|
|
|
53
47
|
# DO NOT MODIFY -- This file is generated by type_spec
|
|
54
48
|
@dataclass(kw_only=True)
|
|
55
49
|
class Data:
|
|
56
|
-
entity: Entity
|
|
50
|
+
entity: entity_t.Entity
|
|
57
51
|
# DO NOT MODIFY -- This file is generated by type_spec
|