albert 1.10.0rc2__py3-none-any.whl → 1.11.1__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.
- albert/__init__.py +1 -1
- albert/client.py +5 -0
- albert/collections/custom_templates.py +3 -0
- albert/collections/data_templates.py +118 -264
- albert/collections/entity_types.py +19 -3
- albert/collections/inventory.py +1 -1
- albert/collections/notebooks.py +154 -26
- albert/collections/parameters.py +1 -0
- albert/collections/property_data.py +384 -280
- albert/collections/reports.py +4 -0
- albert/collections/synthesis.py +292 -0
- albert/collections/tasks.py +2 -1
- albert/collections/worksheets.py +3 -0
- albert/core/shared/models/base.py +3 -1
- albert/core/shared/models/patch.py +1 -1
- albert/resources/batch_data.py +4 -2
- albert/resources/cas.py +3 -1
- albert/resources/custom_fields.py +3 -1
- albert/resources/data_templates.py +60 -12
- albert/resources/entity_types.py +15 -4
- albert/resources/inventory.py +6 -4
- albert/resources/lists.py +3 -1
- albert/resources/notebooks.py +12 -7
- albert/resources/parameter_groups.py +3 -1
- albert/resources/property_data.py +64 -5
- albert/resources/sheets.py +16 -14
- albert/resources/synthesis.py +61 -0
- albert/resources/tags.py +3 -1
- albert/resources/tasks.py +4 -7
- albert/resources/workflows.py +4 -2
- albert/utils/data_template.py +392 -37
- albert/utils/property_data.py +638 -0
- albert/utils/tasks.py +3 -3
- {albert-1.10.0rc2.dist-info → albert-1.11.1.dist-info}/METADATA +1 -1
- {albert-1.10.0rc2.dist-info → albert-1.11.1.dist-info}/RECORD +37 -34
- {albert-1.10.0rc2.dist-info → albert-1.11.1.dist-info}/WHEEL +0 -0
- {albert-1.10.0rc2.dist-info → albert-1.11.1.dist-info}/licenses/LICENSE +0 -0
albert/resources/notebooks.py
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import re
|
|
2
4
|
import uuid
|
|
3
5
|
from datetime import datetime
|
|
4
6
|
from enum import Enum
|
|
7
|
+
from pathlib import Path
|
|
5
8
|
from typing import Annotated, Any, Literal
|
|
6
9
|
|
|
7
10
|
from pandas import DataFrame
|
|
@@ -104,6 +107,7 @@ class AttachesContent(BaseAlbertModel):
|
|
|
104
107
|
namespace: str = Field(default="result")
|
|
105
108
|
file_key: str | None = Field(default=None, alias="fileKey")
|
|
106
109
|
format: str | None = Field(default=None, alias="mimeType")
|
|
110
|
+
file_path: str | Path | None = Field(default=None, exclude=True)
|
|
107
111
|
signed_url: str | None = Field(default=None, alias="signedURL", exclude=True, frozen=True)
|
|
108
112
|
|
|
109
113
|
|
|
@@ -120,6 +124,7 @@ class ImageContent(BaseAlbertModel):
|
|
|
120
124
|
with_border: bool = Field(default=False, alias="withBorder")
|
|
121
125
|
file_key: str | None = Field(default=None, alias="fileKey")
|
|
122
126
|
format: str | None = Field(default=None, alias="mimeType")
|
|
127
|
+
file_path: str | Path | None = Field(default=None, exclude=True)
|
|
123
128
|
signed_url: str | None = Field(default=None, alias="signedURL", exclude=True, frozen=True)
|
|
124
129
|
|
|
125
130
|
|
|
@@ -130,14 +135,14 @@ class ImageBlock(BaseBlock):
|
|
|
130
135
|
|
|
131
136
|
class KetcherContent(BaseAlbertModel):
|
|
132
137
|
synthesis_id: SynthesisId | None = Field(default=None, alias="synthesisId")
|
|
133
|
-
name: str | None = Field(default=None)
|
|
134
138
|
id: str | None = Field(default=None)
|
|
135
139
|
block_id: str | None = Field(default=None, alias="blockId")
|
|
136
|
-
data: str
|
|
140
|
+
data: str = Field(default=None, exclude=True)
|
|
137
141
|
file_key: str | None = Field(default=None, alias="fileKey")
|
|
138
|
-
s3_key: str | None = Field(default=None, alias="s3Key"
|
|
139
|
-
png: str | None = Field(default=None, exclude=True
|
|
140
|
-
|
|
142
|
+
s3_key: str | None = Field(default=None, alias="s3Key")
|
|
143
|
+
png: str | None = Field(default=None, exclude=True)
|
|
144
|
+
state_type: str = Field(default="project", alias="stateType")
|
|
145
|
+
smiles: str | None = Field(default=None, alias="smiles", exclude=True)
|
|
141
146
|
|
|
142
147
|
|
|
143
148
|
class KetcherBlock(BaseBlock):
|
|
@@ -179,7 +184,7 @@ class TableBlock(BaseBlock):
|
|
|
179
184
|
|
|
180
185
|
class NotebookListItem(BaseAlbertModel):
|
|
181
186
|
content: str | None
|
|
182
|
-
items: list[
|
|
187
|
+
items: list[NotebookListItem] = Field(default_factory=list)
|
|
183
188
|
|
|
184
189
|
|
|
185
190
|
class BulletedListContent(BaseAlbertModel):
|
|
@@ -264,7 +269,7 @@ class PutBlockDatum(BaseAlbertModel):
|
|
|
264
269
|
previous_block_id: str | None = Field(default=None, alias="previousBlockId")
|
|
265
270
|
|
|
266
271
|
@model_validator(mode="after")
|
|
267
|
-
def content_matches_type(self) ->
|
|
272
|
+
def content_matches_type(self) -> PutBlockDatum:
|
|
268
273
|
if self.content is None:
|
|
269
274
|
return self # skip check if there's no content
|
|
270
275
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
from enum import Enum
|
|
2
4
|
from typing import Any
|
|
3
5
|
|
|
@@ -123,7 +125,7 @@ class ParameterValue(BaseAlbertModel):
|
|
|
123
125
|
return value
|
|
124
126
|
|
|
125
127
|
@model_validator(mode="after")
|
|
126
|
-
def set_parameter_fields(self) ->
|
|
128
|
+
def set_parameter_fields(self) -> ParameterValue:
|
|
127
129
|
if self.parameter is None and self.id is None:
|
|
128
130
|
raise ValueError("Please provide either an id or an parameter object.")
|
|
129
131
|
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
from enum import Enum
|
|
4
|
+
from pathlib import Path
|
|
2
5
|
from typing import Any, Literal
|
|
3
6
|
|
|
4
7
|
import pandas as pd
|
|
@@ -20,7 +23,12 @@ from albert.core.shared.identifiers import (
|
|
|
20
23
|
from albert.core.shared.models.base import BaseResource
|
|
21
24
|
from albert.core.shared.models.patch import PatchDatum
|
|
22
25
|
from albert.core.shared.types import SerializeAsEntityLink
|
|
23
|
-
from albert.resources.data_templates import
|
|
26
|
+
from albert.resources.data_templates import (
|
|
27
|
+
CurveDBMetadata,
|
|
28
|
+
DataTemplate,
|
|
29
|
+
ImportMode,
|
|
30
|
+
StorageKeyReference,
|
|
31
|
+
)
|
|
24
32
|
from albert.resources.lots import Lot
|
|
25
33
|
from albert.resources.units import Unit
|
|
26
34
|
from albert.resources.workflows import Workflow
|
|
@@ -173,7 +181,7 @@ class BulkPropertyData(BaseAlbertModel):
|
|
|
173
181
|
)
|
|
174
182
|
|
|
175
183
|
@classmethod
|
|
176
|
-
def from_dataframe(cls, df: pd.DataFrame) ->
|
|
184
|
+
def from_dataframe(cls, df: pd.DataFrame) -> BulkPropertyData:
|
|
177
185
|
"""
|
|
178
186
|
Converts a DataFrame to a BulkPropertyData object.
|
|
179
187
|
|
|
@@ -205,6 +213,51 @@ class TaskPropertyValue(BaseAlbertModel):
|
|
|
205
213
|
value: str | None = Field(default=None)
|
|
206
214
|
|
|
207
215
|
|
|
216
|
+
class ImagePropertyValue(BaseAlbertModel):
|
|
217
|
+
"""
|
|
218
|
+
Image property value input.
|
|
219
|
+
|
|
220
|
+
Attributes
|
|
221
|
+
----------
|
|
222
|
+
file_path : str | Path
|
|
223
|
+
Local path to the image file to upload.
|
|
224
|
+
"""
|
|
225
|
+
|
|
226
|
+
file_path: str | Path
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
class CurvePropertyValue(BaseAlbertModel):
|
|
230
|
+
"""
|
|
231
|
+
Curve property value input.
|
|
232
|
+
|
|
233
|
+
Attributes
|
|
234
|
+
----------
|
|
235
|
+
file_path : str | Path
|
|
236
|
+
Local path to the CSV file containing curve data.
|
|
237
|
+
mode : ImportMode
|
|
238
|
+
Import mode for the curve data.
|
|
239
|
+
field_mapping : dict[str, str] | None
|
|
240
|
+
Optional mapping from CSV headers to curve result identifiers.
|
|
241
|
+
"""
|
|
242
|
+
|
|
243
|
+
file_path: str | Path
|
|
244
|
+
mode: ImportMode = ImportMode.CSV
|
|
245
|
+
field_mapping: dict[str, str] | None = None
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
class ImagePropertyValuePayload(BaseAlbertModel):
|
|
249
|
+
file_name: str = Field(alias="fileName")
|
|
250
|
+
s3_key: StorageKeyReference = Field(alias="s3Key")
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
class CurvePropertyValuePayload(BaseAlbertModel):
|
|
254
|
+
file_name: str = Field(alias="fileName")
|
|
255
|
+
s3_key: StorageKeyReference = Field(alias="s3Key")
|
|
256
|
+
job_id: str = Field(alias="jobId")
|
|
257
|
+
csv_mapping: dict[str, str] = Field(alias="csvMapping")
|
|
258
|
+
athena: CurveDBMetadata
|
|
259
|
+
|
|
260
|
+
|
|
208
261
|
class TaskDataColumn(BaseAlbertModel):
|
|
209
262
|
data_column_id: DataColumnId = Field(alias="id")
|
|
210
263
|
column_sequence: str | None = Field(default=None, alias="columnId")
|
|
@@ -263,9 +316,15 @@ class TaskPropertyCreate(BaseResource):
|
|
|
263
316
|
description="The interval combination, which can be found using `Workflow.get_interval_id`.",
|
|
264
317
|
)
|
|
265
318
|
data_column: TaskDataColumn = Field(
|
|
266
|
-
|
|
319
|
+
alias="DataColumns", description="The data column associated with the task property."
|
|
320
|
+
)
|
|
321
|
+
value: str | ImagePropertyValue | CurvePropertyValue | None = Field(
|
|
322
|
+
default=None,
|
|
323
|
+
description=(
|
|
324
|
+
"The value of the task property. Use ImagePropertyValue for image data columns or "
|
|
325
|
+
"CurvePropertyValue for curve data columns."
|
|
326
|
+
),
|
|
267
327
|
)
|
|
268
|
-
value: str | None = Field(default=None, description="The value of the task property.")
|
|
269
328
|
trial_number: int = Field(
|
|
270
329
|
alias="trialNo",
|
|
271
330
|
default=None,
|
|
@@ -283,7 +342,7 @@ class TaskPropertyCreate(BaseResource):
|
|
|
283
342
|
)
|
|
284
343
|
|
|
285
344
|
@model_validator(mode="after")
|
|
286
|
-
def set_visible_trial_number(self) ->
|
|
345
|
+
def set_visible_trial_number(self) -> TaskPropertyCreate:
|
|
287
346
|
if self.visible_trial_number is None:
|
|
288
347
|
if self.trial_number is not None:
|
|
289
348
|
self.visible_trial_number = self.trial_number
|
albert/resources/sheets.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
from enum import Enum
|
|
2
4
|
from typing import Any, ForwardRef, TypedDict, Union
|
|
3
5
|
|
|
@@ -165,7 +167,7 @@ class Component(BaseResource):
|
|
|
165
167
|
_cell: Cell = None # read only property set on registrstion
|
|
166
168
|
|
|
167
169
|
@model_validator(mode="after")
|
|
168
|
-
def _ensure_inventory_reference(self:
|
|
170
|
+
def _ensure_inventory_reference(self: Component) -> Component:
|
|
169
171
|
item = self.inventory_item
|
|
170
172
|
if item is None and self.inventory_id is None:
|
|
171
173
|
raise ValueError("Component requires either 'inventory_item' or 'inventory_id'.")
|
|
@@ -217,9 +219,9 @@ class Design(BaseSessionResource):
|
|
|
217
219
|
id: str = Field(alias="albertId")
|
|
218
220
|
design_type: DesignType = Field(alias="designType")
|
|
219
221
|
_grid: pd.DataFrame | None = PrivateAttr(default=None)
|
|
220
|
-
_rows: list[
|
|
221
|
-
_columns: list[
|
|
222
|
-
_sheet: Union[
|
|
222
|
+
_rows: list[Row] | None = PrivateAttr(default=None)
|
|
223
|
+
_columns: list[Column] | None = PrivateAttr(default=None)
|
|
224
|
+
_sheet: Union[Sheet, None] = PrivateAttr(default=None) # noqa
|
|
223
225
|
_leftmost_pinned_column: str | None = PrivateAttr(default=None)
|
|
224
226
|
|
|
225
227
|
def _grid_to_cell_df(self, *, grid_response):
|
|
@@ -284,7 +286,7 @@ class Design(BaseSessionResource):
|
|
|
284
286
|
self._grid = self._get_grid()
|
|
285
287
|
return self._grid
|
|
286
288
|
|
|
287
|
-
def _get_columns(self, *, grid_response: dict) -> list[
|
|
289
|
+
def _get_columns(self, *, grid_response: dict) -> list[Column]:
|
|
288
290
|
"""
|
|
289
291
|
Normalizes inventory IDs (always prefixed "INV") and—for the
|
|
290
292
|
"Inventory ID" header—falls back to the row's top-level `id`
|
|
@@ -358,7 +360,7 @@ class Design(BaseSessionResource):
|
|
|
358
360
|
|
|
359
361
|
return cols
|
|
360
362
|
|
|
361
|
-
def _get_rows(self, *, grid_response: dict) -> list[
|
|
363
|
+
def _get_rows(self, *, grid_response: dict) -> list[Row]:
|
|
362
364
|
"""
|
|
363
365
|
Parse the /grid response into a list of Row models.
|
|
364
366
|
|
|
@@ -413,13 +415,13 @@ class Design(BaseSessionResource):
|
|
|
413
415
|
return self._grid_to_cell_df(grid_response=resp_json)
|
|
414
416
|
|
|
415
417
|
@property
|
|
416
|
-
def columns(self) -> list[
|
|
418
|
+
def columns(self) -> list[Column]:
|
|
417
419
|
if not self._columns:
|
|
418
420
|
self._get_grid()
|
|
419
421
|
return self._columns
|
|
420
422
|
|
|
421
423
|
@property
|
|
422
|
-
def rows(self) -> list[
|
|
424
|
+
def rows(self) -> list[Row]:
|
|
423
425
|
if not self._rows:
|
|
424
426
|
self._get_grid()
|
|
425
427
|
return self._rows
|
|
@@ -494,7 +496,7 @@ class Sheet(BaseSessionResource): # noqa:F811
|
|
|
494
496
|
return self._process_design
|
|
495
497
|
|
|
496
498
|
@model_validator(mode="after")
|
|
497
|
-
def set_sheet_fields(self:
|
|
499
|
+
def set_sheet_fields(self: Sheet) -> Sheet:
|
|
498
500
|
for _idx, d in enumerate(self.designs): # Instead of creating a new list
|
|
499
501
|
d._sheet = self # Set the reference to the sheet
|
|
500
502
|
if d.design_type == DesignType.APPS:
|
|
@@ -542,12 +544,12 @@ class Sheet(BaseSessionResource): # noqa:F811
|
|
|
542
544
|
return self._leftmost_pinned_column
|
|
543
545
|
|
|
544
546
|
@property
|
|
545
|
-
def columns(self) -> list[
|
|
547
|
+
def columns(self) -> list[Column]:
|
|
546
548
|
"""The columns of a given sheet"""
|
|
547
549
|
return self.product_design.columns
|
|
548
550
|
|
|
549
551
|
@property
|
|
550
|
-
def rows(self) -> list[
|
|
552
|
+
def rows(self) -> list[Row]:
|
|
551
553
|
"""The rows of a given sheet"""
|
|
552
554
|
rows = []
|
|
553
555
|
for d in self.designs:
|
|
@@ -607,7 +609,7 @@ class Sheet(BaseSessionResource): # noqa:F811
|
|
|
607
609
|
new_dicts.append(this_dict)
|
|
608
610
|
return new_dicts
|
|
609
611
|
|
|
610
|
-
def _clear_formulation_from_column(self, *, column:
|
|
612
|
+
def _clear_formulation_from_column(self, *, column: Column):
|
|
611
613
|
cleared_cells = []
|
|
612
614
|
for cell in column.cells:
|
|
613
615
|
if cell.type == CellType.INVENTORY:
|
|
@@ -674,7 +676,7 @@ class Sheet(BaseSessionResource): # noqa:F811
|
|
|
674
676
|
inventory_id: InventoryId,
|
|
675
677
|
existing_cells,
|
|
676
678
|
enforce_order,
|
|
677
|
-
product_rows: list[
|
|
679
|
+
product_rows: list[Row],
|
|
678
680
|
):
|
|
679
681
|
sheet_inv_id = inventory_id
|
|
680
682
|
matching_rows = [row for row in product_rows if row.inventory_id == sheet_inv_id]
|
|
@@ -736,7 +738,7 @@ class Sheet(BaseSessionResource): # noqa:F811
|
|
|
736
738
|
*,
|
|
737
739
|
formulation_names: list[str],
|
|
738
740
|
starting_position: dict | None = None,
|
|
739
|
-
) -> list[
|
|
741
|
+
) -> list[Column]:
|
|
740
742
|
if starting_position is None:
|
|
741
743
|
starting_position = {
|
|
742
744
|
"reference_id": self.leftmost_pinned_column,
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from pydantic import Field
|
|
6
|
+
|
|
7
|
+
from albert.core.base import BaseAlbertModel
|
|
8
|
+
from albert.core.shared.identifiers import NotebookId, SynthesisId
|
|
9
|
+
from albert.core.shared.models.base import AuditFields
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ColumnDescriptor(BaseAlbertModel):
|
|
13
|
+
id: str
|
|
14
|
+
label: str | None = None
|
|
15
|
+
category: str | None = None
|
|
16
|
+
default: Any | None = None
|
|
17
|
+
type: str | None = None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ColumnSequence(BaseAlbertModel):
|
|
21
|
+
reactants: list[ColumnDescriptor] = Field(default_factory=list)
|
|
22
|
+
products: list[ColumnDescriptor] = Field(default_factory=list)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class RowSequence(BaseAlbertModel):
|
|
26
|
+
reactants: list[str] = Field(default_factory=list)
|
|
27
|
+
products: list[str] = Field(default_factory=list)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ReactionParticipant(BaseAlbertModel):
|
|
31
|
+
row_id: str = Field(alias="rowId")
|
|
32
|
+
smiles: str | None = None
|
|
33
|
+
values: dict[str, Any] | None = None
|
|
34
|
+
type: str | None = None
|
|
35
|
+
limiting_reagent: str | bool | None = Field(default=None, alias="limitingReagent")
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class Synthesis(BaseAlbertModel):
|
|
39
|
+
id: SynthesisId = Field(alias="albertId")
|
|
40
|
+
parent_id: NotebookId | str | None = Field(default=None, alias="parentId")
|
|
41
|
+
name: str | None = None
|
|
42
|
+
status: str | None = None
|
|
43
|
+
block_id: str | None = Field(default=None, alias="blockId")
|
|
44
|
+
inventory_id: str | None = Field(default=None, alias="inventoryId")
|
|
45
|
+
hide_reaction_worksheet: str | bool | None = Field(default=None, alias="hideReactionWorksheet")
|
|
46
|
+
s3_key: str | None = Field(default=None, alias="s3Key")
|
|
47
|
+
canvas_data: dict[str, Any] | None = Field(default=None, alias="canvasData")
|
|
48
|
+
smiles: list[str | None] = Field(default_factory=list)
|
|
49
|
+
reactants: list[ReactionParticipant] = Field(default_factory=list)
|
|
50
|
+
products: list[ReactionParticipant] = Field(default_factory=list)
|
|
51
|
+
column_sequence: ColumnSequence | None = Field(default=None, alias="columnSequence")
|
|
52
|
+
row_sequence: RowSequence | None = Field(default=None, alias="rowSequence")
|
|
53
|
+
created: AuditFields | None = Field(default=None, alias="Created")
|
|
54
|
+
updated: AuditFields | None = Field(default=None, alias="Updated")
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class ReactantValues(BaseAlbertModel):
|
|
58
|
+
mass: float | None = None
|
|
59
|
+
moles: float | None = None
|
|
60
|
+
eq: float | None = None
|
|
61
|
+
concentration: float | int | None = None
|
albert/resources/tags.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
from enum import Enum
|
|
2
4
|
from typing import Any
|
|
3
5
|
|
|
@@ -45,7 +47,7 @@ class Tag(BaseResource):
|
|
|
45
47
|
)
|
|
46
48
|
|
|
47
49
|
@classmethod
|
|
48
|
-
def from_string(cls, tag: str) ->
|
|
50
|
+
def from_string(cls, tag: str) -> Tag:
|
|
49
51
|
"""
|
|
50
52
|
Creates a Tag object from a string.
|
|
51
53
|
|
albert/resources/tasks.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
from datetime import datetime
|
|
2
4
|
from enum import Enum
|
|
3
5
|
from typing import Annotated, Any, Literal
|
|
@@ -450,11 +452,6 @@ class TaskSearchItem(BaseAlbertModel, HydrationMixin[BaseTask]):
|
|
|
450
452
|
parent_batch_status: str | None = Field(default=None, alias="parentBatchStatus")
|
|
451
453
|
|
|
452
454
|
|
|
453
|
-
class ImportMode(str, Enum):
|
|
454
|
-
SCRIPT = "SCRIPT"
|
|
455
|
-
CSV = "CSV"
|
|
456
|
-
|
|
457
|
-
|
|
458
455
|
# TODO: refactor TaskMetadata models to reuse existing models where possible
|
|
459
456
|
class TaskMetadataDataTemplate(BaseAlbertModel):
|
|
460
457
|
"""Metadata summary describing a data template on the task."""
|
|
@@ -581,7 +578,7 @@ class CsvTableInput(BaseAlbertModel):
|
|
|
581
578
|
|
|
582
579
|
script_s3_url: str = Field(alias="scriptS3URL")
|
|
583
580
|
data_s3_url: str = Field(alias="dataS3URL")
|
|
584
|
-
task_metadata:
|
|
581
|
+
task_metadata: TaskMetadata = Field(alias="TaskMetadata")
|
|
585
582
|
|
|
586
583
|
|
|
587
584
|
class CsvTableResponseItem(BaseAlbertModel):
|
|
@@ -596,7 +593,7 @@ class CsvCurveInput(BaseAlbertModel):
|
|
|
596
593
|
script_s3_url: str = Field(alias="scriptS3URL")
|
|
597
594
|
data_s3_url: str = Field(alias="dataS3URL")
|
|
598
595
|
result_s3_url: str = Field(alias="resultS3URL")
|
|
599
|
-
task_metadata:
|
|
596
|
+
task_metadata: TaskMetadata = Field(alias="TaskMetadata")
|
|
600
597
|
|
|
601
598
|
|
|
602
599
|
class CsvCurveResponse(BaseAlbertModel):
|
albert/resources/workflows.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
from collections.abc import Mapping
|
|
2
4
|
from typing import Any
|
|
3
5
|
|
|
@@ -60,7 +62,7 @@ class Interval(BaseAlbertModel):
|
|
|
60
62
|
row_id: RowId | None = Field(default=None, alias="rowId", exclude=True)
|
|
61
63
|
|
|
62
64
|
@model_validator(mode="after")
|
|
63
|
-
def validate_interval(self) ->
|
|
65
|
+
def validate_interval(self) -> Interval:
|
|
64
66
|
if not self.value:
|
|
65
67
|
raise ValueError("Interval: 'value' is required.")
|
|
66
68
|
if self.unit and not getattr(self.unit, "id", None):
|
|
@@ -133,7 +135,7 @@ class ParameterSetpoint(BaseAlbertModel):
|
|
|
133
135
|
sequence: str | None = Field(default=None, alias="prgPrmRowId")
|
|
134
136
|
|
|
135
137
|
@model_validator(mode="after")
|
|
136
|
-
def validate_shape(self) ->
|
|
138
|
+
def validate_shape(self) -> ParameterSetpoint:
|
|
137
139
|
def has_id(obj: Any) -> bool:
|
|
138
140
|
if isinstance(obj, Mapping):
|
|
139
141
|
return bool(obj.get("id"))
|