cradle-sdk 0.1.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.
@@ -0,0 +1,11 @@
1
+ class ClientError(Exception):
2
+ def __init__(self, status_code: int, message: str, errors: list[str]):
3
+ self.status_code = status_code
4
+ self.message = message
5
+
6
+ message = f"API Error {status_code}: {message}"
7
+ if len(errors) > 0:
8
+ error_list = "\n".join(f"\t{error}" for error in errors)
9
+ message = f"{message}\n{error_list}"
10
+
11
+ super().__init__(message)
File without changes
@@ -0,0 +1,8 @@
1
+ from pydantic import BaseModel, Field
2
+
3
+
4
+ class AssemblyFeature(BaseModel):
5
+ ranges: dict[str, list[tuple[int, int]]] = Field(description="The ranges of the feature, keyed by polymer name")
6
+ metadata: dict[str, str | int | float | bool] | None = Field(
7
+ default=None, description="Optional metadata for the feature"
8
+ )
@@ -0,0 +1,62 @@
1
+ from datetime import datetime
2
+ from typing import Annotated, Literal
3
+
4
+ from pydantic import BaseModel, Field
5
+
6
+
7
+ class ListOptions(BaseModel):
8
+ limit: int = Field(default=100, description="Maximum number of items to return")
9
+ cursor: str | None = Field(default=None, description="Continuation token returned by the previous page's response")
10
+ order: Literal["ASC", "DESC"] = Field(
11
+ default="ASC", description="Whether to order the result ascending or descending"
12
+ )
13
+
14
+
15
+ class AbstractResourceResponse(BaseModel):
16
+ id: int = Field(description="The unique identifier of the resource")
17
+ created_at: datetime = Field(description="The time at which the resource was created")
18
+ created_by: str = Field(description="The ID of the user who created the resource")
19
+
20
+
21
+ class ResourceResponse(AbstractResourceResponse):
22
+ updated_at: datetime = Field(description="The time at which the resource was last updated")
23
+ updated_by: str = Field(description="The ID of the user who last updated the resource")
24
+
25
+
26
+ class ErrorResponseMixin(BaseModel):
27
+ """Mixin for resources that can return errors."""
28
+
29
+ errors: list[str] = Field(default_factory=list, description="List of error messages associated with the resource.")
30
+
31
+
32
+ class BaseListResponse(BaseModel):
33
+ items: list[AbstractResourceResponse] = Field(description="The listed resources.")
34
+ cursor: str | None = Field(
35
+ description="Cursor with which the next page of entries can be retrieved. If no cursor is returned, no further pages exist."
36
+ )
37
+
38
+
39
+ class ArchivableResourceMixin(BaseModel):
40
+ archived_at: datetime | None = Field(default=None, description="The time at which the resource was archived")
41
+ archived_by: str | None = Field(default=None, description="The ID of the user who archived the resource")
42
+
43
+
44
+ class ImmutableResourceResponse(AbstractResourceResponse):
45
+ pass
46
+
47
+
48
+ class ContextWorkspace(BaseModel):
49
+ kind: Literal["WORKSPACE"] = Field(default="WORKSPACE")
50
+
51
+
52
+ class ContextProject(BaseModel):
53
+ kind: Literal["PROJECT"] = Field(default="PROJECT")
54
+ project_id: int
55
+
56
+
57
+ class ContextRound(BaseModel):
58
+ kind: Literal["ROUND"] = Field(default="ROUND")
59
+ round_id: int
60
+
61
+
62
+ Context = Annotated[ContextWorkspace | ContextProject | ContextRound, Field(discriminator="kind")]
@@ -0,0 +1,353 @@
1
+ from enum import StrEnum
2
+ from typing import Annotated, Literal
3
+
4
+ from pydantic import BaseModel, Field
5
+
6
+ from .common import (
7
+ ArchivableResourceMixin,
8
+ BaseListResponse,
9
+ Context,
10
+ ContextProject,
11
+ ContextRound,
12
+ ErrorResponseMixin,
13
+ ImmutableResourceResponse,
14
+ ResourceResponse,
15
+ )
16
+
17
+
18
+ class QueryDataRequest(BaseModel):
19
+ query: str = Field(description="The SQL query to execute.")
20
+ arrow_compression: Literal["zstd", "lz4"] | None = Field(
21
+ default=None,
22
+ description="The compression algorithm to use for the Arrow response. Supported values are `zstd`, `lz4`, and `None`(meaning no compression).",
23
+ )
24
+ project_id: int | None = Field(
25
+ default=None, description="If set, the query will only run over data associated with the given `project_id`."
26
+ )
27
+ version_id: int | None = Field(
28
+ default=None,
29
+ description="If set, will run the query against the given version of the data according to the changelog.",
30
+ )
31
+
32
+
33
+ class DataActionKind(StrEnum):
34
+ LOAD = "LOAD"
35
+ UNDO_LOAD = "UNDO_LOAD"
36
+ TABLE_CREATE = "TABLE_CREATE"
37
+ TABLE_UPDATE = "TABLE_UPDATE"
38
+ TABLE_ARCHIVE = "TABLE_ARCHIVE"
39
+
40
+
41
+ class DataActionLoad(BaseModel):
42
+ kind: Literal[DataActionKind.LOAD] = Field(default=DataActionKind.LOAD)
43
+ load_id: int = Field(description="The ID of the data load from which data was added to the dataset.")
44
+
45
+
46
+ class DataActionUndoLoad(BaseModel):
47
+ kind: Literal[DataActionKind.UNDO_LOAD] = Field(default=DataActionKind.UNDO_LOAD)
48
+ load_id: int = Field(description="ID of the data load of which data was removed from the dataset.")
49
+
50
+
51
+ class DataActionTableCreate(BaseModel):
52
+ kind: Literal[DataActionKind.TABLE_CREATE] = Field(default=DataActionKind.TABLE_CREATE)
53
+ table_id: int = Field(description="The ID of the table that was created.")
54
+ table_version_id: int = Field(description="The ID of the table version that was created.")
55
+
56
+
57
+ class DataActionTableUpdate(BaseModel):
58
+ kind: Literal[DataActionKind.TABLE_UPDATE] = Field(default=DataActionKind.TABLE_UPDATE)
59
+ table_id: int = Field(description="The ID of the table that was updated.")
60
+ table_version_id: int = Field(description="The ID of the new table version.")
61
+
62
+
63
+ class DataActionTableArchive(BaseModel):
64
+ kind: Literal[DataActionKind.TABLE_ARCHIVE] = Field(default=DataActionKind.TABLE_ARCHIVE)
65
+ table_id: int = Field(description="The ID of the table that was archived.")
66
+
67
+
68
+ class DataVersionResponse(ImmutableResourceResponse):
69
+ action: (
70
+ DataActionLoad
71
+ | DataActionUndoLoad
72
+ | Annotated[DataActionTableCreate | DataActionTableUpdate | DataActionTableArchive, Field(discriminator="kind")]
73
+ ) = Field(discriminator="kind")
74
+
75
+
76
+ class ListDataVersionResponse(BaseListResponse):
77
+ items: list[DataVersionResponse]
78
+
79
+
80
+ class ArtifactProducerKind(StrEnum):
81
+ TASK = "TASK"
82
+ USER = "USER"
83
+
84
+
85
+ class TaskProducer(BaseModel):
86
+ kind: Literal[ArtifactProducerKind.TASK] = Field(default=ArtifactProducerKind.TASK)
87
+ task_id: int
88
+
89
+
90
+ class UserProducer(BaseModel):
91
+ kind: Literal[ArtifactProducerKind.USER] = Field(default=ArtifactProducerKind.USER)
92
+
93
+
94
+ class ArtifactResponse(ImmutableResourceResponse):
95
+ context: "Context" = Field(discriminator="kind")
96
+ type: Literal[
97
+ "protein_structure/v1",
98
+ "scorer/v1",
99
+ "report/v1",
100
+ "sampler/v1",
101
+ "biostats/v1",
102
+ "scorer.monomer/v2",
103
+ "scorer.vhvl/v2",
104
+ "sampler.monomer/v2",
105
+ "sampler.vhvl/v2",
106
+ "analysis_data.train/v1",
107
+ ]
108
+ producer: TaskProducer | UserProducer = Field(discriminator="kind")
109
+
110
+
111
+ class ListArtifactResponse(BaseListResponse):
112
+ items: list[ArtifactResponse]
113
+
114
+
115
+ class TableKind(StrEnum):
116
+ TABLE = "TABLE"
117
+ VIEW = "VIEW"
118
+
119
+
120
+ class ColumnMetadata(BaseModel):
121
+ description: str | None = Field(default=None)
122
+ deprecated: bool = Field(default=False)
123
+
124
+
125
+ class ColumnBase(BaseModel):
126
+ name: str
127
+ metadata: ColumnMetadata | None = Field(default=None)
128
+
129
+
130
+ class TypeNames(StrEnum):
131
+ BOOL = "BOOL"
132
+ INT64 = "INT64"
133
+ FLOAT64 = "FLOAT64"
134
+ STRING = "STRING"
135
+ STRUCT = "STRUCT"
136
+ ARRAY = "ARRAY"
137
+
138
+
139
+ class PrimitiveType(BaseModel):
140
+ type: Literal[TypeNames.BOOL, TypeNames.INT64, TypeNames.FLOAT64, TypeNames.STRING]
141
+
142
+
143
+ class PrimitiveColumn(ColumnBase, PrimitiveType):
144
+ """A column representing a primitive type."""
145
+
146
+ nullable: bool = Field(default=True)
147
+
148
+
149
+ class ArrayType(BaseModel):
150
+ type: Literal[TypeNames.ARRAY] = Field(default=TypeNames.ARRAY)
151
+ item_type: "ColumnType"
152
+
153
+
154
+ class ArrayColumn(ColumnBase, ArrayType):
155
+ """A column representing an array of elements.
156
+
157
+ Unlike the other column types it is not nullable but the array can be empty.
158
+ This matches BigQuery's behavior and reduces ambiguity.
159
+ """
160
+
161
+
162
+ class StructType(BaseModel):
163
+ type: Literal[TypeNames.STRUCT] = Field(default=TypeNames.STRUCT)
164
+ columns: list["Column"]
165
+
166
+
167
+ class StructColumn(ColumnBase, StructType):
168
+ """A column representing a struct of fields."""
169
+
170
+ nullable: bool = Field(default=True)
171
+
172
+
173
+ class TableResponseBase(ResourceResponse, ArchivableResourceMixin):
174
+ """Base class for table responses."""
175
+
176
+ kind: TableKind
177
+ reference: str = Field(
178
+ description="""A unique name to use for referring to the table, such as `temperature_assay`. User-created
179
+ tables should always use this simple `table_name` format. Cradle-created table references have the form
180
+ `catalog.schema.table_name`, for example `cradle.results.engineered_sequences`.
181
+
182
+ References must be unique per workspace. One exception to the rule is that once a table is archived the
183
+ refence is available to be used again. References are tied to a data version, i.e. when running a query
184
+ at a historic version, a reference will point to the table that held the reference at this data version."""
185
+ )
186
+ description: str | None
187
+ columns: list["Column"] = Field(
188
+ description="The columns of the table. For views, the columns and their types are inferred from the query at view creation or update time."
189
+ )
190
+ version_id: int = Field(
191
+ description="The version ID of the table state reflected in the response.Changes to a view's query or a base table's columns cause a version change as well as renames cause a version change."
192
+ )
193
+
194
+
195
+ class BaseTableResponse(TableResponseBase):
196
+ kind: Literal[TableKind.TABLE] = Field(default=TableKind.TABLE)
197
+
198
+
199
+ class ViewTableResponse(TableResponseBase):
200
+ kind: Literal[TableKind.VIEW] = Field(default=TableKind.VIEW)
201
+ query: str = Field(description="The SQL query that defines the view.")
202
+
203
+
204
+ class ListTableResponse(BaseListResponse):
205
+ items: list["TableResponse"]
206
+
207
+
208
+ class TableCreateBase(BaseModel):
209
+ kind: TableKind
210
+ reference: str = Field(
211
+ description="""A unique name to use for referring to the table, such as `temperature_assay`. User-created
212
+ tables should always use this simple `table_name` format. Cradle-created table references have the form
213
+ `catalog.schema.table_name`, for example `cradle.results.engineered_sequences`.
214
+
215
+ References must be unique per workspace. One exception to the rule is that once a table is archived the
216
+ refence is available to be used again. References are tied to a data version, i.e. when running a query
217
+ at a historic version, a reference will point to the table that held the reference at this data version."""
218
+ )
219
+ description: str | None = Field(default=None, description="A human-friendly description of the table's contents.")
220
+
221
+
222
+ class BaseTableCreate(TableCreateBase):
223
+ kind: Literal[TableKind.TABLE] = Field(
224
+ default=TableKind.TABLE,
225
+ description="""Whether to create a *table* or a *view*. Tables are created with the purpose of uploading data
226
+ to them, while views are created as queries on top of existing tables or views. Think of tables as physical
227
+ entities that store data, while views are virtual entities that represent a query result.
228
+ """,
229
+ )
230
+ columns: list["Column"] = Field(description="Columns of the table")
231
+
232
+
233
+ class ViewTableCreate(TableCreateBase):
234
+ kind: Literal[TableKind.VIEW] = Field(
235
+ default=TableKind.VIEW,
236
+ description="""Whether to create a *table* or a *view*. Tables are created with the purpose of uploading data
237
+ to them, while views are created as queries on top of existing tables or views. Think of tables as physical
238
+ entities that store data, while views are virtual entities that represent a query result.
239
+ """,
240
+ )
241
+ query: str = Field(
242
+ description="SQL query for the view. It must be a single SELECT statement with a limited, but still very powerful, subset of SQL. Subqueries, common table expressions, joins, and conditional expressions with all commonly used SQL operators are supported. Contact your customer success representative if you need to use a specific SQL feature that is not supported. If you have a query use case that is not covered by the currently permitted SQL expressions, contact support to discuss potential extensions."
243
+ )
244
+ columns: list["Column"] | None = Field(
245
+ default=None,
246
+ description="Columns of the view. The column schema must match the query's result schema. If unspecified, a schema is automatically inferred from the query and column metadata will be copied over from the existing schema if the column already existed.",
247
+ )
248
+
249
+
250
+ class TableRename(BaseModel):
251
+ new_reference: str = Field(
252
+ description="""A unique name to use for referring to the table, such as `temperature_assay`. User-created
253
+ tables should always use this simple `table_name` format. Cradle-created table references have the form
254
+ `catalog.schema.table_name`, for example `cradle.results.engineered_sequences`.
255
+
256
+ References must be unique per workspace. One exception to the rule is that once a table is archived the
257
+ refence is available to be used again. References are tied to a data version, i.e. when running a query
258
+ at a historic version, a reference will point to the table that held the reference at this data version."""
259
+ )
260
+
261
+
262
+ class _TableUpdateBase(BaseModel):
263
+ description: str | None = Field(default=None, description="Description of the table.")
264
+
265
+
266
+ class BaseTableUpdate(_TableUpdateBase):
267
+ kind: Literal[TableKind.TABLE] = Field(default=TableKind.TABLE)
268
+ columns: list["Column"] | None = Field(default=None, description="Columns of the table.")
269
+
270
+
271
+ class ViewTableUpdate(_TableUpdateBase):
272
+ kind: Literal[TableKind.VIEW] = Field(default=TableKind.VIEW)
273
+ query: str | None = Field(
274
+ default=None,
275
+ description="SQL query for the view. It must be a single SELECT statement and only a subset of SQL is allowed. If unspecified, no change is made to the view query.If you have a query use case that is not covered by the currently permitted SQL expressions, contact support to discuss potential extensions.",
276
+ )
277
+ columns: list["Column"] | None = Field(
278
+ default=None,
279
+ description="Columns of the view. The column schema must match the query's result schema. If unspecified, a schema is automatically inferred from the query and column metadata will be copied over from the existing schema if the column already existed.",
280
+ )
281
+
282
+
283
+ class TableArchive(BaseModel):
284
+ pass
285
+
286
+
287
+ class FileFormat(StrEnum):
288
+ CSV = "CSV"
289
+ PARQUET = "PARQUET"
290
+ NDJSON = "NDJSON"
291
+
292
+
293
+ class TableLoadConfig(BaseModel):
294
+ columns: list["Column"] = Field(
295
+ description="The column layout of the files. All files in the data load destined for this table must have this exact column layout. For CSV files, only the specified columns determine how data is loaded. The first row (header) in each uploaded file is skipped. For Parquet files, columns will be matched by name and are thus not order-sensitive. Therefore it is recommended to use Parquet files for more robust data loading."
296
+ )
297
+ format: FileFormat
298
+
299
+
300
+ class DataLoadCreate(BaseModel):
301
+ context: ContextProject | ContextRound = Field(
302
+ description="The context the loaded data will be associated with. The data will either live within a Project (visible to all rounds) or within a specific Round of a project (visible only to that round)."
303
+ )
304
+ tables: dict[str, TableLoadConfig] = Field(
305
+ default_factory=dict,
306
+ description="A map of table references to table schemas. The map keys define the tables for which data is uploaded. The map values define the schema and file format for a given table.",
307
+ )
308
+
309
+
310
+ class TableLoadConfigResponse(TableLoadConfig):
311
+ table_id: int | None = Field(
312
+ description="The table the rows were loaded into. This is the table addressed by the table reference for this configuration at the time of finalization."
313
+ )
314
+
315
+
316
+ class DataLoadState(StrEnum):
317
+ PENDING = "PENDING"
318
+ LOADING = "LOADING"
319
+ DELETING = "DELETING"
320
+ COMPLETED = "COMPLETED"
321
+ FAILED = "FAILED"
322
+
323
+
324
+ class FileUploadResponse(ImmutableResourceResponse):
325
+ filepath: str
326
+ size: int
327
+ table_reference: str | None
328
+ source_file_id: int | None
329
+ description: str | None
330
+
331
+
332
+ class DataLoadResponse(ResourceResponse, ErrorResponseMixin):
333
+ context: "Context" = Field(description="The context the loaded data is be associated with", discriminator="kind")
334
+ tables: dict[str, TableLoadConfigResponse] = Field(
335
+ default_factory=dict, description="The tables for which data will be loaded."
336
+ )
337
+ state: DataLoadState
338
+ is_active: bool
339
+ files: list[FileUploadResponse] = Field(description="Files that have been uploaded to this data load.")
340
+
341
+
342
+ class AddTableRequest(BaseModel):
343
+ table_ref: str
344
+ config: TableLoadConfig
345
+
346
+
347
+ class ListDataLoadResponse(BaseListResponse):
348
+ items: list[DataLoadResponse]
349
+
350
+
351
+ Column = Annotated[PrimitiveColumn | StructColumn | ArrayColumn, Field(discriminator="type")]
352
+ ColumnType = Annotated[PrimitiveType | StructType | ArrayType, Field(discriminator="type")]
353
+ TableResponse = Annotated[BaseTableResponse | ViewTableResponse, Field(discriminator="kind")]