UncountablePythonSDK 0.0.21__py3-none-any.whl → 0.0.23__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.21.dist-info → UncountablePythonSDK-0.0.23.dist-info}/METADATA +1 -1
- {UncountablePythonSDK-0.0.21.dist-info → UncountablePythonSDK-0.0.23.dist-info}/RECORD +27 -25
- examples/async_batch.py +36 -0
- pkgs/type_spec/builder.py +113 -8
- pkgs/type_spec/emit_io_ts.py +4 -1
- pkgs/type_spec/emit_open_api.py +192 -18
- pkgs/type_spec/emit_open_api_util.py +17 -0
- pkgs/type_spec/emit_python.py +7 -1
- pkgs/type_spec/emit_typescript.py +3 -0
- pkgs/type_spec/load_types.py +48 -5
- pkgs/type_spec/open_api_util.py +13 -33
- type_spec/external/api/entity/create_entities.yaml +1 -0
- type_spec/external/api/entity/create_entity.yaml +1 -0
- type_spec/external/api/recipes/edit_recipe_inputs.yaml +1 -4
- uncountable/core/__init__.py +2 -1
- uncountable/core/async_batch.py +22 -0
- uncountable/core/client.py +78 -6
- uncountable/types/api/entity/create_entities.py +1 -1
- uncountable/types/api/entity/create_entity.py +1 -1
- uncountable/types/api/recipes/edit_recipe_inputs.py +2 -3
- uncountable/types/async_batch.py +1 -0
- uncountable/types/async_batch_processor.py +7 -7
- uncountable/types/client_base.py +27 -2
- uncountable/types/identifier.py +3 -3
- uncountable/types/recipe_workflow_steps.py +1 -1
- {UncountablePythonSDK-0.0.21.dist-info → UncountablePythonSDK-0.0.23.dist-info}/WHEEL +0 -0
- {UncountablePythonSDK-0.0.21.dist-info → UncountablePythonSDK-0.0.23.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.23
|
|
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
|
|
@@ -14,6 +14,7 @@ docs/static/favicons/favicon-32x32.png,sha256=U4UU652zGnSeU3P9kUqxPeEnVf6zhtdNdN
|
|
|
14
14
|
docs/static/favicons/manifest.json,sha256=6q_3nZkcg_x0xut4eE-xpdeMY1TydwiZIcbXlLAq9X8,437
|
|
15
15
|
docs/static/favicons/mstile-150x150.png,sha256=eAK4QdEofhdLtfmjuPTpnX3MJqYnvGXsHYUjlcQekyY,1035
|
|
16
16
|
docs/static/favicons/safari-pinned-tab.svg,sha256=S84fRnz0ZxLnQrKtmmFZytiRyu1xLtMR_RVy5jmwU7k,1926
|
|
17
|
+
examples/async_batch.py,sha256=wpf_3P547375vTIO4pKv5vw6WCkUnzqvw_S3idfhjvM,1122
|
|
17
18
|
examples/create_entity.py,sha256=54AmZt83EpypxGcYZSIMmWlGz2oAgHFOsKuLSZOcHsI,625
|
|
18
19
|
examples/upload_files.py,sha256=ZsMChgOioraVHv207YREpivAOf4dq3IxGIBoROoDX_4,482
|
|
19
20
|
examples/recipe-import/importer.py,sha256=baD71xuNibxDTe3bGHsMEIZEf9Xtb-IumBNpCEV0RZU,1134
|
|
@@ -34,16 +35,16 @@ pkgs/strenum_compat/__init__.py,sha256=wXRFeNvBm8RU6dy1PFJ5sRLgUIEeH_DVR95Sv5qpG
|
|
|
34
35
|
pkgs/strenum_compat/strenum_compat.py,sha256=uOUAgpYTjHs1MX8dG81jRlyTkt3KNbkV_25zp7xTX2s,36
|
|
35
36
|
pkgs/type_spec/__init__.py,sha256=h5DmJTca4QVV10sZR1x0-MlkZfuGYDfapR3zHvXfzto,19
|
|
36
37
|
pkgs/type_spec/__main__.py,sha256=5bJaX9Y_-FavP0qwzhk-z-V97UY7uaezJTa1zhO_HHQ,1048
|
|
37
|
-
pkgs/type_spec/builder.py,sha256=
|
|
38
|
+
pkgs/type_spec/builder.py,sha256=9fEcZkasqovH8W4PtQvXtPu4psS_a-HAyu6Wsfk5L8w,43041
|
|
38
39
|
pkgs/type_spec/config.py,sha256=INfEiDcUsZFUKasHprsE6i33siPB0RnfmTKOsWcGnQ8,5043
|
|
39
|
-
pkgs/type_spec/emit_io_ts.py,sha256=
|
|
40
|
-
pkgs/type_spec/emit_open_api.py,sha256=
|
|
41
|
-
pkgs/type_spec/emit_open_api_util.py,sha256=
|
|
42
|
-
pkgs/type_spec/emit_python.py,sha256=
|
|
43
|
-
pkgs/type_spec/emit_typescript.py,sha256=
|
|
40
|
+
pkgs/type_spec/emit_io_ts.py,sha256=Ghd8XYqyNYldHQDepwa9GLfHXcoi48ztBw84K28ETic,5707
|
|
41
|
+
pkgs/type_spec/emit_open_api.py,sha256=RJzzOZ7Ti1PNTPn42ZGW7OA6L9KRQhKOTw4elXzJKpE,23524
|
|
42
|
+
pkgs/type_spec/emit_open_api_util.py,sha256=F6qouGVm2-WGYkoubbBtRu00V4e30bWJ0fDBhigBEfg,2248
|
|
43
|
+
pkgs/type_spec/emit_python.py,sha256=aGPnp86DZN0N7c5eiBHVAT_smDf1uCLmRldDhxmWx9g,42673
|
|
44
|
+
pkgs/type_spec/emit_typescript.py,sha256=4hpCJwiDf-v8LJaNFVfFtf8zvtG73YNPFwwa_5NuffI,17729
|
|
44
45
|
pkgs/type_spec/emit_typescript_util.py,sha256=93FzJnpYse4PKFzgdw4DGV4zFTi5tF4WR-CIi7cW498,873
|
|
45
|
-
pkgs/type_spec/load_types.py,sha256=
|
|
46
|
-
pkgs/type_spec/open_api_util.py,sha256=
|
|
46
|
+
pkgs/type_spec/load_types.py,sha256=xEHwdB_miR3vNs161Oy1luafE0VC-yk9-utAyCJmbEo,3629
|
|
47
|
+
pkgs/type_spec/open_api_util.py,sha256=TFbK2bkYT6S4qPQGO3_G2mfVgtNB26d31kwaHQ9y99E,6730
|
|
47
48
|
pkgs/type_spec/test.py,sha256=4ueujBq-pEgnX3Z69HyPmD-bullFXmpixcpVzfOkhP4,489
|
|
48
49
|
pkgs/type_spec/util.py,sha256=6m6MPfY-SwjyZf2FWQKclswWB5o7gcdd-3tdpViPYOQ,4844
|
|
49
50
|
pkgs/type_spec/actions_registry/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -61,8 +62,8 @@ pkgs/type_spec/value_spec/types.py,sha256=a2zxbbCRWepY1l8OtjeCDKgBKFPFHVgV99oP6p
|
|
|
61
62
|
type_spec/external/api/batch/execute_batch.yaml,sha256=gpdSev3sLEC_cMVSZdj-9bc_XDFDqdPdOII9Ojme2N8,1170
|
|
62
63
|
type_spec/external/api/batch/execute_batch_load_async.yaml,sha256=gcn51NWLiSvlytz8k3_pDOVJLCGfdivKJPG4I9Q8CZc,435
|
|
63
64
|
type_spec/external/api/chemical/convert_chemical_formats.yaml,sha256=EidTxMCRs-ko5yMFDptJPyAEWYZVruP41OG3cwyBLQQ,1069
|
|
64
|
-
type_spec/external/api/entity/create_entities.yaml,sha256=
|
|
65
|
-
type_spec/external/api/entity/create_entity.yaml,sha256=
|
|
65
|
+
type_spec/external/api/entity/create_entities.yaml,sha256=RKjmb_iY4dVHf3aQUCU-OrlbTLLsCkULQ9uEfa8BMFY,1506
|
|
66
|
+
type_spec/external/api/entity/create_entity.yaml,sha256=Orz-3RZsNy5cWXlA3BKVQDYGnGGXlCXOtsOxDSm_nRY,1701
|
|
66
67
|
type_spec/external/api/entity/get_entities_data.yaml,sha256=3XujG7bOpuBQlfFrYtG3L4fBk7LsmdSekmP9iU0zjF0,796
|
|
67
68
|
type_spec/external/api/entity/list_entities.yaml,sha256=H2YVv6il-XVKd_7IipZqauTDvWCrvHok7z47bDH2sI4,1798
|
|
68
69
|
type_spec/external/api/entity/resolve_entity_ids.yaml,sha256=Zf3OhAohwLJO7wWj0e-sK5lhIsXlD8A5Bu3OGjY4-tA,732
|
|
@@ -89,7 +90,7 @@ type_spec/external/api/recipes/associate_recipe_as_lot.yaml,sha256=8wzeJg5njt4qG
|
|
|
89
90
|
type_spec/external/api/recipes/create_recipe.yaml,sha256=mGLyKJI3pN_7nU4rcSqCO3WjuKhO_odZ2pewVgYcMUU,1322
|
|
90
91
|
type_spec/external/api/recipes/create_recipes.yaml,sha256=eXMlXRpB5TFt1mUTECBa4aAIG3KrxYT2mJ5vxmZ9Q3A,1503
|
|
91
92
|
type_spec/external/api/recipes/disassociate_recipe_as_input.yaml,sha256=qTKQCNBNwLnbr22DQVLA6b80BdBhwnDbX1c4KoCKUm8,477
|
|
92
|
-
type_spec/external/api/recipes/edit_recipe_inputs.yaml,sha256=
|
|
93
|
+
type_spec/external/api/recipes/edit_recipe_inputs.yaml,sha256=ljewBw77ucvl_m_KWmSJp-nVQGvVG6cb7xVOgPIlueU,2573
|
|
93
94
|
type_spec/external/api/recipes/get_curve.yaml,sha256=zQpPwOYqojY-YwmTjbqoGtUxpYm3vne2sYpglWbPnpw,779
|
|
94
95
|
type_spec/external/api/recipes/get_recipe_calculations.yaml,sha256=ZE7PzfWrjS7TiO4q7iyCwEj5In8GwO6fFIYGqUlTEXo,1240
|
|
95
96
|
type_spec/external/api/recipes/get_recipe_links.yaml,sha256=Vwm0OVWl3VvDaI7chY_oZQqD8xZ1u09iFWKkZKn1ITo,766
|
|
@@ -103,8 +104,9 @@ type_spec/external/api/recipes/set_recipe_tags.yaml,sha256=IrdkbryxZjNy8n4aMNLRT
|
|
|
103
104
|
type_spec/external/api/triggers/run_trigger.yaml,sha256=c8xDV3bQRjcRRDG4Y7kdQmMMu1fj3ae5eUi-Sdbsi54,405
|
|
104
105
|
uncountable/__init__.py,sha256=281cC2hs8pbrD0jVKMol-tbWSh7Zcsc8oRT42dKteyE,102
|
|
105
106
|
uncountable/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
106
|
-
uncountable/core/__init__.py,sha256=
|
|
107
|
-
uncountable/core/
|
|
107
|
+
uncountable/core/__init__.py,sha256=7xUnbSWJzS31sWg0jCe5nIksn5s0PVdwUrUmDttHfCY,258
|
|
108
|
+
uncountable/core/async_batch.py,sha256=0cRmCr6Z9sNxZyfY9Dl8wlCA4anISVZuHGgBegHhUbc,749
|
|
109
|
+
uncountable/core/client.py,sha256=7bLuACxMJZsckSfL2j-p-XThYdvDAUAwm5nND9s-v1o,6946
|
|
108
110
|
uncountable/core/file_upload.py,sha256=zTpAFSd7_-TmEVWxOn1rDznyWE6_AdZyuDQC3LP34iI,2667
|
|
109
111
|
uncountable/core/types.py,sha256=gQtCw1-WSRak_ypFlGI1Ea9iZBP9zDeFq6XQtiXBlZA,459
|
|
110
112
|
uncountable/integration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -119,19 +121,19 @@ uncountable/integration/db/connect.py,sha256=iI9e8a2hfbFP-dvH0MGLsrG-RpM0dHKCL-o
|
|
|
119
121
|
uncountable/integration/executors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
120
122
|
uncountable/integration/executors/script_executor.py,sha256=6oMPAFe0PUdqt76e8jMi4vXszGVsVHLULob7Qbl3o38,816
|
|
121
123
|
uncountable/types/__init__.py,sha256=fTNNsvFFkjp4acdBA8eS00OZVnDo_Zn7aRwPs8SFnrs,6024
|
|
122
|
-
uncountable/types/async_batch.py,sha256=
|
|
123
|
-
uncountable/types/async_batch_processor.py,sha256=
|
|
124
|
+
uncountable/types/async_batch.py,sha256=FtIoDCeyt9rF5hknQs6Sw-vjiYBMJbe1re0-4bk_6VY,1578
|
|
125
|
+
uncountable/types/async_batch_processor.py,sha256=YksvTyJaZ3rqpZx4UXofUf7XU1Br4aNBNPZXB3LLtkA,5940
|
|
124
126
|
uncountable/types/base.py,sha256=w3BRf8SAvYPlKrcJtJcQ_WhCU3A9zy0VuRTRWRFKVUA,2709
|
|
125
127
|
uncountable/types/calculations.py,sha256=16J-KKMp-I8ZQUkYNmKCHfAn6DGb99cFinALcDIdGHY,562
|
|
126
128
|
uncountable/types/chemical_structure.py,sha256=zQKl53DGtQQONIUHFXuwjWLQaG7FPZY7x6SBSOzkGV0,758
|
|
127
|
-
uncountable/types/client_base.py,sha256=
|
|
129
|
+
uncountable/types/client_base.py,sha256=nsV7NWN5UoqjCfFSw9XLXT_rbpfZeWRrOLxqeZ20Sjw,47114
|
|
128
130
|
uncountable/types/curves.py,sha256=qYyRntMmFNonEwTrGhquMLbgMqjyP1moQflNTP0FMec,1308
|
|
129
131
|
uncountable/types/entity.py,sha256=NjMZrqBwQ7sZe_oUuJqy9IEG7dWZmFMkQQXJ0_odcnA,11637
|
|
130
132
|
uncountable/types/experiment_groups.py,sha256=ZBEk06F4n98Jz3oEA09WaDmw5rqPs7iVAm_Ysr4gc_o,599
|
|
131
133
|
uncountable/types/field_values.py,sha256=2unBAeBqQPqLQKaL6nGpnDDksZ-5MZepgEF3sgy6oOk,1670
|
|
132
134
|
uncountable/types/fields.py,sha256=eGtZ6axTYGFxLmPAyri2LwlcR4SZ2sX2c6QDX0ybKz0,570
|
|
133
135
|
uncountable/types/id_source.py,sha256=Y3suURq3L1SahZ2oHPD986SU0l3Ik-ZzH38aQKgc1Fg,1341
|
|
134
|
-
uncountable/types/identifier.py,sha256=
|
|
136
|
+
uncountable/types/identifier.py,sha256=94-O3H_qNrA48tf3srwPwdu8HURkLl7_-88kUnwElZg,1455
|
|
135
137
|
uncountable/types/input_attributes.py,sha256=u-JABoZ-Ij1Ynq5g6MxOgRdQeYbM7OnGP2q_N7KuVdw,826
|
|
136
138
|
uncountable/types/inputs.py,sha256=q7fNGaSKIk3R6uXCEhSQpiHvXu82YcK3oZHDI7bxE88,1597
|
|
137
139
|
uncountable/types/outputs.py,sha256=hSUlu41sisYKIZpPrj1G1DRfKm6hsKNcd1eNKFYb-4w,671
|
|
@@ -144,7 +146,7 @@ uncountable/types/recipe_links.py,sha256=RldSV7SdeBYa0bx02DzMg4jfPdgrlMRE40T16Fd
|
|
|
144
146
|
uncountable/types/recipe_metadata.py,sha256=cebGg_lJzqZzGnKnDgmuQFrw4Xhoz6HEiGM6G0az120,1437
|
|
145
147
|
uncountable/types/recipe_output_metadata.py,sha256=XJA8R1r4NTzyR_DhMkmH4ZtYD-vqpvBMji9Be8OcFmo,613
|
|
146
148
|
uncountable/types/recipe_tags.py,sha256=lYpksHAxXCcIjZKR7JoZOTH2cBSovwxZaHwjZy_yqiQ,581
|
|
147
|
-
uncountable/types/recipe_workflow_steps.py,sha256=
|
|
149
|
+
uncountable/types/recipe_workflow_steps.py,sha256=LmyFwWWwJv30vuaQ4qtd0hzDdeJaIxHQZqwRb1Wi_6A,2626
|
|
148
150
|
uncountable/types/response.py,sha256=ZI0CG7ZxBM2k5_W-6mNMU3UlB0p1i-0nrwOvsMaS-vU,620
|
|
149
151
|
uncountable/types/units.py,sha256=_kZ7KkXIbRiY2fOdkTsbJBpWRah5TCC2WWiG05e-1DA,565
|
|
150
152
|
uncountable/types/users.py,sha256=SUjNHBDcImKnnE7IN096Wfr1fmjNjCkQ7yQgKUPffz8,588
|
|
@@ -156,8 +158,8 @@ uncountable/types/api/batch/execute_batch_load_async.py,sha256=dcdGFibO8fUDpC__X
|
|
|
156
158
|
uncountable/types/api/chemical/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr8APdZYUniAor8,55
|
|
157
159
|
uncountable/types/api/chemical/convert_chemical_formats.py,sha256=COGzkfpTL_Ermg2cbasoVKGAxDAtJaTFay18IZtrWCA,1305
|
|
158
160
|
uncountable/types/api/entity/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr8APdZYUniAor8,55
|
|
159
|
-
uncountable/types/api/entity/create_entities.py,sha256=
|
|
160
|
-
uncountable/types/api/entity/create_entity.py,sha256=
|
|
161
|
+
uncountable/types/api/entity/create_entities.py,sha256=vzo5hS1qcmjQdfyCMarSu8MRcRGSiholOVSCfjXlA1k,1703
|
|
162
|
+
uncountable/types/api/entity/create_entity.py,sha256=ausozCQ3qPM9YUQ87bOTCKOm-zkhn4CSLJr9jLc9n2U,1873
|
|
161
163
|
uncountable/types/api/entity/get_entities_data.py,sha256=XjrJGZucIn1TYUlDLRnRA0JTQw-vXHIAT-m0H9hk37A,1170
|
|
162
164
|
uncountable/types/api/entity/list_entities.py,sha256=_bIIZJj3N0E6YiHgqzfCOKxD1fQW6biWJQMp5wIVbBw,1514
|
|
163
165
|
uncountable/types/api/entity/resolve_entity_ids.py,sha256=AidGpPmI9ATDv0E7vd9LDOl3n3beGxUlRojh5uZrkl4,1086
|
|
@@ -193,7 +195,7 @@ uncountable/types/api/recipes/associate_recipe_as_lot.py,sha256=bTYjbnY3B7GKz4MV
|
|
|
193
195
|
uncountable/types/api/recipes/create_recipe.py,sha256=Ni00efkcPkQ3WTIgDHzkfu1qoc52ReV9VT0wwwPOT4g,1364
|
|
194
196
|
uncountable/types/api/recipes/create_recipes.py,sha256=qwIYa8hfcjY7_VOFt9lxmVtJ-HOJqQN3GDNSbZsRCZU,1544
|
|
195
197
|
uncountable/types/api/recipes/disassociate_recipe_as_input.py,sha256=L25fpiK1Y5PByPVVgsZy9t4podz3xSSLIwKHj8CUrSg,913
|
|
196
|
-
uncountable/types/api/recipes/edit_recipe_inputs.py,sha256=
|
|
198
|
+
uncountable/types/api/recipes/edit_recipe_inputs.py,sha256=pTw606AgLhb-oJjfj1WPyEcJ4B0tgZsvEKeqP5VZ1gY,3281
|
|
197
199
|
uncountable/types/api/recipes/get_curve.py,sha256=UIWfpqtU5sQokaxwYfQFNFl6HMyzWEF_Sjd8UMz0U88,939
|
|
198
200
|
uncountable/types/api/recipes/get_recipe_calculations.py,sha256=eQmkdZzCEuq8S2f_kf_7GPvDLX1pTnY1CRmkK0SkMCI,1472
|
|
199
201
|
uncountable/types/api/recipes/get_recipe_links.py,sha256=hk5dfQjv7yU2r-S9b8vwWEJLPHqU0-M6SFiTLMR3fVk,985
|
|
@@ -206,7 +208,7 @@ uncountable/types/api/recipes/set_recipe_outputs.py,sha256=QYq39TNchQ80ET1C77OE9
|
|
|
206
208
|
uncountable/types/api/recipes/set_recipe_tags.py,sha256=U710hgq9-t6QZGRB-ZGHskpt4iXwYEjIRb67eh3P518,2453
|
|
207
209
|
uncountable/types/api/triggers/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr8APdZYUniAor8,55
|
|
208
210
|
uncountable/types/api/triggers/run_trigger.py,sha256=9m9M8-nlGB_sAU2Qm2lWugp4h4Osqj6QpjNfU8osd1U,901
|
|
209
|
-
UncountablePythonSDK-0.0.
|
|
210
|
-
UncountablePythonSDK-0.0.
|
|
211
|
-
UncountablePythonSDK-0.0.
|
|
212
|
-
UncountablePythonSDK-0.0.
|
|
211
|
+
UncountablePythonSDK-0.0.23.dist-info/METADATA,sha256=W6CHPkwSSSiPK9zlnXFS8WjX7sCL8o2-76dd4m2CJkY,1613
|
|
212
|
+
UncountablePythonSDK-0.0.23.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
213
|
+
UncountablePythonSDK-0.0.23.dist-info/top_level.txt,sha256=HaMiBnH1wA7SG9-RVHIJPBH3l8X5gee2jUf-77Nz-Dk,41
|
|
214
|
+
UncountablePythonSDK-0.0.23.dist-info/RECORD,,
|
examples/async_batch.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from decimal import Decimal
|
|
2
|
+
from uncountable.core import AuthDetailsApiKey, Client
|
|
3
|
+
from uncountable.core import AsyncBatchProcessor
|
|
4
|
+
from uncountable.types import (
|
|
5
|
+
recipe_metadata,
|
|
6
|
+
)
|
|
7
|
+
from uncountable.types.identifier import IdentifierKeyBatchReference
|
|
8
|
+
from uncountable.types.recipe_identifiers import (
|
|
9
|
+
RecipeIdentifierEditableName,
|
|
10
|
+
RecipeIdentifiers,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
client = Client(
|
|
15
|
+
base_url="https://app.uncountable.com",
|
|
16
|
+
auth_details=AuthDetailsApiKey(
|
|
17
|
+
api_id="X",
|
|
18
|
+
api_secret_key="X",
|
|
19
|
+
),
|
|
20
|
+
)
|
|
21
|
+
batch_loader = AsyncBatchProcessor(client=client)
|
|
22
|
+
recipe_identifiers: RecipeIdentifiers = []
|
|
23
|
+
recipe_identifiers.append(
|
|
24
|
+
RecipeIdentifierEditableName(editable_name="My recipe from API")
|
|
25
|
+
)
|
|
26
|
+
req = batch_loader.create_recipe(
|
|
27
|
+
material_family_id=1, workflow_id=1, identifiers=recipe_identifiers
|
|
28
|
+
)
|
|
29
|
+
created_recipe_reference = req.batch_reference
|
|
30
|
+
batch_loader.set_recipe_metadata(
|
|
31
|
+
recipe_key=IdentifierKeyBatchReference(reference=created_recipe_reference),
|
|
32
|
+
recipe_metadata=[
|
|
33
|
+
recipe_metadata.MetadataValue(metadata_id=7, value_numeric=Decimal(38))
|
|
34
|
+
],
|
|
35
|
+
)
|
|
36
|
+
job_id = batch_loader.send()
|
pkgs/type_spec/builder.py
CHANGED
|
@@ -10,7 +10,7 @@ import re
|
|
|
10
10
|
from collections import defaultdict
|
|
11
11
|
from dataclasses import MISSING, dataclass
|
|
12
12
|
from enum import Enum, StrEnum, auto
|
|
13
|
-
from typing import Any, Optional
|
|
13
|
+
from typing import Any, Optional, Self
|
|
14
14
|
|
|
15
15
|
from . import util
|
|
16
16
|
from .util import parse_type_str, unused
|
|
@@ -86,6 +86,7 @@ class BaseTypeName(StrEnum):
|
|
|
86
86
|
s_optional = "Optional"
|
|
87
87
|
s_string = "String"
|
|
88
88
|
s_tuple = "Tuple"
|
|
89
|
+
s_readonly_array = "ReadonlyArray"
|
|
89
90
|
s_union = "Union"
|
|
90
91
|
|
|
91
92
|
# For a root class that defines properties
|
|
@@ -184,6 +185,34 @@ class SpecTypeInstance(SpecType):
|
|
|
184
185
|
return defn_type + self.parameters
|
|
185
186
|
|
|
186
187
|
|
|
188
|
+
@dataclass(kw_only=True)
|
|
189
|
+
class SpecEndpointExample:
|
|
190
|
+
summary: str
|
|
191
|
+
description: str
|
|
192
|
+
arguments: dict[str, object]
|
|
193
|
+
data: dict[str, object]
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
@dataclass(kw_only=True)
|
|
197
|
+
class SpecGuide:
|
|
198
|
+
title: str
|
|
199
|
+
markdown_content: str
|
|
200
|
+
html_content: str
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
@dataclass(kw_only=True, frozen=True)
|
|
204
|
+
class RootGuideKey:
|
|
205
|
+
pass
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
@dataclass(kw_only=True, frozen=True)
|
|
209
|
+
class EndpointGuideKey:
|
|
210
|
+
path: str
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
SpecGuideKey = RootGuideKey | EndpointGuideKey
|
|
214
|
+
|
|
215
|
+
|
|
187
216
|
class SpecTypeLiteralWrapper(SpecType):
|
|
188
217
|
def __init__(
|
|
189
218
|
self,
|
|
@@ -672,6 +701,32 @@ class ResultType(StrEnum):
|
|
|
672
701
|
RE_ENDPOINT_ROOT = re.compile(r"\${([_a-z]+)}")
|
|
673
702
|
|
|
674
703
|
|
|
704
|
+
@dataclass(kw_only=True, frozen=True)
|
|
705
|
+
class _EndpointPathDetails:
|
|
706
|
+
root: str
|
|
707
|
+
root_path: str
|
|
708
|
+
resolved_path: str
|
|
709
|
+
|
|
710
|
+
|
|
711
|
+
def _resolve_endpoint_path(
|
|
712
|
+
path: str, api_endpoints: dict[str, str]
|
|
713
|
+
) -> _EndpointPathDetails:
|
|
714
|
+
root_path_source = path.split("/")[0]
|
|
715
|
+
root_match = RE_ENDPOINT_ROOT.fullmatch(root_path_source)
|
|
716
|
+
if root_match is None:
|
|
717
|
+
raise Exception(f"invalid-api-path-root:{root_path_source}")
|
|
718
|
+
|
|
719
|
+
root_var = root_match.group(1)
|
|
720
|
+
root_path = api_endpoints[root_var]
|
|
721
|
+
|
|
722
|
+
_, *rest_path = path.split("/", 1)
|
|
723
|
+
resolved_path = "/".join([root_path] + rest_path)
|
|
724
|
+
|
|
725
|
+
return _EndpointPathDetails(
|
|
726
|
+
root=root_var, root_path=root_path, resolved_path=resolved_path
|
|
727
|
+
)
|
|
728
|
+
|
|
729
|
+
|
|
675
730
|
class SpecEndpoint:
|
|
676
731
|
method: RouteMethod
|
|
677
732
|
root: str
|
|
@@ -748,14 +803,10 @@ class SpecEndpoint:
|
|
|
748
803
|
|
|
749
804
|
self.result_type = ResultType(data.get("result_type", ResultType.json.value))
|
|
750
805
|
|
|
806
|
+
path_details = _resolve_endpoint_path(data["path"], builder.api_endpoints)
|
|
807
|
+
self.root = path_details.root
|
|
808
|
+
self.path_root = path_details.root_path
|
|
751
809
|
self.desc = data.get("desc")
|
|
752
|
-
|
|
753
|
-
root_match = RE_ENDPOINT_ROOT.fullmatch(path[0])
|
|
754
|
-
if root_match is None:
|
|
755
|
-
raise Exception(f"invalid-api-path-root:{path[0]}")
|
|
756
|
-
|
|
757
|
-
self.root = root_match.group(1)
|
|
758
|
-
self.path_root = builder.api_endpoints[self.root]
|
|
759
810
|
# IMPROVE: remove need for is_external flag
|
|
760
811
|
self.is_external = self.path_root == "api/external"
|
|
761
812
|
self.has_attachment = data.get("has_attachment", False)
|
|
@@ -764,6 +815,10 @@ class SpecEndpoint:
|
|
|
764
815
|
not is_sdk or self.desc is not None
|
|
765
816
|
), f"Endpoint description required for SDK endpoints, missing: {path}"
|
|
766
817
|
|
|
818
|
+
@property
|
|
819
|
+
def resolved_path(self: Self) -> str:
|
|
820
|
+
return f"{self.path_root}/{self.path_dirname}/{self.path_basename}"
|
|
821
|
+
|
|
767
822
|
|
|
768
823
|
def _parse_const(
|
|
769
824
|
builder: SpecBuilder,
|
|
@@ -1014,6 +1069,8 @@ class SpecBuilder:
|
|
|
1014
1069
|
self.pending: list[NamespaceDataPair] = []
|
|
1015
1070
|
self.parts: dict[str, dict[str, str]] = defaultdict(dict)
|
|
1016
1071
|
self.preparts: dict[str, dict[str, str]] = defaultdict(dict)
|
|
1072
|
+
self.examples: dict[str, list[SpecEndpointExample]] = defaultdict(list)
|
|
1073
|
+
self.guides: dict[SpecGuideKey, list[SpecGuide]] = defaultdict(list)
|
|
1017
1074
|
self.api_endpoints = api_endpoints
|
|
1018
1075
|
base_namespace = SpecNamespace(name=base_namespace_name)
|
|
1019
1076
|
for base_type in BaseTypeName:
|
|
@@ -1198,5 +1255,53 @@ class SpecBuilder:
|
|
|
1198
1255
|
def add_prepart_file(self, target: str, name: str, data: str) -> None:
|
|
1199
1256
|
self.preparts[target][name] = data
|
|
1200
1257
|
|
|
1258
|
+
def add_example_file(self, data: dict[str, object]) -> None:
|
|
1259
|
+
path_details = _resolve_endpoint_path(str(data["path"]), self.api_endpoints)
|
|
1260
|
+
|
|
1261
|
+
examples_data = data["examples"]
|
|
1262
|
+
if not isinstance(examples_data, list):
|
|
1263
|
+
raise Exception(
|
|
1264
|
+
f"'examples' in example files are expected to be a list, endpoint_path={path_details.resolved_path}"
|
|
1265
|
+
)
|
|
1266
|
+
for example in examples_data:
|
|
1267
|
+
arguments = example["arguments"]
|
|
1268
|
+
data_example = example["data"]
|
|
1269
|
+
if not isinstance(arguments, dict) or not isinstance(data_example, dict):
|
|
1270
|
+
raise Exception(
|
|
1271
|
+
f"'arguments' and 'data' fields must be dictionaries for each endpoint example, endpoint={path_details.resolved_path}"
|
|
1272
|
+
)
|
|
1273
|
+
self.examples[path_details.resolved_path].append(
|
|
1274
|
+
SpecEndpointExample(
|
|
1275
|
+
summary=str(example["summary"]),
|
|
1276
|
+
description=str(example["description"]),
|
|
1277
|
+
arguments=arguments,
|
|
1278
|
+
data=data_example,
|
|
1279
|
+
)
|
|
1280
|
+
)
|
|
1281
|
+
|
|
1282
|
+
def add_guide_file(self, file_content: str) -> None:
|
|
1283
|
+
import markdown
|
|
1284
|
+
|
|
1285
|
+
md = markdown.Markdown(extensions=["meta"])
|
|
1286
|
+
html = md.convert(file_content)
|
|
1287
|
+
meta: dict[str, list[str]] = md.Meta # type: ignore[attr-defined]
|
|
1288
|
+
title_meta: list[str] | None = meta.get("title")
|
|
1289
|
+
if title_meta is None:
|
|
1290
|
+
raise Exception("guides requier a title in the meta section")
|
|
1291
|
+
|
|
1292
|
+
path_meta: list[str] | None = meta.get("path")
|
|
1293
|
+
guide_key: SpecGuideKey = RootGuideKey()
|
|
1294
|
+
if path_meta is not None:
|
|
1295
|
+
path_details = _resolve_endpoint_path("".join(path_meta), self.api_endpoints)
|
|
1296
|
+
guide_key = EndpointGuideKey(path=path_details.resolved_path)
|
|
1297
|
+
|
|
1298
|
+
self.guides[guide_key].append(
|
|
1299
|
+
SpecGuide(
|
|
1300
|
+
title="".join(title_meta),
|
|
1301
|
+
html_content=html,
|
|
1302
|
+
markdown_content=file_content,
|
|
1303
|
+
)
|
|
1304
|
+
)
|
|
1305
|
+
|
|
1201
1306
|
def resolve_proper_name(self, stype: SpecTypeDefn) -> str:
|
|
1202
1307
|
return f"{'.'.join(stype.namespace.path)}.{stype.name}"
|
pkgs/type_spec/emit_io_ts.py
CHANGED
|
@@ -118,7 +118,10 @@ def refer_to_io_ts(
|
|
|
118
118
|
stype: builder.SpecType,
|
|
119
119
|
) -> str:
|
|
120
120
|
if isinstance(stype, builder.SpecTypeInstance):
|
|
121
|
-
if
|
|
121
|
+
if (
|
|
122
|
+
stype.defn_type.name == builder.BaseTypeName.s_list
|
|
123
|
+
or stype.defn_type.name == builder.BaseTypeName.s_readonly_array
|
|
124
|
+
):
|
|
122
125
|
spec = refer_to_io_ts(ctx, stype.parameters[0])
|
|
123
126
|
return f"IO.array({spec})"
|
|
124
127
|
if stype.defn_type.name == builder.BaseTypeName.s_union:
|