benchling-sdk 1.18.1__py3-none-any.whl → 1.19.0__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.
- benchling_sdk/helpers/client_helpers.py +5 -0
- benchling_sdk/helpers/task_helpers.py +145 -0
- benchling_sdk/services/v2/alpha/v2_alpha_assembly_service.py +6 -4
- benchling_sdk/services/v2/base_service.py +11 -0
- benchling_sdk/services/v2/beta/v2_beta_audit_service.py +18 -13
- benchling_sdk/services/v2/beta/v2_beta_data_frame_service.py +9 -9
- benchling_sdk/services/v2/stable/aa_sequence_service.py +23 -13
- benchling_sdk/services/v2/stable/app_service.py +4 -2
- benchling_sdk/services/v2/stable/assay_result_service.py +3 -3
- benchling_sdk/services/v2/stable/container_service.py +14 -7
- benchling_sdk/services/v2/stable/custom_entity_service.py +15 -7
- benchling_sdk/services/v2/stable/dna_alignments_service.py +9 -5
- benchling_sdk/services/v2/stable/dna_oligo_service.py +13 -7
- benchling_sdk/services/v2/stable/dna_sequence_service.py +28 -19
- benchling_sdk/services/v2/stable/export_service.py +4 -4
- benchling_sdk/services/v2/stable/feature_library_service.py +6 -3
- benchling_sdk/services/v2/stable/lab_automation_service.py +5 -5
- benchling_sdk/services/v2/stable/nucleotide_alignments_service.py +5 -5
- benchling_sdk/services/v2/stable/oligo_service.py +4 -3
- benchling_sdk/services/v2/stable/registry_service.py +3 -3
- benchling_sdk/services/v2/stable/rna_oligo_service.py +13 -7
- benchling_sdk/services/v2/stable/rna_sequence_service.py +17 -11
- benchling_sdk/services/v2/stable/task_service.py +4 -0
- {benchling_sdk-1.18.1.dist-info → benchling_sdk-1.19.0.dist-info}/METADATA +2 -2
- {benchling_sdk-1.18.1.dist-info → benchling_sdk-1.19.0.dist-info}/RECORD +27 -26
- {benchling_sdk-1.18.1.dist-info → benchling_sdk-1.19.0.dist-info}/LICENSE +0 -0
- {benchling_sdk-1.18.1.dist-info → benchling_sdk-1.19.0.dist-info}/WHEEL +0 -0
@@ -11,6 +11,11 @@ def replace_client_path(client: Client, base_path: str) -> Client:
|
|
11
11
|
return client.with_base_url(updated_url.geturl())
|
12
12
|
|
13
13
|
|
14
|
+
def v2_stable_client(client: Client) -> Client:
|
15
|
+
"""Override a client's base URL with a v2 stable path."""
|
16
|
+
return replace_client_path(client, "api/v2")
|
17
|
+
|
18
|
+
|
14
19
|
def v2_alpha_client(client: Client) -> Client:
|
15
20
|
"""Override a client's base URL with a v2-alpha path."""
|
16
21
|
return replace_client_path(client, "api/v2-alpha")
|
@@ -0,0 +1,145 @@
|
|
1
|
+
from dataclasses import dataclass
|
2
|
+
from typing import Any, cast, Generic, Optional, Type, TypeVar
|
3
|
+
|
4
|
+
from benchling_api_client.v2.stable.client import Client
|
5
|
+
|
6
|
+
from benchling_sdk.helpers.serialization_helpers import unset_as_none
|
7
|
+
from benchling_sdk.models import AsyncTaskErrors, AsyncTaskLink, AsyncTaskStatus
|
8
|
+
|
9
|
+
ResponseT = TypeVar("ResponseT")
|
10
|
+
|
11
|
+
|
12
|
+
@dataclass
|
13
|
+
class TaskCompletion(Generic[ResponseT]):
|
14
|
+
"""Return type for TaskHelper.wait_for_task, same as AsyncTask but with a typed response."""
|
15
|
+
|
16
|
+
success: bool
|
17
|
+
errors: Optional[AsyncTaskErrors] = None
|
18
|
+
message: Optional[str] = None
|
19
|
+
response: Optional[ResponseT] = None
|
20
|
+
|
21
|
+
|
22
|
+
@dataclass
|
23
|
+
class TaskFailureException(Exception):
|
24
|
+
"""Exception type used by :py:class:`.TaskHelper` methods."""
|
25
|
+
|
26
|
+
errors: AsyncTaskErrors
|
27
|
+
message: Optional[str]
|
28
|
+
|
29
|
+
|
30
|
+
class EmptyTaskResponse:
|
31
|
+
"""A sentinel object used for tasks that do not return any response data on completion."""
|
32
|
+
|
33
|
+
pass
|
34
|
+
|
35
|
+
|
36
|
+
EMPTY_TASK_RESPONSE = EmptyTaskResponse()
|
37
|
+
|
38
|
+
|
39
|
+
class TaskHelper(AsyncTaskLink, Generic[ResponseT]):
|
40
|
+
"""Used by Benchling async task endpoints to provide the task response in an appropriate type.
|
41
|
+
|
42
|
+
In the API spec, endpoints that create a long-running task are defined as returning an
|
43
|
+
:py:class:`benchling_sdk.models.AsyncTaskLink`, which can be used with
|
44
|
+
:py:class:`benchling_sdk.services.v2.stable.TaskService` to query the task status and
|
45
|
+
response. But AsyncTaskLink and the task query endpoint do not define a specific schema
|
46
|
+
for the task response.
|
47
|
+
|
48
|
+
To work around that limitation, those SDK endpoints now return a TaskHelper instead. This is
|
49
|
+
subclassed from AsyncTaskLink for backward compatibility, but unlike AsyncTaskLink, TaskHelper
|
50
|
+
knows what the type of the task response should be. It also retains an association with the API
|
51
|
+
client, so rather than calling a separate service method, you can simply call
|
52
|
+
:py:meth:`.TaskHelper.wait_for_completion` or :py:meth:`.TaskHelper.wait_for_response`.
|
53
|
+
|
54
|
+
You can access a task for up to 30 minutes after its completion, after which its data will no
|
55
|
+
longer be available.
|
56
|
+
"""
|
57
|
+
|
58
|
+
_client: Client
|
59
|
+
_response_class: Type[ResponseT]
|
60
|
+
_response_decoder: Any
|
61
|
+
# _response_decoder is really a Callable, but adding that type hint would cause problems because
|
62
|
+
# mypy would treat it as an instance method and assume it should have a self parameter.
|
63
|
+
|
64
|
+
def __init__(self, from_task_link: AsyncTaskLink, client: Client, response_class: Type[ResponseT]):
|
65
|
+
"""Initialize the instance. This should only be used internally by Benchling API methods."""
|
66
|
+
self.task_id = from_task_link.task_id
|
67
|
+
self.additional_properties = from_task_link.additional_properties
|
68
|
+
self._client = client
|
69
|
+
self._response_class = response_class
|
70
|
+
|
71
|
+
if response_class is not EmptyTaskResponse:
|
72
|
+
assert hasattr(response_class, "from_dict")
|
73
|
+
self._response_decoder = getattr(response_class, "from_dict")
|
74
|
+
|
75
|
+
def wait_for_completion(
|
76
|
+
self, interval_wait_seconds: int = 1, max_wait_seconds: int = 600
|
77
|
+
) -> TaskCompletion[ResponseT]:
|
78
|
+
"""Wait for the task to succeed or fail.
|
79
|
+
|
80
|
+
This is equivalent to the :py:meth:`benchling_sdk.services.v2.stable.task_service.TaskService.wait_for_task`
|
81
|
+
method in :py:class:`benchling_sdk.services.v2.stable.task_service.TaskService`, except that
|
82
|
+
instead of returning an :py:class:`benchling_sdk.models.AsyncTask` whose `response` property is
|
83
|
+
a dict, it returns a :py:class:`TaskCompletion` whose `response` property is the appropriate type
|
84
|
+
for the API method you called. For instance, if the method was `AaSequenceService.bulk_create`,
|
85
|
+
the response type will be :py:class:`benchling_sdk.models.BulkCreateAaSequencesAsyncTaskResponse`.
|
86
|
+
|
87
|
+
:param interval_wait_seconds: time to wait between API calls in seconds
|
88
|
+
:param max_wait_seconds: maximum wait time in seconds before raising an error
|
89
|
+
:return: The task completion status. Check `status` for success or failure
|
90
|
+
:rtype: TaskCompletion
|
91
|
+
:raises benchling_sdk.errors.WaitForTaskExpiredError: if the maximum wait time has elapsed
|
92
|
+
"""
|
93
|
+
from benchling_sdk.helpers.client_helpers import v2_stable_client
|
94
|
+
from benchling_sdk.services.v2.stable.task_service import TaskService
|
95
|
+
|
96
|
+
# The "get task" polling endpoint is part of the v2 stable API; it doesn't exist in alpha or beta.
|
97
|
+
task_service = TaskService(v2_stable_client(self._client))
|
98
|
+
|
99
|
+
task = task_service.wait_for_task(
|
100
|
+
self.task_id, interval_wait_seconds=interval_wait_seconds, max_wait_seconds=max_wait_seconds
|
101
|
+
)
|
102
|
+
response: Optional[ResponseT]
|
103
|
+
if task.status != AsyncTaskStatus.SUCCEEDED:
|
104
|
+
response = None
|
105
|
+
elif self._response_class is EmptyTaskResponse:
|
106
|
+
response = cast(ResponseT, EMPTY_TASK_RESPONSE)
|
107
|
+
else:
|
108
|
+
response = self._response_decoder(task.response.to_dict())
|
109
|
+
errors = None if task.status != AsyncTaskStatus.FAILED else unset_as_none(task.errors)
|
110
|
+
message = None if task.status != AsyncTaskStatus.FAILED else unset_as_none(task.message)
|
111
|
+
return TaskCompletion(
|
112
|
+
success=task.status == AsyncTaskStatus.SUCCEEDED,
|
113
|
+
errors=errors,
|
114
|
+
message=message,
|
115
|
+
response=response,
|
116
|
+
)
|
117
|
+
|
118
|
+
def wait_for_response(self, interval_wait_seconds: int = 1, max_wait_seconds: int = 600) -> ResponseT:
|
119
|
+
"""Wait for the task and return the response object on success, or raise an exception on failure.
|
120
|
+
|
121
|
+
This is a convenience method for calling :py:meth:`wait_for_completion` and then getting the
|
122
|
+
`response` property of the returned object if the task succeeded, in cases where you're not
|
123
|
+
interested in any :py:class:`.TaskCompletion` properties except the response.
|
124
|
+
|
125
|
+
The type of the returned object is depends on the API method you called. For instance, if the
|
126
|
+
method was `AaSequenceService.bulk_create`, the response type will be
|
127
|
+
:py:class:`benchling_sdk.models.BulkCreateAaSequencesAsyncTaskResponse`.
|
128
|
+
|
129
|
+
:param interval_wait_seconds: time to wait between API calls in seconds
|
130
|
+
:param max_wait_seconds: maximum wait time in seconds before raising an error
|
131
|
+
:return: The response object, if the task succeeded.
|
132
|
+
:rtype: ResponseT
|
133
|
+
:raises benchling_sdk.errors.WaitForTaskExpiredError: if the maximum wait time has elapsed
|
134
|
+
:raises .TaskFailureException: if the task failed
|
135
|
+
"""
|
136
|
+
task_completion = self.wait_for_completion(interval_wait_seconds, max_wait_seconds)
|
137
|
+
if not task_completion.success:
|
138
|
+
raise TaskFailureException(task_completion.errors or AsyncTaskErrors(), task_completion.message)
|
139
|
+
assert task_completion.response, "completed task should have contained a response"
|
140
|
+
# This assertion matches the behavior of TaskHelper.wait_for_completion(): response is only set
|
141
|
+
# to None if the task failed, otherwise it should always be an object even if that object is an
|
142
|
+
# EmptyTaskResponse. This also matches how we define async task models in the API spec, where
|
143
|
+
# if we don't care about the response field, it's an empty object rather than null.
|
144
|
+
|
145
|
+
return task_completion.response
|
@@ -11,6 +11,7 @@ from benchling_api_client.v2.alpha.models.create_and_finalize_assembly_json_body
|
|
11
11
|
|
12
12
|
from benchling_sdk.helpers.decorators import api_method
|
13
13
|
from benchling_sdk.helpers.response_helpers import model_from_detailed
|
14
|
+
from benchling_sdk.helpers.task_helpers import TaskHelper
|
14
15
|
from benchling_sdk.models import AsyncTaskLink
|
15
16
|
from benchling_sdk.services.v2.base_service import BaseService
|
16
17
|
|
@@ -36,17 +37,18 @@ class V2AlphaAssemblyService(BaseService):
|
|
36
37
|
return model_from_detailed(response)
|
37
38
|
|
38
39
|
@api_method
|
39
|
-
def create_and_finalize(self, create: CreateAndFinalizeAssemblyJsonBody) ->
|
40
|
+
def create_and_finalize(self, create: CreateAndFinalizeAssemblyJsonBody) -> TaskHelper[Assembly]:
|
40
41
|
"""
|
41
42
|
Create and finalize a new bulk assembly in a single step.
|
42
43
|
|
43
|
-
This endpoint launches a long-running task and returns
|
44
|
-
|
44
|
+
This endpoint launches a long-running task and returns a
|
45
|
+
:py:class:`benchling_sdk.helpers.task_helpers.TaskHelper` for waiting on the task.
|
46
|
+
On success, the task's response will be an :py:class:`.Assembly`.
|
45
47
|
|
46
48
|
See https://benchling.com/api/v2-alpha/reference#/Assemblies/CreateAndFinalizeAssembly
|
47
49
|
"""
|
48
50
|
response = create_and_finalize_assembly.sync_detailed(client=self.client, json_body=create)
|
49
|
-
return
|
51
|
+
return self._task_helper_from_response(response, Assembly)
|
50
52
|
|
51
53
|
@api_method
|
52
54
|
def validate(self, assembly: AssemblySpecShared) -> AsyncTaskLink:
|
@@ -1,9 +1,15 @@
|
|
1
1
|
from abc import ABC
|
2
|
+
from typing import Type, TYPE_CHECKING
|
2
3
|
|
3
4
|
from benchling_api_client.v2.stable.client import Client
|
5
|
+
from benchling_api_client.v2.types import Response
|
4
6
|
|
7
|
+
from benchling_sdk.helpers.response_helpers import model_from_detailed
|
5
8
|
from benchling_sdk.helpers.retry_helpers import RetryStrategy
|
6
9
|
|
10
|
+
if TYPE_CHECKING:
|
11
|
+
from benchling_sdk.helpers.task_helpers import TaskHelper
|
12
|
+
|
7
13
|
|
8
14
|
class BaseService(ABC):
|
9
15
|
"""Abstract class for Benchling functional namespaces."""
|
@@ -37,3 +43,8 @@ class BaseService(ABC):
|
|
37
43
|
Override this in alpha and beta services that use a client other than self._client.
|
38
44
|
"""
|
39
45
|
return cls(self._client, self._retry_strategy)
|
46
|
+
|
47
|
+
def _task_helper_from_response(self, response: Response, result_type: Type) -> "TaskHelper":
|
48
|
+
from benchling_sdk.helpers.task_helpers import TaskHelper
|
49
|
+
|
50
|
+
return TaskHelper(model_from_detailed(response), self.client, result_type)
|
@@ -2,8 +2,8 @@ from benchling_api_client.v2.beta.api.audit import audit_log
|
|
2
2
|
from benchling_api_client.v2.beta.models.audit_log_export import AuditLogExport
|
3
3
|
|
4
4
|
from benchling_sdk.helpers.decorators import api_method
|
5
|
-
from benchling_sdk.helpers.
|
6
|
-
from benchling_sdk.models import
|
5
|
+
from benchling_sdk.helpers.task_helpers import TaskHelper
|
6
|
+
from benchling_sdk.models import ExportAuditLogAsyncTaskResponse
|
7
7
|
from benchling_sdk.services.v2.base_service import BaseService
|
8
8
|
|
9
9
|
|
@@ -17,25 +17,30 @@ class V2BetaAuditService(BaseService):
|
|
17
17
|
"""
|
18
18
|
|
19
19
|
@api_method
|
20
|
-
def get_audit_log(
|
20
|
+
def get_audit_log(
|
21
|
+
self, object_id: str, export: AuditLogExport
|
22
|
+
) -> TaskHelper[ExportAuditLogAsyncTaskResponse]:
|
21
23
|
"""
|
22
24
|
Export an audit log file for a Benchling object.
|
23
25
|
|
24
|
-
This endpoint launches a long-running task and returns
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
26
|
+
This endpoint launches a long-running task and returns a
|
27
|
+
:py:class:`benchling_sdk.helpers.task_helpers.TaskHelper`. On success, the task's
|
28
|
+
response will be an :py:class:`.ExportAuditLogAsyncTaskResponse` containing a link to
|
29
|
+
download the exported audit log file from Amazon S3.
|
30
|
+
|
31
|
+
This endpoint is subject to a rate limit of 500 requests per hour, in conjunction with
|
32
|
+
the global request rate limit. Export throughput will additionally be rate limited around
|
33
|
+
the scale of 70,000 total audit events exported in csv format or 30,000 total audit events
|
34
|
+
exported in pdf format per hour.
|
30
35
|
|
31
36
|
Example of submitting an export request and then getting the download URL from
|
32
37
|
the completed task:
|
33
38
|
|
34
|
-
|
35
|
-
|
36
|
-
url =
|
39
|
+
task = benchling.v2.beta.audit.get_audit_log(object_id, export)
|
40
|
+
task_result = task.wait_for_response()
|
41
|
+
url = task_result.download_url
|
37
42
|
|
38
43
|
See https://benchling.com/api/v2-beta/reference#/Audit/auditLog
|
39
44
|
"""
|
40
45
|
response = audit_log.sync_detailed(client=self.client, object_id=object_id, json_body=export)
|
41
|
-
return
|
46
|
+
return self._task_helper_from_response(response, ExportAuditLogAsyncTaskResponse)
|
@@ -19,7 +19,7 @@ import httpx
|
|
19
19
|
from benchling_sdk.errors import DataFrameInProgressError, InvalidDataFrameError, raise_for_status
|
20
20
|
from benchling_sdk.helpers.decorators import api_method
|
21
21
|
from benchling_sdk.helpers.response_helpers import model_from_detailed
|
22
|
-
from benchling_sdk.
|
22
|
+
from benchling_sdk.helpers.task_helpers import TaskHelper
|
23
23
|
from benchling_sdk.services.v2.base_service import BaseService
|
24
24
|
|
25
25
|
_DEFAULT_HTTP_TIMEOUT_UPLOAD_DATA_FRAME: float = 60.0
|
@@ -55,7 +55,7 @@ class V2BetaDataFrameService(BaseService):
|
|
55
55
|
return model_from_detailed(response)
|
56
56
|
|
57
57
|
@api_method
|
58
|
-
def update(self, data_frame_id: str, data_frame: DataFrameUpdate) ->
|
58
|
+
def update(self, data_frame_id: str, data_frame: DataFrameUpdate) -> TaskHelper[DataFrame]:
|
59
59
|
"""
|
60
60
|
Update a data frame.
|
61
61
|
|
@@ -64,7 +64,7 @@ class V2BetaDataFrameService(BaseService):
|
|
64
64
|
response = patch_data_frame.sync_detailed(
|
65
65
|
client=self.client, data_frame_id=data_frame_id, json_body=data_frame
|
66
66
|
)
|
67
|
-
return
|
67
|
+
return self._task_helper_from_response(response, DataFrame)
|
68
68
|
|
69
69
|
def upload_bytes(
|
70
70
|
self,
|
@@ -114,15 +114,15 @@ class V2BetaDataFrameService(BaseService):
|
|
114
114
|
data_frame: DataFrameCreate,
|
115
115
|
input_bytes: Union[BytesIO, bytes],
|
116
116
|
timeout_seconds: float = _DEFAULT_HTTP_TIMEOUT_UPLOAD_DATA_FRAME,
|
117
|
-
) ->
|
117
|
+
) -> TaskHelper[DataFrame]:
|
118
118
|
"""Create a data frame from bytes or BytesIO data.
|
119
119
|
|
120
120
|
:param data_frame: The DataFrameCreate specification for the data. This must be provided, as it cannot be inferred from file names.
|
121
121
|
:param input_bytes: Data to upload as bytes or BytesIO
|
122
122
|
:param timeout_seconds: Extends the normal HTTP timeout settings since DataFrame uploads can be large
|
123
123
|
Use this to extend even further if streams are very large
|
124
|
-
:return:
|
125
|
-
:rtype:
|
124
|
+
:return: A TaskHelper that can be polled to know when the data frame has completed processing
|
125
|
+
:rtype: TaskHelper[DataFrame]
|
126
126
|
"""
|
127
127
|
# This is a current limit of the DataFrame API. We may need additional methods in the future
|
128
128
|
# to allow multi upload
|
@@ -150,15 +150,15 @@ class V2BetaDataFrameService(BaseService):
|
|
150
150
|
file: Path,
|
151
151
|
data_frame: Optional[DataFrameCreate] = None,
|
152
152
|
timeout_seconds: float = _DEFAULT_HTTP_TIMEOUT_UPLOAD_DATA_FRAME,
|
153
|
-
) ->
|
153
|
+
) -> TaskHelper[DataFrame]:
|
154
154
|
"""Create a data frame from file data.
|
155
155
|
|
156
156
|
:param file: A valid Path to an existing file containing the data to upload
|
157
157
|
:param data_frame: The DataFrameCreate specification for the data. If not provided, it will be inferred from the file name
|
158
158
|
:param timeout_seconds: Extends the normal HTTP timeout settings since DataFrame uploads can be large
|
159
159
|
Use this to extend even further if streams are very large
|
160
|
-
:return:
|
161
|
-
:rtype:
|
160
|
+
:return: A TaskHelper that can be polled to know when the data frame has completed processing
|
161
|
+
:rtype: TaskHelper[DataFrame]
|
162
162
|
"""
|
163
163
|
if file.is_dir():
|
164
164
|
raise IsADirectoryError(
|
@@ -32,6 +32,7 @@ from benchling_sdk.helpers.serialization_helpers import (
|
|
32
32
|
optional_array_query_param,
|
33
33
|
schema_fields_query_param,
|
34
34
|
)
|
35
|
+
from benchling_sdk.helpers.task_helpers import EmptyTaskResponse, TaskHelper
|
35
36
|
from benchling_sdk.models import (
|
36
37
|
AaSequence,
|
37
38
|
AaSequenceBulkCreate,
|
@@ -49,10 +50,13 @@ from benchling_sdk.models import (
|
|
49
50
|
AaSequencesUnarchive,
|
50
51
|
AaSequenceUpdate,
|
51
52
|
AaSequenceUpsert,
|
52
|
-
AsyncTaskLink,
|
53
53
|
AutoAnnotateAaSequences,
|
54
54
|
BackTranslate,
|
55
|
+
BulkCreateAaSequencesAsyncTaskResponse,
|
56
|
+
BulkCreateDnaSequencesAsyncTaskResponse,
|
57
|
+
BulkUpdateAaSequencesAsyncTaskResponse,
|
55
58
|
EntityArchiveReason,
|
59
|
+
FindMatchingRegionsAsyncTaskResponse,
|
56
60
|
ListAASequencesSort,
|
57
61
|
)
|
58
62
|
from benchling_sdk.services.v2.base_service import BaseService
|
@@ -264,7 +268,9 @@ class AaSequenceService(BaseService):
|
|
264
268
|
return aa_sequences_results.aa_sequences
|
265
269
|
|
266
270
|
@api_method
|
267
|
-
def bulk_create(
|
271
|
+
def bulk_create(
|
272
|
+
self, aa_sequences: Iterable[AaSequenceBulkCreate]
|
273
|
+
) -> TaskHelper[BulkCreateAaSequencesAsyncTaskResponse]:
|
268
274
|
"""
|
269
275
|
Bulk create AA sequences.
|
270
276
|
|
@@ -272,10 +278,12 @@ class AaSequenceService(BaseService):
|
|
272
278
|
"""
|
273
279
|
body = AaSequencesBulkCreateRequest(list(aa_sequences))
|
274
280
|
response = bulk_create_aa_sequences.sync_detailed(client=self.client, json_body=body)
|
275
|
-
return
|
281
|
+
return self._task_helper_from_response(response, BulkCreateAaSequencesAsyncTaskResponse)
|
276
282
|
|
277
283
|
@api_method
|
278
|
-
def bulk_update(
|
284
|
+
def bulk_update(
|
285
|
+
self, aa_sequences: Iterable[AaSequenceBulkUpdate]
|
286
|
+
) -> TaskHelper[BulkUpdateAaSequencesAsyncTaskResponse]:
|
279
287
|
"""
|
280
288
|
Bulk update AA sequences.
|
281
289
|
|
@@ -283,17 +291,17 @@ class AaSequenceService(BaseService):
|
|
283
291
|
"""
|
284
292
|
body = AaSequencesBulkUpdateRequest(list(aa_sequences))
|
285
293
|
response = bulk_update_aa_sequences.sync_detailed(client=self.client, json_body=body)
|
286
|
-
return
|
294
|
+
return self._task_helper_from_response(response, BulkUpdateAaSequencesAsyncTaskResponse)
|
287
295
|
|
288
296
|
@api_method
|
289
|
-
def auto_annotate(self, auto_annotate: AutoAnnotateAaSequences) ->
|
297
|
+
def auto_annotate(self, auto_annotate: AutoAnnotateAaSequences) -> TaskHelper[EmptyTaskResponse]:
|
290
298
|
"""
|
291
299
|
Auto-annotate AA sequences with matching features from specified Feature Libraries.
|
292
300
|
|
293
301
|
See https://benchling.com/api/reference#/AA%20Sequences/autoAnnotateAaSequences
|
294
302
|
"""
|
295
303
|
response = auto_annotate_aa_sequences.sync_detailed(client=self.client, json_body=auto_annotate)
|
296
|
-
return
|
304
|
+
return self._task_helper_from_response(response, EmptyTaskResponse)
|
297
305
|
|
298
306
|
@api_method
|
299
307
|
def upsert(self, entity_registry_id: str, aa_sequence: AaSequenceUpsert) -> AaSequence:
|
@@ -310,7 +318,7 @@ class AaSequenceService(BaseService):
|
|
310
318
|
@api_method
|
311
319
|
def bulk_upsert(
|
312
320
|
self, body: AaSequencesBulkUpsertRequest, returning: Optional[Iterable[str]] = None
|
313
|
-
) ->
|
321
|
+
) -> TaskHelper[BulkUpdateAaSequencesAsyncTaskResponse]:
|
314
322
|
"""
|
315
323
|
Bulk create or update AA sequences.
|
316
324
|
|
@@ -320,10 +328,12 @@ class AaSequenceService(BaseService):
|
|
320
328
|
response = bulk_upsert_aa_sequences.sync_detailed(
|
321
329
|
client=self.client, json_body=body, returning=none_as_unset(returning_string)
|
322
330
|
)
|
323
|
-
return
|
331
|
+
return self._task_helper_from_response(response, BulkUpdateAaSequencesAsyncTaskResponse)
|
324
332
|
|
325
333
|
@api_method
|
326
|
-
def find_matching_regions(
|
334
|
+
def find_matching_regions(
|
335
|
+
self, find_matching_region: AaSequencesFindMatchingRegion
|
336
|
+
) -> TaskHelper[FindMatchingRegionsAsyncTaskResponse]:
|
327
337
|
"""
|
328
338
|
Find matching regions for AA sequences.
|
329
339
|
|
@@ -332,17 +342,17 @@ class AaSequenceService(BaseService):
|
|
332
342
|
response = find_matching_regions_aa_sequences.sync_detailed(
|
333
343
|
client=self.client, json_body=find_matching_region
|
334
344
|
)
|
335
|
-
return
|
345
|
+
return self._task_helper_from_response(response, FindMatchingRegionsAsyncTaskResponse)
|
336
346
|
|
337
347
|
@api_method
|
338
|
-
def back_translate(self, translate: BackTranslate) ->
|
348
|
+
def back_translate(self, translate: BackTranslate) -> TaskHelper[BulkCreateDnaSequencesAsyncTaskResponse]:
|
339
349
|
"""
|
340
350
|
Create back-translated DNA sequences from AA sequences.
|
341
351
|
|
342
352
|
See https://benchling.com/api/v2/reference#/AA%20Sequences/backTranslate
|
343
353
|
"""
|
344
354
|
response = back_translate.sync_detailed(client=self.client, json_body=translate)
|
345
|
-
return
|
355
|
+
return self._task_helper_from_response(response, BulkCreateDnaSequencesAsyncTaskResponse)
|
346
356
|
|
347
357
|
@api_method
|
348
358
|
def _match_bases_page(self, match_bases: AaSequencesMatchBases) -> Response[AaSequencesPaginatedList]:
|
@@ -442,7 +442,7 @@ class AppService(BaseService):
|
|
442
442
|
# return PageIterator(api_call, results_extractor)
|
443
443
|
|
444
444
|
@api_method
|
445
|
-
def get_canvas_by_id(self, canvas_id: str) -> AppCanvas:
|
445
|
+
def get_canvas_by_id(self, canvas_id: str, returning: Optional[List[str]] = None) -> AppCanvas:
|
446
446
|
"""
|
447
447
|
Get the current state of the App Canvas, including user input elements.
|
448
448
|
|
@@ -451,6 +451,7 @@ class AppService(BaseService):
|
|
451
451
|
response = get_app_canvas.sync_detailed(
|
452
452
|
client=self.client,
|
453
453
|
canvas_id=canvas_id,
|
454
|
+
returning=none_as_unset(optional_array_query_param(returning)),
|
454
455
|
)
|
455
456
|
return model_from_detailed(response)
|
456
457
|
|
@@ -511,7 +512,7 @@ class AppService(BaseService):
|
|
511
512
|
return model_from_detailed(response)
|
512
513
|
|
513
514
|
@api_method
|
514
|
-
def get_session_by_id(self, session_id: str) -> AppSession:
|
515
|
+
def get_session_by_id(self, session_id: str, returning: Optional[List[str]] = None) -> AppSession:
|
515
516
|
"""
|
516
517
|
Get a Benchling App session.
|
517
518
|
|
@@ -520,6 +521,7 @@ class AppService(BaseService):
|
|
520
521
|
response = get_app_session_by_id.sync_detailed(
|
521
522
|
client=self.client,
|
522
523
|
id=session_id,
|
524
|
+
returning=none_as_unset(optional_array_query_param(returning)),
|
523
525
|
)
|
524
526
|
return model_from_detailed(response)
|
525
527
|
|
@@ -25,6 +25,7 @@ from benchling_sdk.helpers.serialization_helpers import (
|
|
25
25
|
none_as_unset,
|
26
26
|
optional_array_query_param,
|
27
27
|
)
|
28
|
+
from benchling_sdk.helpers.task_helpers import TaskHelper
|
28
29
|
from benchling_sdk.helpers.transaction_manager import TransactionManager
|
29
30
|
from benchling_sdk.models import (
|
30
31
|
AssayResult,
|
@@ -37,7 +38,6 @@ from benchling_sdk.models import (
|
|
37
38
|
AssayResultsCreateResponse,
|
38
39
|
AssayResultsPaginatedList,
|
39
40
|
AssayResultTransactionCreateResponse,
|
40
|
-
AsyncTaskLink,
|
41
41
|
ListAssayResultsSort,
|
42
42
|
)
|
43
43
|
from benchling_sdk.services.v2.base_service import BaseService
|
@@ -202,7 +202,7 @@ class AssayResultService(BaseService):
|
|
202
202
|
@api_method
|
203
203
|
def bulk_create(
|
204
204
|
self, assay_results: Iterable[AssayResultCreate], table_id: Optional[str] = None
|
205
|
-
) ->
|
205
|
+
) -> TaskHelper[AssayResultsCreateResponse]:
|
206
206
|
"""
|
207
207
|
Create 1 or more results.
|
208
208
|
|
@@ -212,7 +212,7 @@ class AssayResultService(BaseService):
|
|
212
212
|
assay_results=list(assay_results), **({"table_id": table_id} if table_id else {})
|
213
213
|
)
|
214
214
|
response = bulk_create_assay_results.sync_detailed(client=self.client, json_body=request_body)
|
215
|
-
return
|
215
|
+
return self._task_helper_from_response(response, AssayResultsCreateResponse)
|
216
216
|
|
217
217
|
@api_method
|
218
218
|
def archive(self, assay_result_ids: Iterable[str]) -> AssayResultIdsResponse:
|
@@ -34,8 +34,10 @@ from benchling_sdk.helpers.serialization_helpers import (
|
|
34
34
|
optional_array_query_param,
|
35
35
|
schema_fields_query_param,
|
36
36
|
)
|
37
|
+
from benchling_sdk.helpers.task_helpers import TaskHelper
|
37
38
|
from benchling_sdk.models import (
|
38
|
-
|
39
|
+
BulkCreateContainersAsyncTaskResponse,
|
40
|
+
BulkUpdateContainersAsyncTaskResponse,
|
39
41
|
Container,
|
40
42
|
ContainerBulkUpdateItem,
|
41
43
|
ContainerContent,
|
@@ -59,6 +61,7 @@ from benchling_sdk.models import (
|
|
59
61
|
MultipleContainersTransfersList,
|
60
62
|
PrintLabels,
|
61
63
|
SampleRestrictionStatus,
|
64
|
+
TransfersAsyncTaskResponse,
|
62
65
|
)
|
63
66
|
from benchling_sdk.services.v2.base_service import BaseService
|
64
67
|
|
@@ -264,7 +267,9 @@ class ContainerService(BaseService):
|
|
264
267
|
return containers_list.containers
|
265
268
|
|
266
269
|
@api_method
|
267
|
-
def bulk_create(
|
270
|
+
def bulk_create(
|
271
|
+
self, containers: Iterable[ContainerCreate]
|
272
|
+
) -> TaskHelper[BulkCreateContainersAsyncTaskResponse]:
|
268
273
|
"""
|
269
274
|
Bulk create containers.
|
270
275
|
|
@@ -272,10 +277,12 @@ class ContainerService(BaseService):
|
|
272
277
|
"""
|
273
278
|
body = ContainersBulkCreateRequest(list(containers))
|
274
279
|
response = bulk_create_containers.sync_detailed(client=self.client, json_body=body)
|
275
|
-
return
|
280
|
+
return self._task_helper_from_response(response, BulkCreateContainersAsyncTaskResponse)
|
276
281
|
|
277
282
|
@api_method
|
278
|
-
def bulk_update(
|
283
|
+
def bulk_update(
|
284
|
+
self, containers: Iterable[ContainerBulkUpdateItem]
|
285
|
+
) -> TaskHelper[BulkUpdateContainersAsyncTaskResponse]:
|
279
286
|
"""
|
280
287
|
Bulk update containers.
|
281
288
|
|
@@ -283,7 +290,7 @@ class ContainerService(BaseService):
|
|
283
290
|
"""
|
284
291
|
body = ContainersBulkUpdateRequest(list(containers))
|
285
292
|
response = bulk_update_containers.sync_detailed(client=self.client, json_body=body)
|
286
|
-
return
|
293
|
+
return self._task_helper_from_response(response, BulkUpdateContainersAsyncTaskResponse)
|
287
294
|
|
288
295
|
@api_method
|
289
296
|
def create(self, container: ContainerCreate) -> Container:
|
@@ -440,7 +447,7 @@ class ContainerService(BaseService):
|
|
440
447
|
@api_method
|
441
448
|
def transfer_into_containers(
|
442
449
|
self, transfer_requests: Iterable[MultipleContainersTransfer]
|
443
|
-
) ->
|
450
|
+
) -> TaskHelper[TransfersAsyncTaskResponse]:
|
444
451
|
"""
|
445
452
|
Transfer into containers.
|
446
453
|
|
@@ -448,4 +455,4 @@ class ContainerService(BaseService):
|
|
448
455
|
"""
|
449
456
|
multiple_requests = MultipleContainersTransfersList(transfers=list(transfer_requests))
|
450
457
|
response = transfer_into_containers.sync_detailed(client=self.client, json_body=multiple_requests)
|
451
|
-
return
|
458
|
+
return self._task_helper_from_response(response, TransfersAsyncTaskResponse)
|
@@ -26,8 +26,10 @@ from benchling_sdk.helpers.serialization_helpers import (
|
|
26
26
|
optional_array_query_param,
|
27
27
|
schema_fields_query_param,
|
28
28
|
)
|
29
|
+
from benchling_sdk.helpers.task_helpers import TaskHelper
|
29
30
|
from benchling_sdk.models import (
|
30
|
-
|
31
|
+
BulkCreateCustomEntitiesAsyncTaskResponse,
|
32
|
+
BulkUpdateCustomEntitiesAsyncTaskResponse,
|
31
33
|
CustomEntitiesArchivalChange,
|
32
34
|
CustomEntitiesArchive,
|
33
35
|
CustomEntitiesBulkCreateRequest,
|
@@ -250,7 +252,9 @@ class CustomEntityService(BaseService):
|
|
250
252
|
return custom_entities.custom_entities
|
251
253
|
|
252
254
|
@api_method
|
253
|
-
def bulk_create(
|
255
|
+
def bulk_create(
|
256
|
+
self, entities: Iterable[CustomEntityBulkCreate]
|
257
|
+
) -> TaskHelper[BulkCreateCustomEntitiesAsyncTaskResponse]:
|
254
258
|
"""
|
255
259
|
Bulk create custom entities.
|
256
260
|
|
@@ -258,10 +262,12 @@ class CustomEntityService(BaseService):
|
|
258
262
|
"""
|
259
263
|
body = CustomEntitiesBulkCreateRequest(list(entities))
|
260
264
|
response = bulk_create_custom_entities.sync_detailed(client=self.client, json_body=body)
|
261
|
-
return
|
265
|
+
return self._task_helper_from_response(response, BulkCreateCustomEntitiesAsyncTaskResponse)
|
262
266
|
|
263
267
|
@api_method
|
264
|
-
def bulk_update(
|
268
|
+
def bulk_update(
|
269
|
+
self, entities: Iterable[CustomEntityBulkUpdate]
|
270
|
+
) -> TaskHelper[BulkUpdateCustomEntitiesAsyncTaskResponse]:
|
265
271
|
"""
|
266
272
|
Bulk update custom entities.
|
267
273
|
|
@@ -269,7 +275,7 @@ class CustomEntityService(BaseService):
|
|
269
275
|
"""
|
270
276
|
body = CustomEntitiesBulkUpdateRequest(list(entities))
|
271
277
|
response = bulk_update_custom_entities.sync_detailed(client=self.client, json_body=body)
|
272
|
-
return
|
278
|
+
return self._task_helper_from_response(response, BulkUpdateCustomEntitiesAsyncTaskResponse)
|
273
279
|
|
274
280
|
@api_method
|
275
281
|
def upsert(self, entity_registry_id: str, entity: CustomEntityUpsertRequest) -> CustomEntity:
|
@@ -284,11 +290,13 @@ class CustomEntityService(BaseService):
|
|
284
290
|
return model_from_detailed(response)
|
285
291
|
|
286
292
|
@api_method
|
287
|
-
def bulk_upsert(
|
293
|
+
def bulk_upsert(
|
294
|
+
self, body: CustomEntitiesBulkUpsertRequest
|
295
|
+
) -> TaskHelper[BulkUpdateCustomEntitiesAsyncTaskResponse]:
|
288
296
|
"""
|
289
297
|
Bulk update custom entities.
|
290
298
|
|
291
299
|
See https://benchling.com/api/reference#/Custom%20Entities/bulkUpsertCustomEntities
|
292
300
|
"""
|
293
301
|
response = bulk_upsert_custom_entities.sync_detailed(client=self.client, json_body=body)
|
294
|
-
return
|
302
|
+
return self._task_helper_from_response(response, BulkUpdateCustomEntitiesAsyncTaskResponse)
|