UncountablePythonSDK 0.0.127__py3-none-any.whl → 0.0.128__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_parse.py +87 -0
- examples/integration-server/jobs/materials_auto/example_runsheet_wh.py +3 -2
- examples/integration-server/jobs/materials_auto/profile.yaml +9 -0
- uncountable/integration/job.py +2 -3
- uncountable/integration/telemetry.py +41 -7
- uncountable/types/client_base.py +1 -1
- {uncountablepythonsdk-0.0.127.dist-info → uncountablepythonsdk-0.0.128.dist-info}/METADATA +1 -1
- {uncountablepythonsdk-0.0.127.dist-info → uncountablepythonsdk-0.0.128.dist-info}/RECORD +10 -9
- {uncountablepythonsdk-0.0.127.dist-info → uncountablepythonsdk-0.0.128.dist-info}/WHEEL +0 -0
- {uncountablepythonsdk-0.0.127.dist-info → uncountablepythonsdk-0.0.128.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from uncountable.integration.job import JobArguments, WebhookJob, register_job
|
|
4
|
+
from uncountable.types import (
|
|
5
|
+
base_t,
|
|
6
|
+
generic_upload_t,
|
|
7
|
+
identifier_t,
|
|
8
|
+
job_definition_t,
|
|
9
|
+
uploader_t,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(kw_only=True)
|
|
14
|
+
class ParsePayload:
|
|
15
|
+
async_job_id: base_t.ObjectId
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@register_job
|
|
19
|
+
class ParseExample(WebhookJob[ParsePayload]):
|
|
20
|
+
def run(
|
|
21
|
+
self, args: JobArguments, payload: ParsePayload
|
|
22
|
+
) -> job_definition_t.JobResult:
|
|
23
|
+
dummy_parsed_file_data: list[uploader_t.ParsedFileData] = [
|
|
24
|
+
uploader_t.ParsedFileData(
|
|
25
|
+
file_name="my_file_to_upload.xlsx",
|
|
26
|
+
file_structures=[
|
|
27
|
+
uploader_t.DataChannel(
|
|
28
|
+
type=uploader_t.StructureElementType.CHANNEL,
|
|
29
|
+
channel=uploader_t.TextChannelData(
|
|
30
|
+
name="column1",
|
|
31
|
+
type=uploader_t.ChannelType.TEXT_CHANNEL,
|
|
32
|
+
data=[
|
|
33
|
+
uploader_t.StringValue(value="value1"),
|
|
34
|
+
uploader_t.StringValue(value="value4"),
|
|
35
|
+
uploader_t.StringValue(value="value7"),
|
|
36
|
+
],
|
|
37
|
+
),
|
|
38
|
+
),
|
|
39
|
+
uploader_t.DataChannel(
|
|
40
|
+
type=uploader_t.StructureElementType.CHANNEL,
|
|
41
|
+
channel=uploader_t.TextChannelData(
|
|
42
|
+
name="column2",
|
|
43
|
+
type=uploader_t.ChannelType.TEXT_CHANNEL,
|
|
44
|
+
data=[
|
|
45
|
+
uploader_t.StringValue(value="value2"),
|
|
46
|
+
uploader_t.StringValue(value="value5"),
|
|
47
|
+
uploader_t.StringValue(value="value8"),
|
|
48
|
+
],
|
|
49
|
+
),
|
|
50
|
+
),
|
|
51
|
+
uploader_t.DataChannel(
|
|
52
|
+
type=uploader_t.StructureElementType.CHANNEL,
|
|
53
|
+
channel=uploader_t.TextChannelData(
|
|
54
|
+
name="column3",
|
|
55
|
+
type=uploader_t.ChannelType.TEXT_CHANNEL,
|
|
56
|
+
data=[
|
|
57
|
+
uploader_t.StringValue(value="value3"),
|
|
58
|
+
uploader_t.StringValue(value="value6"),
|
|
59
|
+
uploader_t.StringValue(value="value9"),
|
|
60
|
+
],
|
|
61
|
+
),
|
|
62
|
+
),
|
|
63
|
+
uploader_t.HeaderEntry(
|
|
64
|
+
type=uploader_t.StructureElementType.HEADER,
|
|
65
|
+
value=uploader_t.TextHeaderData(
|
|
66
|
+
name="file_source",
|
|
67
|
+
type=uploader_t.HeaderType.TEXT_HEADER,
|
|
68
|
+
data=uploader_t.StringValue(value="my_file_to_upload.xlsx"),
|
|
69
|
+
),
|
|
70
|
+
),
|
|
71
|
+
],
|
|
72
|
+
)
|
|
73
|
+
]
|
|
74
|
+
|
|
75
|
+
args.client.complete_async_parse(
|
|
76
|
+
parsed_file_data=dummy_parsed_file_data,
|
|
77
|
+
async_job_key=identifier_t.IdentifierKeyId(id=payload.async_job_id),
|
|
78
|
+
upload_destination=generic_upload_t.UploadDestinationRecipe(
|
|
79
|
+
recipe_key=identifier_t.IdentifierKeyId(id=1)
|
|
80
|
+
),
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
return job_definition_t.JobResult(success=True)
|
|
84
|
+
|
|
85
|
+
@property
|
|
86
|
+
def webhook_payload_type(self) -> type:
|
|
87
|
+
return ParsePayload
|
|
@@ -2,7 +2,7 @@ from io import BytesIO
|
|
|
2
2
|
|
|
3
3
|
from uncountable.core.file_upload import DataFileUpload, FileUpload
|
|
4
4
|
from uncountable.integration.job import JobArguments, RunsheetWebhookJob, register_job
|
|
5
|
-
from uncountable.types import
|
|
5
|
+
from uncountable.types import webhook_job_t
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
@register_job
|
|
@@ -11,8 +11,9 @@ class StandardRunsheetGenerator(RunsheetWebhookJob):
|
|
|
11
11
|
self,
|
|
12
12
|
*,
|
|
13
13
|
args: JobArguments,
|
|
14
|
-
|
|
14
|
+
payload: webhook_job_t.RunsheetWebhookPayload,
|
|
15
15
|
) -> FileUpload:
|
|
16
|
+
entities = payload.entities
|
|
16
17
|
args.logger.log_info(f"Generating runsheet for {len(entities)} entities")
|
|
17
18
|
|
|
18
19
|
content = []
|
|
@@ -93,3 +93,12 @@ jobs:
|
|
|
93
93
|
executor:
|
|
94
94
|
type: script
|
|
95
95
|
import_path: example_predictions
|
|
96
|
+
- id: example_parse
|
|
97
|
+
type: webhook
|
|
98
|
+
name: Webhook Parse
|
|
99
|
+
signature_key_secret:
|
|
100
|
+
type: env
|
|
101
|
+
env_key: WH_PARSE_SIGNATURE_KEY
|
|
102
|
+
executor:
|
|
103
|
+
type: script
|
|
104
|
+
import_path: example_parse
|
uncountable/integration/job.py
CHANGED
|
@@ -28,7 +28,6 @@ from uncountable.integration.secret_retrieval.retrieve_secret import retrieve_se
|
|
|
28
28
|
from uncountable.integration.telemetry import JobLogger
|
|
29
29
|
from uncountable.types import (
|
|
30
30
|
base_t,
|
|
31
|
-
entity_t,
|
|
32
31
|
job_definition_t,
|
|
33
32
|
queued_job_t,
|
|
34
33
|
webhook_job_t,
|
|
@@ -255,13 +254,13 @@ class RunsheetWebhookJob(WebhookJob[webhook_job_t.RunsheetWebhookPayload]):
|
|
|
255
254
|
self,
|
|
256
255
|
*,
|
|
257
256
|
args: JobArguments,
|
|
258
|
-
|
|
257
|
+
payload: webhook_job_t.RunsheetWebhookPayload,
|
|
259
258
|
) -> FileUpload: ...
|
|
260
259
|
|
|
261
260
|
def run(
|
|
262
261
|
self, args: JobArguments, payload: webhook_job_t.RunsheetWebhookPayload
|
|
263
262
|
) -> JobResult:
|
|
264
|
-
runsheet = self.build_runsheet(args=args,
|
|
263
|
+
runsheet = self.build_runsheet(args=args, payload=payload)
|
|
265
264
|
|
|
266
265
|
files = args.client.upload_files(file_uploads=[runsheet])
|
|
267
266
|
args.client.complete_async_upload(
|
|
@@ -12,7 +12,10 @@ from opentelemetry import _logs, trace
|
|
|
12
12
|
from opentelemetry.exporter.otlp.proto.http._log_exporter import OTLPLogExporter
|
|
13
13
|
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
|
|
14
14
|
from opentelemetry.sdk._logs import Logger as OTELLogger
|
|
15
|
-
from opentelemetry.sdk._logs import
|
|
15
|
+
from opentelemetry.sdk._logs import (
|
|
16
|
+
LoggerProvider,
|
|
17
|
+
LogRecord,
|
|
18
|
+
)
|
|
16
19
|
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor, ConsoleLogExporter
|
|
17
20
|
from opentelemetry.sdk.resources import Attributes, Resource
|
|
18
21
|
from opentelemetry.sdk.trace import TracerProvider
|
|
@@ -95,8 +98,27 @@ class Logger:
|
|
|
95
98
|
def current_trace_id(self) -> int | None:
|
|
96
99
|
return self.current_span.get_span_context().trace_id
|
|
97
100
|
|
|
98
|
-
def _patch_attributes(
|
|
99
|
-
|
|
101
|
+
def _patch_attributes(
|
|
102
|
+
self,
|
|
103
|
+
attributes: Attributes | None,
|
|
104
|
+
*,
|
|
105
|
+
message: str | None = None,
|
|
106
|
+
severity: LogSeverity | None = None,
|
|
107
|
+
) -> Attributes:
|
|
108
|
+
patched_attributes = {**(attributes if attributes is not None else {})}
|
|
109
|
+
if message is not None:
|
|
110
|
+
patched_attributes["message"] = message
|
|
111
|
+
elif "body" in patched_attributes:
|
|
112
|
+
patched_attributes["message"] = patched_attributes["body"]
|
|
113
|
+
|
|
114
|
+
if severity is not None:
|
|
115
|
+
patched_attributes["status"] = severity.lower()
|
|
116
|
+
elif "severity_text" in patched_attributes and isinstance(
|
|
117
|
+
patched_attributes["severity_text"], str
|
|
118
|
+
):
|
|
119
|
+
patched_attributes["status"] = patched_attributes["severity_text"].lower()
|
|
120
|
+
|
|
121
|
+
return patched_attributes
|
|
100
122
|
|
|
101
123
|
def _emit_log(
|
|
102
124
|
self, message: str, *, severity: LogSeverity, attributes: Attributes | None
|
|
@@ -106,7 +128,9 @@ class Logger:
|
|
|
106
128
|
body=message,
|
|
107
129
|
severity_text=severity,
|
|
108
130
|
timestamp=time.time_ns(),
|
|
109
|
-
attributes=self._patch_attributes(
|
|
131
|
+
attributes=self._patch_attributes(
|
|
132
|
+
message=message, severity=severity, attributes=attributes
|
|
133
|
+
),
|
|
110
134
|
span_id=self.current_span_id,
|
|
111
135
|
trace_id=self.current_trace_id,
|
|
112
136
|
trace_flags=DEFAULT_TRACE_OPTIONS,
|
|
@@ -140,7 +164,9 @@ class Logger:
|
|
|
140
164
|
attributes: Attributes | None = None,
|
|
141
165
|
) -> None:
|
|
142
166
|
traceback_str = "".join(traceback.format_exception(exception))
|
|
143
|
-
patched_attributes = self._patch_attributes(
|
|
167
|
+
patched_attributes = self._patch_attributes(
|
|
168
|
+
message=message, severity=LogSeverity.ERROR, attributes=attributes
|
|
169
|
+
)
|
|
144
170
|
self.current_span.record_exception(
|
|
145
171
|
exception=exception, attributes=patched_attributes
|
|
146
172
|
)
|
|
@@ -171,9 +197,17 @@ class JobLogger(Logger):
|
|
|
171
197
|
self.job_definition = job_definition
|
|
172
198
|
super().__init__(base_span)
|
|
173
199
|
|
|
174
|
-
def _patch_attributes(
|
|
200
|
+
def _patch_attributes(
|
|
201
|
+
self,
|
|
202
|
+
attributes: Attributes | None,
|
|
203
|
+
*,
|
|
204
|
+
message: str | None = None,
|
|
205
|
+
severity: LogSeverity | None = None,
|
|
206
|
+
) -> Attributes:
|
|
175
207
|
patched_attributes: dict[str, base_t.JsonValue] = {
|
|
176
|
-
**(
|
|
208
|
+
**super()._patch_attributes(
|
|
209
|
+
attributes=attributes, message=message, severity=severity
|
|
210
|
+
)
|
|
177
211
|
}
|
|
178
212
|
patched_attributes["profile.name"] = self.profile_metadata.name
|
|
179
213
|
patched_attributes["profile.base_url"] = self.profile_metadata.base_url
|
uncountable/types/client_base.py
CHANGED
|
@@ -537,7 +537,7 @@ class ClientMethods(ABC):
|
|
|
537
537
|
recipe_definitions: list[create_recipes_t.CreateRecipeDefinition],
|
|
538
538
|
project_id: base_t.ObjectId | None = None,
|
|
539
539
|
) -> create_recipes_t.Data:
|
|
540
|
-
"""
|
|
540
|
+
"""Creates recipes in Uncountable, optionally with metadata values, and returns the resulting ids in corresponding order
|
|
541
541
|
|
|
542
542
|
:param material_family_id: The identifier of the material family to create the recipes in
|
|
543
543
|
:param project_id: The identifier of the project to create the recipes in
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: UncountablePythonSDK
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.128
|
|
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
|
|
@@ -32,10 +32,11 @@ examples/integration-server/jobs/materials_auto/concurrent_cron.py,sha256=xsK3H9
|
|
|
32
32
|
examples/integration-server/jobs/materials_auto/example_cron.py,sha256=spUMiiTEFaepbVXecjD_4aEEfqEtZGGZuWTKs9J6Xcw,736
|
|
33
33
|
examples/integration-server/jobs/materials_auto/example_http.py,sha256=eIL46ElWo8SKY7W5JWWkwZk6Qo7KRd9EJBxfy7YQ_sE,1429
|
|
34
34
|
examples/integration-server/jobs/materials_auto/example_instrument.py,sha256=R2iIRs-2a_9S0LOE42RhglDpZhRkMEa6pCPCxMdqRoI,3438
|
|
35
|
+
examples/integration-server/jobs/materials_auto/example_parse.py,sha256=Rf1tlUoIaY5Py12NhnXzsiZerbTwvX_EdcGUABGv-qI,3489
|
|
35
36
|
examples/integration-server/jobs/materials_auto/example_predictions.py,sha256=8eiKNq9rocOceLrfqbTop3iwXgIr25NTfjXXKBKIVfI,2104
|
|
36
|
-
examples/integration-server/jobs/materials_auto/example_runsheet_wh.py,sha256=
|
|
37
|
+
examples/integration-server/jobs/materials_auto/example_runsheet_wh.py,sha256=Mhh3PM1j_M35UnMllYNLbTvpMoIcoMOoHIPDaabN_hs,1235
|
|
37
38
|
examples/integration-server/jobs/materials_auto/example_wh.py,sha256=PN-skP27yJwDZboWk5g5EZEc3AKfVayQLfnopjsDKJc,659
|
|
38
|
-
examples/integration-server/jobs/materials_auto/profile.yaml,sha256=
|
|
39
|
+
examples/integration-server/jobs/materials_auto/profile.yaml,sha256=ywDrDRAyqiUdj_HvosNP5bXBL8mCWsvdJ1eYQd-mGYo,2369
|
|
39
40
|
pkgs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
40
41
|
pkgs/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
41
42
|
pkgs/argument_parser/__init__.py,sha256=EG3pwLEHTp-Qltd3lRnO4K22RiVrasePzKPDOfTPxFY,924
|
|
@@ -110,11 +111,11 @@ uncountable/integration/cli.py,sha256=sCE0Cz4tMzlzgD3-3P7XmgTUTBinR_yeNkaC-vvPZG
|
|
|
110
111
|
uncountable/integration/construct_client.py,sha256=I53mGcdS88hba3HFwgXmWQaTd1d5u0jWNSwyc_vlVsQ,1937
|
|
111
112
|
uncountable/integration/cron.py,sha256=6eH-kIs3sdYPCyb62_L2M7U_uQTdMTdwY5hreEJb0hw,887
|
|
112
113
|
uncountable/integration/entrypoint.py,sha256=BHOYPQgKvZE6HG8Rv15MkdYl8lRkvfDgv1OdLo0oQ9Q,433
|
|
113
|
-
uncountable/integration/job.py,sha256=
|
|
114
|
+
uncountable/integration/job.py,sha256=brXg6cod4eKNfgPB1J6a0hnrWOrJxRRF571shvxHBw8,8237
|
|
114
115
|
uncountable/integration/scan_profiles.py,sha256=RHBmPc5E10YZzf4cmglwrn2yAy0jHBhQ-P_GlAk2TeU,2919
|
|
115
116
|
uncountable/integration/scheduler.py,sha256=vJQGpuMgryFp5aCQEg5BIvywnu4t3SSFcGoLfY10LKg,6610
|
|
116
117
|
uncountable/integration/server.py,sha256=fU7d26546WA-IRwL8wqWM62ogx28YvTmNd9kQ7c56WI,5787
|
|
117
|
-
uncountable/integration/telemetry.py,sha256=
|
|
118
|
+
uncountable/integration/telemetry.py,sha256=bWfOm4B_ajen4WWIz6tYJSUBGAw3O7nyvhh9Zr3lV9g,8692
|
|
118
119
|
uncountable/integration/db/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
119
120
|
uncountable/integration/db/connect.py,sha256=mE3bdV0huclH2iT_dXCQdRL4LkjIuf_myAR64RTWXEs,498
|
|
120
121
|
uncountable/integration/db/session.py,sha256=96cGQXpe6IugBTdSsjdP0S5yhJ6toSmbVB6qhc3FJzE,693
|
|
@@ -160,7 +161,7 @@ uncountable/types/calculations.py,sha256=fApOFpgBemt_t7IVneVR0VdI3X5EOxiG6Xhzr6R
|
|
|
160
161
|
uncountable/types/calculations_t.py,sha256=pl-lhjyDQuj11Sf9g1-0BsSkN7Ez8UxDp8-KMQ_3enM,709
|
|
161
162
|
uncountable/types/chemical_structure.py,sha256=ujyragaD26-QG5jgKnWhO7TN3N1V9b_04T2WhqNYxxo,281
|
|
162
163
|
uncountable/types/chemical_structure_t.py,sha256=VFFyits_vx4t5L2euu_qFiSpsGJjURkDPr3ISnr3nPc,855
|
|
163
|
-
uncountable/types/client_base.py,sha256=
|
|
164
|
+
uncountable/types/client_base.py,sha256=2HCcT8J0Fb8DXlubq1vLHoCA-LQuki6hpLN3I8Z8p3Y,81359
|
|
164
165
|
uncountable/types/client_config.py,sha256=qLpHt4O_B098CyN6qQajoxZ2zjZ1DILXLUEGyyGP0TQ,280
|
|
165
166
|
uncountable/types/client_config_t.py,sha256=yTFIYAitMrcc4oV9J-HADODS_Hwi45z-piz7rr7QT04,781
|
|
166
167
|
uncountable/types/curves.py,sha256=QyEyC20jsG-LGKVx6miiF-w70vKMwNkILFBDIJ5Ok9g,345
|
|
@@ -344,7 +345,7 @@ uncountable/types/api/uploader/complete_async_parse.py,sha256=nYYBzjT_j4L7_1Ge-i
|
|
|
344
345
|
uncountable/types/api/uploader/invoke_uploader.py,sha256=Bj7Dq4A90k00suacwk3bLA_dCb2aovS1kAbVam2AQnM,1395
|
|
345
346
|
uncountable/types/api/user/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr8APdZYUniAor8,55
|
|
346
347
|
uncountable/types/api/user/get_current_user_info.py,sha256=Avqi_RXtRgbefrT_dwJ9MrO6eDNSSa_Nu650FSuESlg,1109
|
|
347
|
-
uncountablepythonsdk-0.0.
|
|
348
|
-
uncountablepythonsdk-0.0.
|
|
349
|
-
uncountablepythonsdk-0.0.
|
|
350
|
-
uncountablepythonsdk-0.0.
|
|
348
|
+
uncountablepythonsdk-0.0.128.dist-info/METADATA,sha256=J7DAPIol3tInaykdWto7qqNgzTU7-ZbeMCks78LgUXs,2174
|
|
349
|
+
uncountablepythonsdk-0.0.128.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
350
|
+
uncountablepythonsdk-0.0.128.dist-info/top_level.txt,sha256=1UVGjAU-6hJY9qw2iJ7nCBeEwZ793AEN5ZfKX9A1uj4,31
|
|
351
|
+
uncountablepythonsdk-0.0.128.dist-info/RECORD,,
|
|
File without changes
|
{uncountablepythonsdk-0.0.127.dist-info → uncountablepythonsdk-0.0.128.dist-info}/top_level.txt
RENAMED
|
File without changes
|