UncountablePythonSDK 0.0.115__py3-none-any.whl → 0.0.117__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.
- examples/integration-server/jobs/materials_auto/example_http.py +6 -6
- examples/integration-server/jobs/materials_auto/example_instrument.py +38 -0
- examples/integration-server/jobs/materials_auto/profile.yaml +9 -0
- pkgs/type_spec/builder.py +18 -5
- pkgs/type_spec/config.py +26 -5
- pkgs/type_spec/cross_output_links.py +9 -7
- pkgs/type_spec/emit_open_api.py +18 -2
- pkgs/type_spec/emit_open_api_util.py +1 -0
- pkgs/type_spec/emit_python.py +4 -1
- pkgs/type_spec/emit_typescript.py +46 -30
- pkgs/type_spec/emit_typescript_util.py +16 -0
- pkgs/type_spec/load_types.py +1 -1
- pkgs/type_spec/open_api_util.py +16 -1
- pkgs/type_spec/parts/base.ts.prepart +1 -0
- pkgs/type_spec/ui_entry_actions/generate_ui_entry_actions.py +1 -0
- uncountable/types/__init__.py +4 -0
- uncountable/types/api/entity/create_or_update_entity.py +1 -0
- uncountable/types/api/integrations/__init__.py +1 -0
- uncountable/types/api/integrations/publish_realtime_data.py +41 -0
- uncountable/types/async_batch_processor.py +3 -0
- uncountable/types/client_base.py +3 -0
- uncountable/types/entity_t.py +6 -0
- uncountable/types/integrations.py +10 -0
- uncountable/types/integrations_t.py +62 -0
- {uncountablepythonsdk-0.0.115.dist-info → uncountablepythonsdk-0.0.117.dist-info}/METADATA +1 -1
- {uncountablepythonsdk-0.0.115.dist-info → uncountablepythonsdk-0.0.117.dist-info}/RECORD +28 -23
- {uncountablepythonsdk-0.0.115.dist-info → uncountablepythonsdk-0.0.117.dist-info}/WHEEL +0 -0
- {uncountablepythonsdk-0.0.115.dist-info → uncountablepythonsdk-0.0.117.dist-info}/top_level.txt +0 -0
|
@@ -19,17 +19,17 @@ class HttpExample(CustomHttpJob):
|
|
|
19
19
|
@staticmethod
|
|
20
20
|
def validate_request(
|
|
21
21
|
*,
|
|
22
|
-
request: GenericHttpRequest,
|
|
23
|
-
job_definition: job_definition_t.HttpJobDefinitionBase,
|
|
24
|
-
profile_meta: job_definition_t.ProfileMetadata,
|
|
22
|
+
request: GenericHttpRequest, # noqa: ARG004
|
|
23
|
+
job_definition: job_definition_t.HttpJobDefinitionBase, # noqa: ARG004
|
|
24
|
+
profile_meta: job_definition_t.ProfileMetadata, # noqa: ARG004
|
|
25
25
|
) -> None:
|
|
26
26
|
return None
|
|
27
27
|
|
|
28
28
|
@staticmethod
|
|
29
29
|
def handle_request(
|
|
30
30
|
*,
|
|
31
|
-
request: GenericHttpRequest,
|
|
32
|
-
job_definition: job_definition_t.HttpJobDefinitionBase,
|
|
33
|
-
profile_meta: job_definition_t.ProfileMetadata,
|
|
31
|
+
request: GenericHttpRequest, # noqa: ARG004
|
|
32
|
+
job_definition: job_definition_t.HttpJobDefinitionBase, # noqa: ARG004
|
|
33
|
+
profile_meta: job_definition_t.ProfileMetadata, # noqa: ARG004
|
|
34
34
|
) -> GenericHttpResponse:
|
|
35
35
|
return GenericHttpResponse(response="OK", status_code=200)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from uncountable.integration.job import JobArguments, WebhookJob, register_job
|
|
4
|
+
from uncountable.types import base_t, entity_t, job_definition_t
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@dataclass(kw_only=True)
|
|
8
|
+
class InstrumentPayload:
|
|
9
|
+
equipment_id: base_t.ObjectId
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@register_job
|
|
13
|
+
class InstrumentExample(WebhookJob[InstrumentPayload]):
|
|
14
|
+
def run(
|
|
15
|
+
self, args: JobArguments, payload: InstrumentPayload
|
|
16
|
+
) -> job_definition_t.JobResult:
|
|
17
|
+
equipment_data = args.client.get_entities_data(
|
|
18
|
+
entity_type=entity_t.EntityType.EQUIPMENT,
|
|
19
|
+
entity_ids=[payload.equipment_id],
|
|
20
|
+
).entity_details[0]
|
|
21
|
+
|
|
22
|
+
# Load the instrument's connection details from the entity
|
|
23
|
+
instrument_id = None
|
|
24
|
+
for field in equipment_data.field_values:
|
|
25
|
+
if field.field_ref_name == "ins_instrument_id":
|
|
26
|
+
instrument_id = field.value
|
|
27
|
+
|
|
28
|
+
if instrument_id is None:
|
|
29
|
+
args.logger.log_error("Could not find instrument ID")
|
|
30
|
+
return job_definition_t.JobResult(success=False)
|
|
31
|
+
|
|
32
|
+
args.logger.log_info(f"Instrument ID: {instrument_id}")
|
|
33
|
+
|
|
34
|
+
return job_definition_t.JobResult(success=True)
|
|
35
|
+
|
|
36
|
+
@property
|
|
37
|
+
def webhook_payload_type(self) -> type:
|
|
38
|
+
return InstrumentPayload
|
|
@@ -75,3 +75,12 @@ jobs:
|
|
|
75
75
|
executor:
|
|
76
76
|
type: script
|
|
77
77
|
import_path: example_runsheet_wh
|
|
78
|
+
- id: example_instrument
|
|
79
|
+
type: webhook
|
|
80
|
+
name: Webhook Instrument Connection
|
|
81
|
+
signature_key_secret:
|
|
82
|
+
type: env
|
|
83
|
+
env_key: WH_INSTRUMENT_SIGNATURE_KEY
|
|
84
|
+
executor:
|
|
85
|
+
type: script
|
|
86
|
+
import_path: example_instrument
|
pkgs/type_spec/builder.py
CHANGED
|
@@ -15,12 +15,23 @@ from typing import Any, Self
|
|
|
15
15
|
from . import util
|
|
16
16
|
from .cross_output_links import CrossOutputPaths
|
|
17
17
|
from .non_discriminated_union_exceptions import NON_DISCRIMINATED_UNION_EXCEPTIONS
|
|
18
|
-
from .util import parse_type_str
|
|
18
|
+
from .util import parse_type_str
|
|
19
19
|
|
|
20
20
|
RawDict = dict[Any, Any]
|
|
21
21
|
EndpointKey = str
|
|
22
22
|
|
|
23
23
|
|
|
24
|
+
class PathMapping(StrEnum):
|
|
25
|
+
NO_MAPPING = "no_mapping"
|
|
26
|
+
DEFAULT_MAPPING = "default_mapping"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass(kw_only=True)
|
|
30
|
+
class APIEndpointInfo:
|
|
31
|
+
root_path: str
|
|
32
|
+
path_mapping: PathMapping
|
|
33
|
+
|
|
34
|
+
|
|
24
35
|
class StabilityLevel(StrEnum):
|
|
25
36
|
"""These are currently used for open api,
|
|
26
37
|
see: https://github.com/Tufin/oasdiff/blob/main/docs/STABILITY.md
|
|
@@ -835,7 +846,7 @@ class _EndpointPathDetails:
|
|
|
835
846
|
|
|
836
847
|
|
|
837
848
|
def _resolve_endpoint_path(
|
|
838
|
-
path: str, api_endpoints: dict[EndpointKey,
|
|
849
|
+
path: str, api_endpoints: dict[EndpointKey, APIEndpointInfo]
|
|
839
850
|
) -> _EndpointPathDetails:
|
|
840
851
|
root_path_source = path.split("/")[0]
|
|
841
852
|
root_match = RE_ENDPOINT_ROOT.fullmatch(root_path_source)
|
|
@@ -843,7 +854,7 @@ def _resolve_endpoint_path(
|
|
|
843
854
|
raise Exception(f"invalid-api-path-root:{root_path_source}")
|
|
844
855
|
|
|
845
856
|
root_var = root_match.group(1)
|
|
846
|
-
root_path = api_endpoints[root_var]
|
|
857
|
+
root_path = api_endpoints[root_var].root_path
|
|
847
858
|
|
|
848
859
|
_, *rest_path = path.split("/", 1)
|
|
849
860
|
resolved_path = "/".join([root_path] + rest_path)
|
|
@@ -911,6 +922,7 @@ class SpecEndpoint:
|
|
|
911
922
|
stability_level: StabilityLevel | None
|
|
912
923
|
# Don't emit TypeScript endpoint code
|
|
913
924
|
suppress_ts: bool
|
|
925
|
+
deprecated: bool = False
|
|
914
926
|
async_batch_path: str | None = None
|
|
915
927
|
result_type: ResultType = ResultType.json
|
|
916
928
|
has_attachment: bool = False
|
|
@@ -928,13 +940,13 @@ class SpecEndpoint:
|
|
|
928
940
|
pass
|
|
929
941
|
|
|
930
942
|
def process(self, builder: SpecBuilder, data: RawDict) -> None:
|
|
931
|
-
unused(builder)
|
|
932
943
|
util.check_fields(
|
|
933
944
|
data,
|
|
934
945
|
[
|
|
935
946
|
"method",
|
|
936
947
|
"path",
|
|
937
948
|
"data_loader",
|
|
949
|
+
"deprecated",
|
|
938
950
|
"is_sdk",
|
|
939
951
|
"stability_level",
|
|
940
952
|
"async_batch_path",
|
|
@@ -954,6 +966,7 @@ class SpecEndpoint:
|
|
|
954
966
|
data_loader = data.get("data_loader", False)
|
|
955
967
|
assert isinstance(data_loader, bool)
|
|
956
968
|
self.data_loader = data_loader
|
|
969
|
+
self.deprecated = data.get("deprecated", False)
|
|
957
970
|
|
|
958
971
|
is_sdk = data.get("is_sdk", EndpointEmitType.EMIT_NOTHING)
|
|
959
972
|
|
|
@@ -1346,7 +1359,7 @@ class SpecBuilder:
|
|
|
1346
1359
|
def __init__(
|
|
1347
1360
|
self,
|
|
1348
1361
|
*,
|
|
1349
|
-
api_endpoints: dict[EndpointKey,
|
|
1362
|
+
api_endpoints: dict[EndpointKey, APIEndpointInfo],
|
|
1350
1363
|
top_namespace: str,
|
|
1351
1364
|
cross_output_paths: CrossOutputPaths | None,
|
|
1352
1365
|
) -> None:
|
pkgs/type_spec/config.py
CHANGED
|
@@ -4,6 +4,7 @@ from dataclasses import dataclass
|
|
|
4
4
|
from typing import Self, TypeVar
|
|
5
5
|
|
|
6
6
|
from pkgs.serialization import yaml
|
|
7
|
+
from pkgs.type_spec.builder import APIEndpointInfo, EndpointKey
|
|
7
8
|
|
|
8
9
|
ConfigValueType = str | None | Mapping[str, str | None] | list[str]
|
|
9
10
|
|
|
@@ -19,6 +20,22 @@ def _parse_string_lookup(
|
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
|
|
23
|
+
VT = TypeVar("VT")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _parse_data_lookup(
|
|
27
|
+
key: str,
|
|
28
|
+
raw_value: ConfigValueType,
|
|
29
|
+
conv_func: type[VT],
|
|
30
|
+
) -> dict[str, VT]:
|
|
31
|
+
assert isinstance(raw_value, dict), f"{key} must be key/values"
|
|
32
|
+
return {
|
|
33
|
+
k: conv_func(**v)
|
|
34
|
+
for k, v in raw_value.items()
|
|
35
|
+
if v is not None and isinstance(v, dict)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
22
39
|
@dataclass(kw_only=True)
|
|
23
40
|
class BaseLanguageConfig:
|
|
24
41
|
types_output: (
|
|
@@ -31,7 +48,9 @@ class BaseLanguageConfig:
|
|
|
31
48
|
|
|
32
49
|
@dataclass(kw_only=True)
|
|
33
50
|
class TypeScriptConfig(BaseLanguageConfig):
|
|
34
|
-
|
|
51
|
+
endpoint_to_routes_output: dict[
|
|
52
|
+
EndpointKey, str
|
|
53
|
+
] # folder for generate route files will be located.
|
|
35
54
|
type_info_output: str # folder for generated type info files
|
|
36
55
|
id_source_output: str | None = None # folder for emitted id source maps.
|
|
37
56
|
endpoint_to_frontend_app_type: dict[
|
|
@@ -39,7 +58,7 @@ class TypeScriptConfig(BaseLanguageConfig):
|
|
|
39
58
|
] # map from api_endpoint to frontend app type
|
|
40
59
|
|
|
41
60
|
def __post_init__(self: Self) -> None:
|
|
42
|
-
self.
|
|
61
|
+
self.endpoint_to_routes_output = self.endpoint_to_routes_output
|
|
43
62
|
self.type_info_output = os.path.abspath(self.type_info_output)
|
|
44
63
|
self.id_source_output = (
|
|
45
64
|
os.path.abspath(self.id_source_output)
|
|
@@ -100,7 +119,7 @@ class OpenAPIConfig(BaseLanguageConfig):
|
|
|
100
119
|
class Config:
|
|
101
120
|
top_namespace: str
|
|
102
121
|
type_spec_types: list[str] # folders containing the yaml type spec definitions
|
|
103
|
-
api_endpoint: dict[str,
|
|
122
|
+
api_endpoint: dict[str, APIEndpointInfo]
|
|
104
123
|
# languages
|
|
105
124
|
typescript: TypeScriptConfig | None
|
|
106
125
|
python: PythonConfig
|
|
@@ -125,8 +144,10 @@ def parse_yaml_config(config_file: str) -> Config:
|
|
|
125
144
|
)
|
|
126
145
|
type_spec_types = [os.path.abspath(folder) for folder in raw_type_spec_types]
|
|
127
146
|
|
|
128
|
-
api_endpoint =
|
|
129
|
-
"api_endpoint",
|
|
147
|
+
api_endpoint = _parse_data_lookup(
|
|
148
|
+
"api_endpoint",
|
|
149
|
+
raw_config.get("api_endpoint", {}),
|
|
150
|
+
APIEndpointInfo,
|
|
130
151
|
)
|
|
131
152
|
|
|
132
153
|
raw_typescript = raw_config.get("typescript")
|
|
@@ -21,7 +21,7 @@ def get_python_stub_file_path(
|
|
|
21
21
|
class CrossOutputPaths:
|
|
22
22
|
python_types_output: str
|
|
23
23
|
typescript_types_output: str
|
|
24
|
-
|
|
24
|
+
typescript_routes_output_by_endpoint: dict[str, str]
|
|
25
25
|
typespec_files_input: list[str]
|
|
26
26
|
|
|
27
27
|
|
|
@@ -35,10 +35,9 @@ def get_python_api_file_path(
|
|
|
35
35
|
def get_typescript_api_file_path(
|
|
36
36
|
cross_output_paths: CrossOutputPaths,
|
|
37
37
|
namespace: builder.SpecNamespace,
|
|
38
|
+
endpoint_key: builder.EndpointKey,
|
|
38
39
|
) -> str:
|
|
39
|
-
return (
|
|
40
|
-
f"{cross_output_paths.typescript_routes_output}/{'/'.join(namespace.path)}.tsx"
|
|
41
|
-
)
|
|
40
|
+
return f"{cross_output_paths.typescript_routes_output_by_endpoint[endpoint_key]}/{'/'.join(namespace.path)}.tsx"
|
|
42
41
|
|
|
43
42
|
|
|
44
43
|
def get_yaml_api_file_path(
|
|
@@ -68,13 +67,16 @@ def get_path_links(
|
|
|
68
67
|
namespace: builder.SpecNamespace,
|
|
69
68
|
*,
|
|
70
69
|
current_path_type: str,
|
|
70
|
+
endpoint: builder.SpecEndpoint,
|
|
71
71
|
) -> str:
|
|
72
72
|
if cross_output_paths is None:
|
|
73
73
|
return ""
|
|
74
74
|
|
|
75
75
|
api_paths = {
|
|
76
76
|
"Python": get_python_api_file_path(cross_output_paths, namespace),
|
|
77
|
-
"TypeScript": get_typescript_api_file_path(
|
|
77
|
+
"TypeScript": get_typescript_api_file_path(
|
|
78
|
+
cross_output_paths, namespace, endpoint.default_endpoint_key
|
|
79
|
+
),
|
|
78
80
|
"YAML": get_yaml_api_file_path(cross_output_paths, namespace),
|
|
79
81
|
}
|
|
80
82
|
|
|
@@ -95,11 +97,11 @@ def get_path_links(
|
|
|
95
97
|
|
|
96
98
|
if namespace.endpoint is not None:
|
|
97
99
|
for (
|
|
98
|
-
|
|
100
|
+
endpoint_key,
|
|
99
101
|
path_specific_endpoint,
|
|
100
102
|
) in namespace.endpoint.path_per_api_endpoint.items():
|
|
101
103
|
path_from_root = get_python_stub_file_path(path_specific_endpoint.function)
|
|
102
104
|
if path_from_root is None:
|
|
103
105
|
continue
|
|
104
|
-
paths_string += f"{comment_prefix} Implementation for {
|
|
106
|
+
paths_string += f"{comment_prefix} Implementation for {endpoint_key}: file://./{return_to_root_path}{path_from_root}\n"
|
|
105
107
|
return paths_string
|
pkgs/type_spec/emit_open_api.py
CHANGED
|
@@ -261,6 +261,10 @@ def _emit_endpoint_parameters(
|
|
|
261
261
|
} | _emit_endpoint_parameter_examples(examples)
|
|
262
262
|
|
|
263
263
|
|
|
264
|
+
def _emit_endpoint_deprecated(deprecated: bool) -> DictApiSchema:
|
|
265
|
+
return {"deprecated": True} if deprecated else {}
|
|
266
|
+
|
|
267
|
+
|
|
264
268
|
def _emit_stability_level(
|
|
265
269
|
stability_level: EmitOpenAPIStabilityLevel | None,
|
|
266
270
|
) -> DictApiSchema:
|
|
@@ -376,6 +380,7 @@ def _emit_namespace(
|
|
|
376
380
|
"tags": endpoint.tags,
|
|
377
381
|
"summary": endpoint.summary,
|
|
378
382
|
}
|
|
383
|
+
| _emit_endpoint_deprecated(endpoint.deprecated)
|
|
379
384
|
| _emit_endpoint_description(endpoint.description, ctx.endpoint.guides)
|
|
380
385
|
| _emit_stability_level(endpoint.stability_level)
|
|
381
386
|
| _emit_endpoint_parameters(endpoint, argument_type, ctx.endpoint.examples)
|
|
@@ -474,8 +479,18 @@ def _emit_type(
|
|
|
474
479
|
return
|
|
475
480
|
|
|
476
481
|
if isinstance(stype, builder.SpecTypeDefnUnion):
|
|
477
|
-
|
|
478
|
-
|
|
482
|
+
converted_discriminator_map: dict[str, OpenAPIRefType] = dict()
|
|
483
|
+
if stype.discriminator_map is not None:
|
|
484
|
+
for discriminator_value, base_type in stype.discriminator_map.items():
|
|
485
|
+
converted_base_type = open_api_type(ctx, base_type, config=config)
|
|
486
|
+
assert isinstance(converted_base_type, OpenAPIRefType)
|
|
487
|
+
converted_discriminator_map[discriminator_value] = converted_base_type
|
|
488
|
+
ctx.types[stype.name] = OpenAPIUnionType(
|
|
489
|
+
[open_api_type(ctx, p, config=config) for p in stype.types],
|
|
490
|
+
discriminator=stype.discriminator,
|
|
491
|
+
discriminator_map=converted_discriminator_map
|
|
492
|
+
if stype.discriminator_map is not None
|
|
493
|
+
else None,
|
|
479
494
|
)
|
|
480
495
|
return
|
|
481
496
|
|
|
@@ -617,6 +632,7 @@ def _emit_endpoint(
|
|
|
617
632
|
tags=[tag_name],
|
|
618
633
|
summary=f"{'/'.join(namespace.path[path_cutoff:])}",
|
|
619
634
|
description=description,
|
|
635
|
+
deprecated=namespace.endpoint.deprecated,
|
|
620
636
|
stability_level=namespace.endpoint.stability_level,
|
|
621
637
|
examples=[
|
|
622
638
|
EmitOpenAPIEndpointExample(
|
pkgs/type_spec/emit_python.py
CHANGED
|
@@ -357,7 +357,10 @@ def _emit_namespace(ctx: Context, namespace: builder.SpecNamespace) -> None:
|
|
|
357
357
|
endpoint = namespace.endpoint
|
|
358
358
|
if endpoint is not None:
|
|
359
359
|
path_links = get_path_links(
|
|
360
|
-
ctx.builder.cross_output_paths,
|
|
360
|
+
ctx.builder.cross_output_paths,
|
|
361
|
+
namespace,
|
|
362
|
+
current_path_type="Python",
|
|
363
|
+
endpoint=endpoint,
|
|
361
364
|
)
|
|
362
365
|
if path_links != "":
|
|
363
366
|
ctx.out.write("\n")
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import io
|
|
2
2
|
import os
|
|
3
|
+
from typing import assert_never
|
|
3
4
|
|
|
4
5
|
from . import builder, util
|
|
5
|
-
from .builder import EndpointKey, EndpointSpecificPath
|
|
6
|
+
from .builder import EndpointKey, EndpointSpecificPath, PathMapping
|
|
6
7
|
from .config import TypeScriptConfig
|
|
7
8
|
from .cross_output_links import get_path_links
|
|
8
9
|
from .emit_io_ts import emit_type_io_ts
|
|
9
10
|
from .emit_typescript_util import (
|
|
10
11
|
MODIFY_NOTICE,
|
|
11
12
|
EmitTypescriptContext,
|
|
13
|
+
emit_constant_ts,
|
|
12
14
|
emit_namespace_imports_ts,
|
|
13
15
|
emit_type_ts,
|
|
14
|
-
emit_value_ts,
|
|
15
16
|
resolve_namespace_name,
|
|
16
17
|
resolve_namespace_ref,
|
|
17
18
|
ts_type_name,
|
|
@@ -37,6 +38,7 @@ def _emit_types(builder: builder.SpecBuilder, config: TypeScriptConfig) -> None:
|
|
|
37
38
|
out=io.StringIO(),
|
|
38
39
|
namespace=namespace,
|
|
39
40
|
cross_output_paths=builder.cross_output_paths,
|
|
41
|
+
api_endpoints=builder.api_endpoints,
|
|
40
42
|
)
|
|
41
43
|
|
|
42
44
|
_emit_namespace(ctx, config, namespace)
|
|
@@ -78,6 +80,7 @@ def _emit_types(builder: builder.SpecBuilder, config: TypeScriptConfig) -> None:
|
|
|
78
80
|
full.write("\n")
|
|
79
81
|
full.write(MODIFY_NOTICE)
|
|
80
82
|
full.write(f"// === START section from {namespace.name}.ts.part ===\n")
|
|
83
|
+
full.write("\n")
|
|
81
84
|
full.write(part)
|
|
82
85
|
full.write(f"// === END section from {namespace.name}.ts.part ===\n")
|
|
83
86
|
|
|
@@ -112,7 +115,7 @@ def _emit_namespace(
|
|
|
112
115
|
emit_type_ts(ctx, stype)
|
|
113
116
|
|
|
114
117
|
for sconst in namespace.constants.values():
|
|
115
|
-
|
|
118
|
+
emit_constant_ts(ctx, sconst)
|
|
116
119
|
|
|
117
120
|
if namespace.endpoint is not None:
|
|
118
121
|
_emit_endpoint(ctx, config, namespace, namespace.endpoint)
|
|
@@ -145,7 +148,10 @@ def _emit_endpoint(
|
|
|
145
148
|
assert endpoint.result_type == builder.ResultType.json
|
|
146
149
|
|
|
147
150
|
paths_string = get_path_links(
|
|
148
|
-
ctx.cross_output_paths,
|
|
151
|
+
ctx.cross_output_paths,
|
|
152
|
+
namespace,
|
|
153
|
+
current_path_type="TypeScript",
|
|
154
|
+
endpoint=endpoint,
|
|
149
155
|
)
|
|
150
156
|
|
|
151
157
|
data_loader_head = ""
|
|
@@ -155,7 +161,7 @@ def _emit_endpoint(
|
|
|
155
161
|
assert has_data
|
|
156
162
|
|
|
157
163
|
data_loader_head = (
|
|
158
|
-
'import {
|
|
164
|
+
'import { argsKey, buildApiDataLoader } from "unc_base/data_manager"\n'
|
|
159
165
|
)
|
|
160
166
|
data_loader_body = (
|
|
161
167
|
"\nexport const data = buildApiDataLoader(argsKey(), apiCall)\n"
|
|
@@ -175,38 +181,56 @@ def _emit_endpoint(
|
|
|
175
181
|
unc_base_api_imports = (
|
|
176
182
|
f"appSpecificApiPath, {wrap_name}" if has_multiple_endpoints else wrap_name
|
|
177
183
|
)
|
|
184
|
+
path_mapping = ctx.api_endpoints[endpoint.default_endpoint_key].path_mapping
|
|
185
|
+
|
|
186
|
+
match path_mapping:
|
|
187
|
+
case PathMapping.NO_MAPPING:
|
|
188
|
+
path_mapping_part = (
|
|
189
|
+
"\n { pathMapping: ApplicationT.APIPathMapping.noMapping },"
|
|
190
|
+
)
|
|
191
|
+
case PathMapping.DEFAULT_MAPPING:
|
|
192
|
+
path_mapping_part = ""
|
|
193
|
+
case _:
|
|
194
|
+
assert_never(path_mapping)
|
|
195
|
+
|
|
178
196
|
unc_types_imports = (
|
|
179
|
-
'import { ApplicationT } from "unc_types"\n'
|
|
197
|
+
'import { ApplicationT } from "unc_types"\n'
|
|
198
|
+
if has_multiple_endpoints or path_mapping_part != ""
|
|
199
|
+
else ""
|
|
180
200
|
)
|
|
181
201
|
|
|
182
202
|
type_path = f"unc_types/{'/'.join(namespace.path)}"
|
|
183
203
|
|
|
184
204
|
if is_binary:
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
{
|
|
205
|
+
tsx_response_head = f"""import {{ {unc_base_api_imports} }} from "unc_base/api"
|
|
206
|
+
"""
|
|
207
|
+
tsx_response_part = f"""import type {{ Arguments }} from "{type_path}"
|
|
208
|
+
|
|
188
209
|
export type {{ Arguments }}
|
|
189
210
|
"""
|
|
190
211
|
elif has_data and endpoint.has_attachment:
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
{
|
|
212
|
+
tsx_response_head = f"""import {{ type AttachmentResponse, {unc_base_api_imports} }} from "unc_base/api"
|
|
213
|
+
"""
|
|
214
|
+
tsx_response_part = f"""import type {{ Arguments, Data }} from "{type_path}"
|
|
215
|
+
|
|
194
216
|
export type {{ Arguments, Data }}
|
|
195
217
|
export type Response = AttachmentResponse<Data>
|
|
196
218
|
"""
|
|
197
219
|
elif has_data:
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
{
|
|
220
|
+
tsx_response_head = f"""import {{ {unc_base_api_imports}, type JsonResponse }} from "unc_base/api"
|
|
221
|
+
"""
|
|
222
|
+
tsx_response_part = f"""import type {{ Arguments, Data }} from "{type_path}"
|
|
223
|
+
|
|
201
224
|
export type {{ Arguments, Data }}
|
|
202
225
|
export type Response = JsonResponse<Data>
|
|
203
226
|
"""
|
|
204
227
|
|
|
205
228
|
else:
|
|
206
229
|
assert has_deprecated_result
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
{
|
|
230
|
+
tsx_response_head = f"""import {{ {unc_base_api_imports} }} from "unc_base/api"
|
|
231
|
+
"""
|
|
232
|
+
tsx_response_part = f"""import type {{ Arguments, DeprecatedResult }} from "{type_path}"
|
|
233
|
+
|
|
210
234
|
export type {{ Arguments }}
|
|
211
235
|
export type Response = DeprecatedResult
|
|
212
236
|
"""
|
|
@@ -247,18 +271,18 @@ export type Response = DeprecatedResult
|
|
|
247
271
|
|
|
248
272
|
# tsx_api = f"""{MODIFY_NOTICE}
|
|
249
273
|
tsx_api = f"""{MODIFY_NOTICE}{paths_string}
|
|
250
|
-
{data_loader_head}{tsx_response_part}
|
|
274
|
+
{tsx_response_head}{data_loader_head}{unc_types_imports}{tsx_response_part}
|
|
251
275
|
export const apiCall = {wrap_call}(
|
|
252
|
-
{endpoint_path_part}
|
|
276
|
+
{endpoint_path_part}{path_mapping_part}
|
|
253
277
|
)
|
|
254
278
|
{data_loader_body}"""
|
|
255
279
|
|
|
256
|
-
output = f"{config.
|
|
280
|
+
output = f"{config.endpoint_to_routes_output[endpoint.default_endpoint_key]}/{'/'.join(namespace.path)}.tsx"
|
|
257
281
|
util.rewrite_file(output, tsx_api)
|
|
258
282
|
|
|
259
283
|
# Hacky index support, until enough is migrated to regen entirely
|
|
260
284
|
# Emits the import into the UI API index file
|
|
261
|
-
index_path = f"{config.
|
|
285
|
+
index_path = f"{config.endpoint_to_routes_output[endpoint.default_endpoint_key]}/{'/'.join(namespace.path[0:-1])}/index.tsx"
|
|
262
286
|
api_name = f"Api{ts_type_name(namespace.path[0 - 1])}"
|
|
263
287
|
if os.path.exists(index_path):
|
|
264
288
|
with open(index_path) as index:
|
|
@@ -274,14 +298,6 @@ export const apiCall = {wrap_call}(
|
|
|
274
298
|
index.write(f"export {{ {api_name} }}\n")
|
|
275
299
|
|
|
276
300
|
|
|
277
|
-
def _emit_constant(ctx: EmitTypescriptContext, sconst: builder.SpecConstant) -> None:
|
|
278
|
-
ctx.out.write("\n\n")
|
|
279
|
-
ctx.out.write(MODIFY_NOTICE)
|
|
280
|
-
value = emit_value_ts(ctx, sconst.value_type, sconst.value)
|
|
281
|
-
const_name = sconst.name.upper()
|
|
282
|
-
ctx.out.write(f"export const {const_name} = {value}\n")
|
|
283
|
-
|
|
284
|
-
|
|
285
301
|
def _emit_id_source(builder: builder.SpecBuilder, config: TypeScriptConfig) -> None:
|
|
286
302
|
id_source_output = config.id_source_output
|
|
287
303
|
if id_source_output is None:
|
|
@@ -32,6 +32,7 @@ class EmitTypescriptContext:
|
|
|
32
32
|
namespace: builder.SpecNamespace
|
|
33
33
|
namespaces: set[builder.SpecNamespace] = field(default_factory=set)
|
|
34
34
|
cross_output_paths: CrossOutputPaths | None = None
|
|
35
|
+
api_endpoints: dict[builder.EndpointKey, builder.APIEndpointInfo]
|
|
35
36
|
|
|
36
37
|
|
|
37
38
|
def ts_type_name(name: str) -> str:
|
|
@@ -80,6 +81,12 @@ def emit_value_ts(
|
|
|
80
81
|
if stype.defn_type.is_base_type(builder.BaseTypeName.s_dict):
|
|
81
82
|
key_type = stype.parameters[0]
|
|
82
83
|
value_type = stype.parameters[1]
|
|
84
|
+
|
|
85
|
+
if not key_type.is_base_type(
|
|
86
|
+
builder.BaseTypeName.s_string
|
|
87
|
+
) and not isinstance(key_type, builder.SpecTypeDefnStringEnum):
|
|
88
|
+
raise Exception("invalid dict keys -- dict keys must be string or enum")
|
|
89
|
+
|
|
83
90
|
return (
|
|
84
91
|
"{\n\t"
|
|
85
92
|
+ ",\n\t".join(
|
|
@@ -106,6 +113,14 @@ def emit_value_ts(
|
|
|
106
113
|
raise Exception("invalid constant type", value, stype, type(stype))
|
|
107
114
|
|
|
108
115
|
|
|
116
|
+
def emit_constant_ts(ctx: EmitTypescriptContext, sconst: builder.SpecConstant) -> None:
|
|
117
|
+
ctx.out.write("\n\n")
|
|
118
|
+
ctx.out.write(MODIFY_NOTICE)
|
|
119
|
+
value = emit_value_ts(ctx, sconst.value_type, sconst.value)
|
|
120
|
+
const_name = sconst.name.upper()
|
|
121
|
+
ctx.out.write(f"export const {const_name} = {value}\n")
|
|
122
|
+
|
|
123
|
+
|
|
109
124
|
def emit_type_ts(ctx: EmitTypescriptContext, stype: builder.SpecType) -> None:
|
|
110
125
|
if not isinstance(stype, builder.SpecTypeDefn):
|
|
111
126
|
return
|
|
@@ -118,6 +133,7 @@ def emit_type_ts(ctx: EmitTypescriptContext, stype: builder.SpecType) -> None:
|
|
|
118
133
|
|
|
119
134
|
if isinstance(stype, builder.SpecTypeDefnExternal):
|
|
120
135
|
assert not stype.is_exported, "expecting private names"
|
|
136
|
+
ctx.out.write("\n")
|
|
121
137
|
ctx.out.write(stype.external_map["ts"])
|
|
122
138
|
ctx.out.write("\n")
|
|
123
139
|
return
|
pkgs/type_spec/load_types.py
CHANGED
|
@@ -46,7 +46,7 @@ def load_types(config: Config) -> SpecBuilder | None:
|
|
|
46
46
|
cross_output_paths = CrossOutputPaths(
|
|
47
47
|
python_types_output=config.python.types_output,
|
|
48
48
|
typescript_types_output=config.typescript.types_output,
|
|
49
|
-
|
|
49
|
+
typescript_routes_output_by_endpoint=config.typescript.endpoint_to_routes_output,
|
|
50
50
|
typespec_files_input=config.type_spec_types,
|
|
51
51
|
# IMPROVE not sure how to know which one is the correct one in emit_typescript
|
|
52
52
|
)
|
pkgs/type_spec/open_api_util.py
CHANGED
|
@@ -223,13 +223,28 @@ class OpenAPIUnionType(OpenAPIType):
|
|
|
223
223
|
base_types: list[OpenAPIType],
|
|
224
224
|
description: str | None = None,
|
|
225
225
|
nullable: bool = False,
|
|
226
|
+
discriminator: str | None = None,
|
|
227
|
+
discriminator_map: dict[str, OpenAPIRefType] | None = None,
|
|
226
228
|
) -> None:
|
|
227
229
|
self.base_types = base_types
|
|
230
|
+
self._discriminator = discriminator
|
|
231
|
+
self._discriminator_map = discriminator_map
|
|
228
232
|
super().__init__(description=description, nullable=nullable)
|
|
229
233
|
|
|
230
234
|
def asdict(self) -> dict[str, object]:
|
|
231
235
|
# TODO: use parents description and nullable
|
|
232
|
-
return {
|
|
236
|
+
return {
|
|
237
|
+
"oneOf": [base_type.asdict() for base_type in self.base_types],
|
|
238
|
+
"discriminator": {
|
|
239
|
+
"propertyName": self._discriminator,
|
|
240
|
+
"mapping": {
|
|
241
|
+
discriminator_value: base_type.source
|
|
242
|
+
for discriminator_value, base_type in self._discriminator_map.items()
|
|
243
|
+
},
|
|
244
|
+
}
|
|
245
|
+
if self._discriminator is not None and self._discriminator_map is not None
|
|
246
|
+
else None,
|
|
247
|
+
}
|
|
233
248
|
|
|
234
249
|
|
|
235
250
|
class OpenAPIIntersectionType(OpenAPIType):
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// doesn't allow referring explicitly to global names (thus cannot override here)
|
|
4
4
|
// IMPROVE: invert relationship for global.d.ts looks here instead
|
|
5
5
|
import * as IO from 'io-ts';
|
|
6
|
+
|
|
6
7
|
type localJsonScalar = JsonScalar
|
|
7
8
|
type localJsonValue = JsonValue
|
|
8
9
|
type localObjectId = ObjectId
|
uncountable/types/__init__.py
CHANGED
|
@@ -63,6 +63,7 @@ from . import identifier_t as identifier_t
|
|
|
63
63
|
from . import input_attributes_t as input_attributes_t
|
|
64
64
|
from . import inputs_t as inputs_t
|
|
65
65
|
from . import integration_server_t as integration_server_t
|
|
66
|
+
from . import integrations_t as integrations_t
|
|
66
67
|
from .api.uploader import invoke_uploader as invoke_uploader_t
|
|
67
68
|
from . import job_definition_t as job_definition_t
|
|
68
69
|
from .api.entity import list_entities as list_entities_t
|
|
@@ -76,6 +77,7 @@ from . import overrides_t as overrides_t
|
|
|
76
77
|
from . import permissions_t as permissions_t
|
|
77
78
|
from . import phases_t as phases_t
|
|
78
79
|
from . import post_base_t as post_base_t
|
|
80
|
+
from .api.integrations import publish_realtime_data as publish_realtime_data_t
|
|
79
81
|
from . import queued_job_t as queued_job_t
|
|
80
82
|
from . import recipe_identifiers_t as recipe_identifiers_t
|
|
81
83
|
from . import recipe_inputs_t as recipe_inputs_t
|
|
@@ -180,6 +182,7 @@ __all__: list[str] = [
|
|
|
180
182
|
"input_attributes_t",
|
|
181
183
|
"inputs_t",
|
|
182
184
|
"integration_server_t",
|
|
185
|
+
"integrations_t",
|
|
183
186
|
"invoke_uploader_t",
|
|
184
187
|
"job_definition_t",
|
|
185
188
|
"list_entities_t",
|
|
@@ -193,6 +196,7 @@ __all__: list[str] = [
|
|
|
193
196
|
"permissions_t",
|
|
194
197
|
"phases_t",
|
|
195
198
|
"post_base_t",
|
|
199
|
+
"publish_realtime_data_t",
|
|
196
200
|
"queued_job_t",
|
|
197
201
|
"recipe_identifiers_t",
|
|
198
202
|
"recipe_inputs_t",
|
|
@@ -35,6 +35,7 @@ class Arguments:
|
|
|
35
35
|
definition_key: identifier_t.IdentifierKey
|
|
36
36
|
field_values: list[field_values_t.FieldArgumentValue]
|
|
37
37
|
entity_key: identifier_t.IdentifierKey | None = None
|
|
38
|
+
on_create_init_field_values: list[field_values_t.FieldArgumentValue] | None = None
|
|
38
39
|
|
|
39
40
|
|
|
40
41
|
# DO NOT MODIFY -- This file is generated by type_spec
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
2
|
+
# ruff: noqa: E402 Q003
|
|
3
|
+
# fmt: off
|
|
4
|
+
# isort: skip_file
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
import typing # noqa: F401
|
|
7
|
+
import datetime # noqa: F401
|
|
8
|
+
from decimal import Decimal # noqa: F401
|
|
9
|
+
import dataclasses
|
|
10
|
+
from pkgs.serialization import serial_class
|
|
11
|
+
from ... import base_t
|
|
12
|
+
from ... import integrations_t
|
|
13
|
+
|
|
14
|
+
__all__: list[str] = [
|
|
15
|
+
"Arguments",
|
|
16
|
+
"Data",
|
|
17
|
+
"ENDPOINT_METHOD",
|
|
18
|
+
"ENDPOINT_PATH",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
ENDPOINT_METHOD = "POST"
|
|
22
|
+
ENDPOINT_PATH = "api/external/integrations/publish_realtime_data"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
26
|
+
@serial_class(
|
|
27
|
+
named_type_path="sdk.api.integrations.publish_realtime_data.Arguments",
|
|
28
|
+
)
|
|
29
|
+
@dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
|
|
30
|
+
class Arguments:
|
|
31
|
+
data_package: integrations_t.DataPackage
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
35
|
+
@serial_class(
|
|
36
|
+
named_type_path="sdk.api.integrations.publish_realtime_data.Data",
|
|
37
|
+
)
|
|
38
|
+
@dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
|
|
39
|
+
class Data:
|
|
40
|
+
pass
|
|
41
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
@@ -258,10 +258,12 @@ class AsyncBatchProcessorBase(ABC):
|
|
|
258
258
|
definition_key: identifier_t.IdentifierKey,
|
|
259
259
|
field_values: list[field_values_t.FieldArgumentValue],
|
|
260
260
|
entity_key: identifier_t.IdentifierKey | None = None,
|
|
261
|
+
on_create_init_field_values: list[field_values_t.FieldArgumentValue] | None = None,
|
|
261
262
|
depends_on: list[str] | None = None,
|
|
262
263
|
) -> async_batch_t.QueuedAsyncBatchRequest:
|
|
263
264
|
"""Creates or updates field values for an entity
|
|
264
265
|
|
|
266
|
+
:param on_create_init_field_values: Field values set only when the entity is created (will be ignored if entity already exists)
|
|
265
267
|
:param depends_on: A list of batch reference keys to process before processing this request
|
|
266
268
|
"""
|
|
267
269
|
args = create_or_update_entity_t.Arguments(
|
|
@@ -269,6 +271,7 @@ class AsyncBatchProcessorBase(ABC):
|
|
|
269
271
|
entity_type=entity_type,
|
|
270
272
|
definition_key=definition_key,
|
|
271
273
|
field_values=field_values,
|
|
274
|
+
on_create_init_field_values=on_create_init_field_values,
|
|
272
275
|
)
|
|
273
276
|
json_data = serialize_for_api(args)
|
|
274
277
|
|
uncountable/types/client_base.py
CHANGED
|
@@ -412,15 +412,18 @@ class ClientMethods(ABC):
|
|
|
412
412
|
definition_key: identifier_t.IdentifierKey,
|
|
413
413
|
field_values: list[field_values_t.FieldArgumentValue],
|
|
414
414
|
entity_key: identifier_t.IdentifierKey | None = None,
|
|
415
|
+
on_create_init_field_values: list[field_values_t.FieldArgumentValue] | None = None,
|
|
415
416
|
) -> create_or_update_entity_t.Data:
|
|
416
417
|
"""Creates or updates field values for an entity
|
|
417
418
|
|
|
419
|
+
:param on_create_init_field_values: Field values set only when the entity is created (will be ignored if entity already exists)
|
|
418
420
|
"""
|
|
419
421
|
args = create_or_update_entity_t.Arguments(
|
|
420
422
|
entity_key=entity_key,
|
|
421
423
|
entity_type=entity_type,
|
|
422
424
|
definition_key=definition_key,
|
|
423
425
|
field_values=field_values,
|
|
426
|
+
on_create_init_field_values=on_create_init_field_values,
|
|
424
427
|
)
|
|
425
428
|
api_request = APIRequest(
|
|
426
429
|
method=create_or_update_entity_t.ENDPOINT_METHOD,
|
uncountable/types/entity_t.py
CHANGED
|
@@ -42,6 +42,7 @@ __all__: list[str] = [
|
|
|
42
42
|
"condition_match": "Condition Match",
|
|
43
43
|
"condition_parameter": "Condition Parameter",
|
|
44
44
|
"condition_parameter_mat_family": "Condition Parameter Material Family",
|
|
45
|
+
"condition_parameter_matches": "Condition Parameter Matches",
|
|
45
46
|
"condition_parameter_rule": "Condition Parameter Rule",
|
|
46
47
|
"condition_parameter_value": "Condition Parameter Value",
|
|
47
48
|
"constraint": "Constraint",
|
|
@@ -110,6 +111,7 @@ __all__: list[str] = [
|
|
|
110
111
|
"output_calculation_entity_mapping": "Output Calculation Entity Mapping",
|
|
111
112
|
"output_category_all": "Output Category",
|
|
112
113
|
"output_condition": "Output Condition",
|
|
114
|
+
"output_condition_condition_parameter": "Output Condition Condition Parameter",
|
|
113
115
|
"output_default_condition": "Output Default Condition",
|
|
114
116
|
"output_condition_parameter": "Output Condition Parameter",
|
|
115
117
|
"output_condition_parameter_analytical_method_category": "Output Condition Parameter Analytical Method Category",
|
|
@@ -138,6 +140,7 @@ __all__: list[str] = [
|
|
|
138
140
|
"recipe_ingredient_actual": "Recipe Ingredient Actual",
|
|
139
141
|
"recipe_ingredients_compounded": "Recipe Ingredients Compounded",
|
|
140
142
|
"recipe_ingredients_compounded_calculation": "Recipe Ingredients Compounded Calculation",
|
|
143
|
+
"recipe_link": "Experiment Link",
|
|
141
144
|
"recipe_output": "Recipe Output",
|
|
142
145
|
"recipe_output_annotation": "Recipe Output Annotation",
|
|
143
146
|
"recipe_output_metadata": "Recipe Output Metadata",
|
|
@@ -224,6 +227,7 @@ class EntityType(StrEnum):
|
|
|
224
227
|
CONDITION_MATCH = "condition_match"
|
|
225
228
|
CONDITION_PARAMETER = "condition_parameter"
|
|
226
229
|
CONDITION_PARAMETER_MAT_FAMILY = "condition_parameter_mat_family"
|
|
230
|
+
CONDITION_PARAMETER_MATCHES = "condition_parameter_matches"
|
|
227
231
|
CONDITION_PARAMETER_RULE = "condition_parameter_rule"
|
|
228
232
|
CONDITION_PARAMETER_VALUE = "condition_parameter_value"
|
|
229
233
|
CONSTRAINT = "constraint"
|
|
@@ -292,6 +296,7 @@ class EntityType(StrEnum):
|
|
|
292
296
|
OUTPUT_CALCULATION_ENTITY_MAPPING = "output_calculation_entity_mapping"
|
|
293
297
|
OUTPUT_CATEGORY_ALL = "output_category_all"
|
|
294
298
|
OUTPUT_CONDITION = "output_condition"
|
|
299
|
+
OUTPUT_CONDITION_CONDITION_PARAMETER = "output_condition_condition_parameter"
|
|
295
300
|
OUTPUT_DEFAULT_CONDITION = "output_default_condition"
|
|
296
301
|
OUTPUT_CONDITION_PARAMETER = "output_condition_parameter"
|
|
297
302
|
OUTPUT_CONDITION_PARAMETER_ANALYTICAL_METHOD_CATEGORY = "output_condition_parameter_analytical_method_category"
|
|
@@ -320,6 +325,7 @@ class EntityType(StrEnum):
|
|
|
320
325
|
RECIPE_INGREDIENT_ACTUAL = "recipe_ingredient_actual"
|
|
321
326
|
RECIPE_INGREDIENTS_COMPOUNDED = "recipe_ingredients_compounded"
|
|
322
327
|
RECIPE_INGREDIENTS_COMPOUNDED_CALCULATION = "recipe_ingredients_compounded_calculation"
|
|
328
|
+
RECIPE_LINK = "recipe_link"
|
|
323
329
|
RECIPE_OUTPUT = "recipe_output"
|
|
324
330
|
RECIPE_OUTPUT_ANNOTATION = "recipe_output_annotation"
|
|
325
331
|
RECIPE_OUTPUT_METADATA = "recipe_output_metadata"
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# ruff: noqa: E402 Q003
|
|
2
|
+
# fmt: off
|
|
3
|
+
# isort: skip_file
|
|
4
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
5
|
+
# Kept only for SDK backwards compatibility
|
|
6
|
+
from .integrations_t import DataPackageType as DataPackageType
|
|
7
|
+
from .integrations_t import DataPackageBase as DataPackageBase
|
|
8
|
+
from .integrations_t import DataPackageNumericReading as DataPackageNumericReading
|
|
9
|
+
from .integrations_t import DataPackage as DataPackage
|
|
10
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
2
|
+
# ruff: noqa: E402 Q003
|
|
3
|
+
# fmt: off
|
|
4
|
+
# isort: skip_file
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
import typing # noqa: F401
|
|
7
|
+
import datetime # noqa: F401
|
|
8
|
+
from decimal import Decimal # noqa: F401
|
|
9
|
+
from enum import StrEnum
|
|
10
|
+
import dataclasses
|
|
11
|
+
from pkgs.serialization import serial_class
|
|
12
|
+
from pkgs.serialization import serial_union_annotation
|
|
13
|
+
from . import base_t
|
|
14
|
+
from . import entity_t
|
|
15
|
+
|
|
16
|
+
__all__: list[str] = [
|
|
17
|
+
"DataPackage",
|
|
18
|
+
"DataPackageBase",
|
|
19
|
+
"DataPackageNumericReading",
|
|
20
|
+
"DataPackageType",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
25
|
+
class DataPackageType(StrEnum):
|
|
26
|
+
NUMERIC_READING = "numeric_reading"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
30
|
+
@serial_class(
|
|
31
|
+
named_type_path="sdk.integrations.DataPackageBase",
|
|
32
|
+
)
|
|
33
|
+
@dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
|
|
34
|
+
class DataPackageBase:
|
|
35
|
+
type: DataPackageType
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
39
|
+
@serial_class(
|
|
40
|
+
named_type_path="sdk.integrations.DataPackageNumericReading",
|
|
41
|
+
to_string_values={"value"},
|
|
42
|
+
parse_require={"type"},
|
|
43
|
+
)
|
|
44
|
+
@dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
|
|
45
|
+
class DataPackageNumericReading(DataPackageBase):
|
|
46
|
+
type: typing.Literal[DataPackageType.NUMERIC_READING] = DataPackageType.NUMERIC_READING
|
|
47
|
+
value: Decimal
|
|
48
|
+
target_entity: entity_t.EntityIdentifier
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
52
|
+
DataPackage = typing.Annotated[
|
|
53
|
+
typing.Union[DataPackageNumericReading],
|
|
54
|
+
serial_union_annotation(
|
|
55
|
+
named_type_path="sdk.integrations.DataPackage",
|
|
56
|
+
discriminator="type",
|
|
57
|
+
discriminator_map={
|
|
58
|
+
"numeric_reading": DataPackageNumericReading,
|
|
59
|
+
},
|
|
60
|
+
),
|
|
61
|
+
]
|
|
62
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: UncountablePythonSDK
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.117
|
|
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
|
|
@@ -26,10 +26,11 @@ examples/upload_files.py,sha256=qMaSvMSdTMPOOP55y1AwEurc0SOdZAMvEydlqJPsGpg,432
|
|
|
26
26
|
examples/integration-server/pyproject.toml,sha256=i4Px7I__asDvP4WlAd2PncfRRQ-U4t5xp0tqT9YYs3s,9149
|
|
27
27
|
examples/integration-server/jobs/materials_auto/concurrent_cron.py,sha256=xsK3H9ZEaniedC2nJUB0rqOcFI8y-ojfl_nLSJb9AMM,312
|
|
28
28
|
examples/integration-server/jobs/materials_auto/example_cron.py,sha256=7VVQ-UJsq3DbGpN3XPnorRVZYo-vCwbfSU3VVDluIzA,699
|
|
29
|
-
examples/integration-server/jobs/materials_auto/example_http.py,sha256=
|
|
29
|
+
examples/integration-server/jobs/materials_auto/example_http.py,sha256=eVq-Fss_AhmztxOMqqO-GYGF3KvPt1O5HbNwwC2arh8,1037
|
|
30
|
+
examples/integration-server/jobs/materials_auto/example_instrument.py,sha256=6qq6a8S5soKC-ypVswZEhkLzB_mxd4dxCSIoXKrbGDs,1261
|
|
30
31
|
examples/integration-server/jobs/materials_auto/example_runsheet_wh.py,sha256=_wILTnbzzLf9zrcQb_KQKytxxcya1ej6MqQnoUSS4fA,1180
|
|
31
32
|
examples/integration-server/jobs/materials_auto/example_wh.py,sha256=PN-skP27yJwDZboWk5g5EZEc3AKfVayQLfnopjsDKJc,659
|
|
32
|
-
examples/integration-server/jobs/materials_auto/profile.yaml,sha256=
|
|
33
|
+
examples/integration-server/jobs/materials_auto/profile.yaml,sha256=btUdn8hStM6Zp4zr0kBI2lL461MqDdzfSuF4LvuSQ8k,1926
|
|
33
34
|
pkgs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
34
35
|
pkgs/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
35
36
|
pkgs/argument_parser/__init__.py,sha256=VWUOOtJ-ueRF2lkIJzgQe4xhBKR9IPkgf9vY28nF35s,870
|
|
@@ -63,29 +64,29 @@ pkgs/strenum_compat/__init__.py,sha256=wXRFeNvBm8RU6dy1PFJ5sRLgUIEeH_DVR95Sv5qpG
|
|
|
63
64
|
pkgs/strenum_compat/strenum_compat.py,sha256=uOUAgpYTjHs1MX8dG81jRlyTkt3KNbkV_25zp7xTX2s,36
|
|
64
65
|
pkgs/type_spec/__init__.py,sha256=h5DmJTca4QVV10sZR1x0-MlkZfuGYDfapR3zHvXfzto,19
|
|
65
66
|
pkgs/type_spec/__main__.py,sha256=5bJaX9Y_-FavP0qwzhk-z-V97UY7uaezJTa1zhO_HHQ,1048
|
|
66
|
-
pkgs/type_spec/builder.py,sha256=
|
|
67
|
-
pkgs/type_spec/config.py,sha256=
|
|
68
|
-
pkgs/type_spec/cross_output_links.py,sha256=
|
|
67
|
+
pkgs/type_spec/builder.py,sha256=17_hkJI5jDb_IGOHZCiZDJ8_er-amVH0-WRpqJb7hEE,54365
|
|
68
|
+
pkgs/type_spec/config.py,sha256=m0Rky7Rg2jMglDPQChF30p5h5P86Ap1GObwzLzmypNE,5829
|
|
69
|
+
pkgs/type_spec/cross_output_links.py,sha256=ttFNfuQmR3sNnPSeUER5IPgLiYc-FB5gjlf7RyFYMpc,3293
|
|
69
70
|
pkgs/type_spec/emit_io_ts.py,sha256=CUvBs0boB_X-Kndh66yYcqFfq3oC_LGs8YffLkJ0ZXA,5707
|
|
70
|
-
pkgs/type_spec/emit_open_api.py,sha256
|
|
71
|
-
pkgs/type_spec/emit_open_api_util.py,sha256=
|
|
72
|
-
pkgs/type_spec/emit_python.py,sha256=
|
|
73
|
-
pkgs/type_spec/emit_typescript.py,sha256=
|
|
74
|
-
pkgs/type_spec/emit_typescript_util.py,sha256=
|
|
75
|
-
pkgs/type_spec/load_types.py,sha256=
|
|
71
|
+
pkgs/type_spec/emit_open_api.py,sha256=-2mNpucrEbWNXGZ2xAlqfouPPDP_yOkZVC_ycWpC8UE,26922
|
|
72
|
+
pkgs/type_spec/emit_open_api_util.py,sha256=bTmRvrGP82-eB75hwf9ySI7pDEC87FNQTF18VKEWSXY,2367
|
|
73
|
+
pkgs/type_spec/emit_python.py,sha256=aURsc-wWdamVDCrIWxA7s8_MLAMjLdXZor6ykkibzXY,52707
|
|
74
|
+
pkgs/type_spec/emit_typescript.py,sha256=FINir79bz4tJYgJuUylNJFvqChzaFlHNCfZ5D7A6B1I,11447
|
|
75
|
+
pkgs/type_spec/emit_typescript_util.py,sha256=ChP4oF2ZJoL0qErGCL0nscj0w_yH6TBgE92MtQS8nPI,11638
|
|
76
|
+
pkgs/type_spec/load_types.py,sha256=JL7tX2H_cy3p5HjGuvNFJlY4pDSbDVnYFsh9mK16-ic,4302
|
|
76
77
|
pkgs/type_spec/non_discriminated_union_exceptions.py,sha256=JB4WNDJWc3e9WMOabX4aTd0-6K7n1hctIW2lGf1bYts,612
|
|
77
|
-
pkgs/type_spec/open_api_util.py,sha256=
|
|
78
|
+
pkgs/type_spec/open_api_util.py,sha256=r4rryE95valu4kmHaMAbXQ5PMwbUnnwYv4Gh6_CwiSU,7966
|
|
78
79
|
pkgs/type_spec/test.py,sha256=4ueujBq-pEgnX3Z69HyPmD-bullFXmpixcpVzfOkhP4,489
|
|
79
80
|
pkgs/type_spec/util.py,sha256=S_SGTJU192x-wIbngVUTvXhQENMbBfxluigLmnItGI8,4848
|
|
80
81
|
pkgs/type_spec/actions_registry/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
81
82
|
pkgs/type_spec/actions_registry/__main__.py,sha256=SRw6kIhHTW7W2wGijYq66JARzoc4KpPmbLqwvnETyTE,4277
|
|
82
83
|
pkgs/type_spec/actions_registry/emit_typescript.py,sha256=W1lI36ITdJ7MBf37wlTB7H3X9Ljt217vIGMv4e3fxfY,5986
|
|
83
84
|
pkgs/type_spec/parts/base.py.prepart,sha256=Xy8my5ol_Iu0hpQpvgsmqGLkGcMsLSg-cgjm4Yp-QI4,2369
|
|
84
|
-
pkgs/type_spec/parts/base.ts.prepart,sha256=
|
|
85
|
+
pkgs/type_spec/parts/base.ts.prepart,sha256=42-1_N_K04t4c6pE62V4wBw3bR5bgPxhmXUk__A7gAs,1002
|
|
85
86
|
pkgs/type_spec/type_info/__main__.py,sha256=TLNvCHGcmaj_8Sj5bAQNpuNaaw2dpDzoFDWZds0V4Qo,1002
|
|
86
87
|
pkgs/type_spec/type_info/emit_type_info.py,sha256=xRjZiwDDii4Bq8yVfcgE8YFechoKAcGmYXBk3Dq-K-s,15387
|
|
87
88
|
pkgs/type_spec/ui_entry_actions/__init__.py,sha256=WiHE_BexOEZWbkkbD7EnFau1aMLNmfgQywG9PTQNCkw,135
|
|
88
|
-
pkgs/type_spec/ui_entry_actions/generate_ui_entry_actions.py,sha256=
|
|
89
|
+
pkgs/type_spec/ui_entry_actions/generate_ui_entry_actions.py,sha256=65qUEp9zVcAsHEe3QjOTlPfLf45kH980fOXZXKNmOC8,9503
|
|
89
90
|
pkgs/type_spec/value_spec/__init__.py,sha256=Z-grlcZtxAfEXhPHsK0nD7PFLGsv4eqvunaPN7_TA84,83
|
|
90
91
|
pkgs/type_spec/value_spec/__main__.py,sha256=oM5lcV6Hv_03okjtfWn2fzSHsarFVa9ArU_g02XnQJw,8879
|
|
91
92
|
pkgs/type_spec/value_spec/convert_type.py,sha256=OvP7dwUMHXNHVXWYT4jkaYJ96S3a2SnFuC_iMdYVB7s,2927
|
|
@@ -139,9 +140,9 @@ uncountable/integration/queue_runner/datastore/model.py,sha256=8-RI5A2yPZVGBLWIN
|
|
|
139
140
|
uncountable/integration/secret_retrieval/__init__.py,sha256=3QXVj35w8rRMxVvmmsViFYDi3lcb3g70incfalOEm6o,87
|
|
140
141
|
uncountable/integration/secret_retrieval/retrieve_secret.py,sha256=LBEf18KHtXZxg-ZZ80stJ1vW39AWf0CQllP6pNu3Eq8,2994
|
|
141
142
|
uncountable/integration/webhook_server/entrypoint.py,sha256=NQawXl_JCRojdVniS5RF7dobQQKW_Wy03bwy-uXknuA,3441
|
|
142
|
-
uncountable/types/__init__.py,sha256=
|
|
143
|
+
uncountable/types/__init__.py,sha256=EZC_LgnO80PfE3SW4Sg95Ew3iUORmT_7oz-6u4zTulY,10169
|
|
143
144
|
uncountable/types/async_batch.py,sha256=yCCWrrLQfxXVqZp-KskxLBNkNmuELdz4PJjx8ULppgs,662
|
|
144
|
-
uncountable/types/async_batch_processor.py,sha256=
|
|
145
|
+
uncountable/types/async_batch_processor.py,sha256=h_8Snzt3lbEFlZAZFByt4Hg4dv2YlxMijHjTHjZ0aXY,22062
|
|
145
146
|
uncountable/types/async_batch_t.py,sha256=JuswurXlYW38MfAXJ0UWb7hE2rmzFaHBAsNhRYAyMD4,3779
|
|
146
147
|
uncountable/types/async_jobs.py,sha256=JI0ScfawaqMRbJ2jbgW3YQLhijPnBeYdMnZJjygSxHg,322
|
|
147
148
|
uncountable/types/async_jobs_t.py,sha256=u4xd3i512PZ-9592Q2ZgWh_faMiI4UMm0F_gOmZnerI,1389
|
|
@@ -153,7 +154,7 @@ uncountable/types/calculations.py,sha256=fApOFpgBemt_t7IVneVR0VdI3X5EOxiG6Xhzr6R
|
|
|
153
154
|
uncountable/types/calculations_t.py,sha256=pl-lhjyDQuj11Sf9g1-0BsSkN7Ez8UxDp8-KMQ_3enM,709
|
|
154
155
|
uncountable/types/chemical_structure.py,sha256=ujyragaD26-QG5jgKnWhO7TN3N1V9b_04T2WhqNYxxo,281
|
|
155
156
|
uncountable/types/chemical_structure_t.py,sha256=VFFyits_vx4t5L2euu_qFiSpsGJjURkDPr3ISnr3nPc,855
|
|
156
|
-
uncountable/types/client_base.py,sha256=
|
|
157
|
+
uncountable/types/client_base.py,sha256=Qd8kxA0C76FKTAuoJOVjEw48mInfV_IXH2CBBTyYwAs,76382
|
|
157
158
|
uncountable/types/client_config.py,sha256=qLpHt4O_B098CyN6qQajoxZ2zjZ1DILXLUEGyyGP0TQ,280
|
|
158
159
|
uncountable/types/client_config_t.py,sha256=yTFIYAitMrcc4oV9J-HADODS_Hwi45z-piz7rr7QT04,781
|
|
159
160
|
uncountable/types/curves.py,sha256=QyEyC20jsG-LGKVx6miiF-w70vKMwNkILFBDIJ5Ok9g,345
|
|
@@ -161,7 +162,7 @@ uncountable/types/curves_t.py,sha256=DxYepdC3QKKR7mepOOBoyarNcFZQdUa5ZYH-hwCY3BI
|
|
|
161
162
|
uncountable/types/data.py,sha256=u2isf4XEug3Eu-xSIoqGaCQmW2dFaKBHCkP_WKYwwBc,500
|
|
162
163
|
uncountable/types/data_t.py,sha256=vFoypK_WMGfN28r1sSlDYHZNUdBQC0XCN7-_Mlo4FJk,2832
|
|
163
164
|
uncountable/types/entity.py,sha256=Zclk1LYcRaYrMDhqyCjMSLEg0fE6_q8LHvV22Qvscgs,566
|
|
164
|
-
uncountable/types/entity_t.py,sha256=
|
|
165
|
+
uncountable/types/entity_t.py,sha256=Q-Ji3IMpQxXoY680ZOYz5Zkcy_wrz3lgQOnKqoU9noA,20666
|
|
165
166
|
uncountable/types/experiment_groups.py,sha256=qUpFOx1AKgzaT_4khCOv5Xs6jwiQGbvHH-GUh3v1nv4,288
|
|
166
167
|
uncountable/types/experiment_groups_t.py,sha256=29Ct-WPejpYMuGfnFfOoosU9iSfjzxpabpBX6oTPFUA,761
|
|
167
168
|
uncountable/types/exports.py,sha256=VMmxUO2PpV1Y63hZ2AnVor4H-B6aswJ7YpSru_u89lU,334
|
|
@@ -182,6 +183,8 @@ uncountable/types/inputs.py,sha256=3ghg39_oiLF5HqWF_wNwYv4HMR1lrKLfeRLn5ptIGw4,4
|
|
|
182
183
|
uncountable/types/inputs_t.py,sha256=eSVA7LNgLI3ja83GJm4sA9KhPICVV4zj2Dd4OhbuY9g,2158
|
|
183
184
|
uncountable/types/integration_server.py,sha256=VonA8h8TGnVBiss5W8-K82lA01JQa7TLk0ubFo8iiBQ,364
|
|
184
185
|
uncountable/types/integration_server_t.py,sha256=pgtoyuW6QvGRawidJZFB-WnOdwCE4OIoJAvGfussZKU,1304
|
|
186
|
+
uncountable/types/integrations.py,sha256=0fOhtbLIOl9w1GP9J3PTagRU8mjOKV48JNLLH3SJQP0,472
|
|
187
|
+
uncountable/types/integrations_t.py,sha256=ihyhuMDKtJarQ19OppS0fYpJUYd8o5-w6YCDE440O-w,1871
|
|
185
188
|
uncountable/types/job_definition.py,sha256=hYp5jPYLLYm3NKEqzQrQfXL0Ms5KgEQGTON13YWSPYk,1804
|
|
186
189
|
uncountable/types/job_definition_t.py,sha256=E4IQvcYF3VDHbwRlvopy8y-HNAyEMZpwy7jkmp74fgQ,9563
|
|
187
190
|
uncountable/types/outputs.py,sha256=I6zP2WHXg_jXgMqmuEJuJOlsjKjQGHjfs1JOwW9YxBM,260
|
|
@@ -235,7 +238,7 @@ uncountable/types/api/condition_parameters/upsert_condition_match.py,sha256=7I9l
|
|
|
235
238
|
uncountable/types/api/entity/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr8APdZYUniAor8,55
|
|
236
239
|
uncountable/types/api/entity/create_entities.py,sha256=cCDEra2SHvGWvz7nIxxMDSQN6OWrHMTT0JSomWUesto,1794
|
|
237
240
|
uncountable/types/api/entity/create_entity.py,sha256=urT6C7iGAa7_rCv9Wcz6GM_lKg1tP55E__rjNkj-Rjc,1879
|
|
238
|
-
uncountable/types/api/entity/create_or_update_entity.py,sha256=
|
|
241
|
+
uncountable/types/api/entity/create_or_update_entity.py,sha256=cxjJIcZTKOg8Y5kGzctYKayfnr8BNZDOM5YfI4dBSf0,1532
|
|
239
242
|
uncountable/types/api/entity/export_entities.py,sha256=zz_4P6bQAt7gU2o2to9zUh0HHLQKaxLkbFGfbgY3KVk,1395
|
|
240
243
|
uncountable/types/api/entity/get_entities_data.py,sha256=hu0UfkU4PTyv3_CBZ7YmR8L8BKMq8hx6zH43XtUm16E,1616
|
|
241
244
|
uncountable/types/api/entity/grant_entity_permissions.py,sha256=4CvVIMvpdok8K1Bh6wMlwuUmoeP_-nL9y2GCEM6uAhY,1536
|
|
@@ -267,6 +270,8 @@ uncountable/types/api/inputs/set_input_attribute_values.py,sha256=Tgd3KofNXYBj2u
|
|
|
267
270
|
uncountable/types/api/inputs/set_input_category.py,sha256=6e1L0RQU6nt51PTZ99Ca4ZfIxIcpa0pXBDCwRFxTKPs,1283
|
|
268
271
|
uncountable/types/api/inputs/set_input_subcategories.py,sha256=w5U6eXes5KquPW1UcYPRHimrfY_cN-K93IrpOw1Gl7s,1320
|
|
269
272
|
uncountable/types/api/inputs/set_intermediate_type.py,sha256=S1RLI2RtrRze0NdMUfK2nwR4Twn_DnLnWNsg0-ivi_A,1431
|
|
273
|
+
uncountable/types/api/integrations/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr8APdZYUniAor8,55
|
|
274
|
+
uncountable/types/api/integrations/publish_realtime_data.py,sha256=-5r2U78AwKUCpModcUIchVIZ9b7L-Ln6O6T-9d57M2A,1181
|
|
270
275
|
uncountable/types/api/material_families/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr8APdZYUniAor8,55
|
|
271
276
|
uncountable/types/api/material_families/update_entity_material_families.py,sha256=qWJgAKH0MayadXvxckePCdo9yd34QXOmGZ7cKz5VLNo,1761
|
|
272
277
|
uncountable/types/api/outputs/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr8APdZYUniAor8,55
|
|
@@ -318,7 +323,7 @@ uncountable/types/api/triggers/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr
|
|
|
318
323
|
uncountable/types/api/triggers/run_trigger.py,sha256=dgDX_sRWSJ36UuzMZhG25oHV1HIOUKYY2G3fjKugZrw,1204
|
|
319
324
|
uncountable/types/api/uploader/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr8APdZYUniAor8,55
|
|
320
325
|
uncountable/types/api/uploader/invoke_uploader.py,sha256=Bj7Dq4A90k00suacwk3bLA_dCb2aovS1kAbVam2AQnM,1395
|
|
321
|
-
uncountablepythonsdk-0.0.
|
|
322
|
-
uncountablepythonsdk-0.0.
|
|
323
|
-
uncountablepythonsdk-0.0.
|
|
324
|
-
uncountablepythonsdk-0.0.
|
|
326
|
+
uncountablepythonsdk-0.0.117.dist-info/METADATA,sha256=tj3OqRKTNxJzMEkVnW6fwy_8S1OUT-00sE7vV4W9lag,2143
|
|
327
|
+
uncountablepythonsdk-0.0.117.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
328
|
+
uncountablepythonsdk-0.0.117.dist-info/top_level.txt,sha256=1UVGjAU-6hJY9qw2iJ7nCBeEwZ793AEN5ZfKX9A1uj4,31
|
|
329
|
+
uncountablepythonsdk-0.0.117.dist-info/RECORD,,
|
|
File without changes
|
{uncountablepythonsdk-0.0.115.dist-info → uncountablepythonsdk-0.0.117.dist-info}/top_level.txt
RENAMED
|
File without changes
|