sapiopycommons 2024.3.19a157__py3-none-any.whl → 2025.1.17a402__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 sapiopycommons might be problematic. Click here for more details.
- sapiopycommons/callbacks/__init__.py +0 -0
- sapiopycommons/callbacks/callback_util.py +2041 -0
- sapiopycommons/callbacks/field_builder.py +545 -0
- sapiopycommons/chem/IndigoMolecules.py +46 -1
- sapiopycommons/chem/Molecules.py +100 -21
- sapiopycommons/customreport/__init__.py +0 -0
- sapiopycommons/customreport/column_builder.py +60 -0
- sapiopycommons/customreport/custom_report_builder.py +137 -0
- sapiopycommons/customreport/term_builder.py +315 -0
- sapiopycommons/datatype/attachment_util.py +14 -15
- sapiopycommons/datatype/data_fields.py +61 -0
- sapiopycommons/datatype/pseudo_data_types.py +440 -0
- sapiopycommons/eln/experiment_handler.py +355 -91
- sapiopycommons/eln/experiment_report_util.py +649 -0
- sapiopycommons/eln/plate_designer.py +152 -0
- sapiopycommons/files/complex_data_loader.py +31 -0
- sapiopycommons/files/file_bridge.py +149 -25
- sapiopycommons/files/file_bridge_handler.py +555 -0
- sapiopycommons/files/file_data_handler.py +633 -0
- sapiopycommons/files/file_util.py +263 -163
- sapiopycommons/files/file_validator.py +569 -0
- sapiopycommons/files/file_writer.py +377 -0
- sapiopycommons/flowcyto/flow_cyto.py +77 -0
- sapiopycommons/flowcyto/flowcyto_data.py +75 -0
- sapiopycommons/general/accession_service.py +375 -0
- sapiopycommons/general/aliases.py +250 -15
- sapiopycommons/general/audit_log.py +185 -0
- sapiopycommons/general/custom_report_util.py +251 -31
- sapiopycommons/general/directive_util.py +86 -0
- sapiopycommons/general/exceptions.py +69 -7
- sapiopycommons/general/popup_util.py +59 -7
- sapiopycommons/general/sapio_links.py +50 -0
- sapiopycommons/general/storage_util.py +148 -0
- sapiopycommons/general/time_util.py +91 -7
- sapiopycommons/multimodal/multimodal.py +146 -0
- sapiopycommons/multimodal/multimodal_data.py +490 -0
- sapiopycommons/processtracking/__init__.py +0 -0
- sapiopycommons/processtracking/custom_workflow_handler.py +406 -0
- sapiopycommons/processtracking/endpoints.py +192 -0
- sapiopycommons/recordmodel/record_handler.py +621 -148
- sapiopycommons/rules/eln_rule_handler.py +87 -8
- sapiopycommons/rules/on_save_rule_handler.py +87 -12
- sapiopycommons/sftpconnect/__init__.py +0 -0
- sapiopycommons/sftpconnect/sftp_builder.py +70 -0
- sapiopycommons/webhook/webhook_context.py +39 -0
- sapiopycommons/webhook/webhook_handlers.py +614 -71
- sapiopycommons/webhook/webservice_handlers.py +317 -0
- {sapiopycommons-2024.3.19a157.dist-info → sapiopycommons-2025.1.17a402.dist-info}/METADATA +5 -4
- sapiopycommons-2025.1.17a402.dist-info/RECORD +60 -0
- {sapiopycommons-2024.3.19a157.dist-info → sapiopycommons-2025.1.17a402.dist-info}/WHEEL +1 -1
- sapiopycommons-2024.3.19a157.dist-info/RECORD +0 -28
- {sapiopycommons-2024.3.19a157.dist-info → sapiopycommons-2025.1.17a402.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
from sapiopylib.rest.utils.Protocols import ElnEntryStep
|
|
2
|
+
from sapiopylib.rest.utils.recordmodel.RecordModelWrapper import WrappedType
|
|
3
|
+
|
|
4
|
+
from sapiopycommons.eln.experiment_handler import ExperimentHandler
|
|
5
|
+
from sapiopycommons.general.aliases import SapioRecord, RecordIdentifier, AliasUtil
|
|
6
|
+
from sapiopycommons.general.exceptions import SapioException
|
|
7
|
+
from sapiopycommons.recordmodel.record_handler import RecordHandler
|
|
8
|
+
|
|
9
|
+
PLATE_IDS_TAG: str = "MultiLayerPlating_Plate_RecordIdList"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class PlateDesignerEntry:
|
|
13
|
+
"""
|
|
14
|
+
A wrapper for 3D plate designer entries in experiments, providing functions for common actions when dealing with
|
|
15
|
+
such entries.
|
|
16
|
+
"""
|
|
17
|
+
step: ElnEntryStep
|
|
18
|
+
__exp_handler: ExperimentHandler
|
|
19
|
+
__rec_handler: RecordHandler
|
|
20
|
+
__plates: list[SapioRecord] | None
|
|
21
|
+
__aliquots: list[SapioRecord] | None
|
|
22
|
+
__sources: list[SapioRecord] | None
|
|
23
|
+
__designer_elements: list[SapioRecord] | None
|
|
24
|
+
__plate_ids: list[int] | None
|
|
25
|
+
|
|
26
|
+
def __init__(self, step: ElnEntryStep, exp_handler: ExperimentHandler):
|
|
27
|
+
"""
|
|
28
|
+
:param step: The ElnEntryStep that is the 3D plate designer entry.
|
|
29
|
+
:param exp_handler: An ExperimentHandler for the experiment that this entry comes from.
|
|
30
|
+
"""
|
|
31
|
+
self.step = step
|
|
32
|
+
self.__exp_handler = exp_handler
|
|
33
|
+
self.__rec_handler = RecordHandler(exp_handler.context)
|
|
34
|
+
self.__plates = None
|
|
35
|
+
self.__aliquots = None
|
|
36
|
+
self.__sources = None
|
|
37
|
+
self.__designer_elements = None
|
|
38
|
+
self.__plate_ids = None
|
|
39
|
+
|
|
40
|
+
def get_plates(self, wrapper_type: type[WrappedType]) -> list[WrappedType]:
|
|
41
|
+
"""
|
|
42
|
+
Get the plates that are in the designer entry.
|
|
43
|
+
|
|
44
|
+
Makes a webservice query to get the plates from the entry and caches the result for future calls. This cache
|
|
45
|
+
will be invalidated if a set_plates or add_plates call is made, requiring a new webservice call the next time
|
|
46
|
+
this function is called.
|
|
47
|
+
|
|
48
|
+
:param wrapper_type: The record model wrapper to use.
|
|
49
|
+
:return: A list of the plates in the designer entry.
|
|
50
|
+
"""
|
|
51
|
+
if self.__plates is not None:
|
|
52
|
+
return self.__plates
|
|
53
|
+
self.__plates = self.__rec_handler.query_models_by_id(wrapper_type, self.__get_plate_ids())
|
|
54
|
+
return self.__plates
|
|
55
|
+
|
|
56
|
+
def set_plates(self, plates: list[RecordIdentifier]) -> None:
|
|
57
|
+
"""
|
|
58
|
+
Set the plates that are in the plate designer entry. This removes any existing plates that are in the entry
|
|
59
|
+
but not in the given list.
|
|
60
|
+
|
|
61
|
+
Makes a webservice call to update the plate designer entry's entry options.
|
|
62
|
+
|
|
63
|
+
:param plates: The plates to set the plate designer entry with.
|
|
64
|
+
"""
|
|
65
|
+
record_ids: list[int] = AliasUtil.to_record_ids(plates)
|
|
66
|
+
self.__set_plate_ids(record_ids)
|
|
67
|
+
|
|
68
|
+
def add_plates(self, plates: list[RecordIdentifier]) -> None:
|
|
69
|
+
"""
|
|
70
|
+
Add the given plates to the plate designer entry. This preserves any existing plates that are in the entry.
|
|
71
|
+
|
|
72
|
+
Makes a webservice call to update the plate designer entry's entry options.
|
|
73
|
+
|
|
74
|
+
:param plates: The plates to add to the plate designer entry.
|
|
75
|
+
"""
|
|
76
|
+
record_ids: list[int] = AliasUtil.to_record_ids(plates)
|
|
77
|
+
self.__set_plate_ids(self.__get_plate_ids() + record_ids)
|
|
78
|
+
|
|
79
|
+
def get_sources(self, wrapper_type: type[WrappedType]) -> list[WrappedType]:
|
|
80
|
+
"""
|
|
81
|
+
Get the source records that were used to populate the plate designer entry's sample table. This looks for the
|
|
82
|
+
entries that the plate designer entry is dependent upon and gets their records if they match the data type name
|
|
83
|
+
of the given wrapper.
|
|
84
|
+
|
|
85
|
+
Makes a webservice call to retrieve the dependent entries if the experiment handler had not already cached it.
|
|
86
|
+
Makes another webservice call to get the records from the dependent entry and caches them for future calls.
|
|
87
|
+
|
|
88
|
+
:param wrapper_type: The record model wrapper to use.
|
|
89
|
+
:return: A list of the source records that populate the plate designer entry's sample table.
|
|
90
|
+
"""
|
|
91
|
+
if self.__sources is not None:
|
|
92
|
+
return self.__sources
|
|
93
|
+
|
|
94
|
+
records: list[WrappedType] = []
|
|
95
|
+
dependent_ids: list[int] = self.step.eln_entry.dependency_set
|
|
96
|
+
for step in self.__exp_handler.get_all_steps(wrapper_type):
|
|
97
|
+
if step.get_id() in dependent_ids:
|
|
98
|
+
records.extend(self.__exp_handler.get_step_models(step, wrapper_type))
|
|
99
|
+
|
|
100
|
+
self.__sources = records
|
|
101
|
+
return self.__sources
|
|
102
|
+
|
|
103
|
+
def get_aliquots(self, wrapper_type: type[WrappedType]) -> list[WrappedType]:
|
|
104
|
+
"""
|
|
105
|
+
Get the aliquots that were created from this plate designer entry upon its submission.
|
|
106
|
+
|
|
107
|
+
Makes a webservice call to retrieve the aliquots from the plate designer entry and caches them for future calls.
|
|
108
|
+
|
|
109
|
+
:param wrapper_type: The record model wrapper to use.
|
|
110
|
+
:return: A list of the aliquots created by the plate designer entry.
|
|
111
|
+
"""
|
|
112
|
+
if not self.__exp_handler.step_is_submitted(self.step):
|
|
113
|
+
raise SapioException("The plate designer entry must be submitted before its aliquots can be retrieved.")
|
|
114
|
+
if self.__aliquots is not None:
|
|
115
|
+
return self.__aliquots
|
|
116
|
+
self.__aliquots = self.__exp_handler.get_step_models(self.step, wrapper_type)
|
|
117
|
+
return self.__aliquots
|
|
118
|
+
|
|
119
|
+
def get_plate_designer_well_elements(self, wrapper_type: type[WrappedType]) -> list[WrappedType]:
|
|
120
|
+
"""
|
|
121
|
+
Get the plate designer well elements for the plates in the plate designer entry. These are the records in the
|
|
122
|
+
system that determine how wells are displayed on each plate in the entry.
|
|
123
|
+
|
|
124
|
+
Makes a webservice call to get the plate designer well elements of the entry and caches them for future calls.
|
|
125
|
+
This cache will be invalidated if a set_plates or add_plates call is made, requiring a new webservice call the
|
|
126
|
+
next time this function is called.
|
|
127
|
+
|
|
128
|
+
:param wrapper_type: The record model wrapper to use.
|
|
129
|
+
:return: A list of the plate designer well elements in the designer entry.
|
|
130
|
+
"""
|
|
131
|
+
if self.__designer_elements is not None:
|
|
132
|
+
return self.__designer_elements
|
|
133
|
+
self.__designer_elements = self.__rec_handler.query_models(wrapper_type, "PlateRecordId",
|
|
134
|
+
self.__get_plate_ids())
|
|
135
|
+
return self.__designer_elements
|
|
136
|
+
|
|
137
|
+
def __get_plate_ids(self) -> list[int]:
|
|
138
|
+
if self.__plate_ids is not None:
|
|
139
|
+
return self.__plate_ids
|
|
140
|
+
id_tag: str = self.__exp_handler.get_step_option(self.step, PLATE_IDS_TAG)
|
|
141
|
+
if not id_tag:
|
|
142
|
+
raise SapioException("No plates in the plate designer entry")
|
|
143
|
+
self.__plate_ids = [int(x) for x in id_tag.split(",")]
|
|
144
|
+
return self.__plate_ids
|
|
145
|
+
|
|
146
|
+
def __set_plate_ids(self, record_ids: list[int]) -> None:
|
|
147
|
+
record_ids.sort()
|
|
148
|
+
self.__exp_handler.add_step_options(self.step, {PLATE_IDS_TAG: ",".join([str(x) for x in record_ids])})
|
|
149
|
+
self.__plate_ids = record_ids
|
|
150
|
+
# The plates and designer elements caches have been invalidated.
|
|
151
|
+
self.__plates = None
|
|
152
|
+
self.__designer_elements = None
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import io
|
|
2
|
+
|
|
3
|
+
from sapiopylib.rest.User import SapioUser
|
|
4
|
+
|
|
5
|
+
from sapiopycommons.general.aliases import UserIdentifier, AliasUtil
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class CDL:
|
|
9
|
+
@staticmethod
|
|
10
|
+
def load_cdl(context: UserIdentifier, config_name: str, file_name: str, file_data: bytes | str) \
|
|
11
|
+
-> list[int]:
|
|
12
|
+
"""
|
|
13
|
+
Create data records from a file using one of the complex data loader (CDL) configurations in the system.
|
|
14
|
+
|
|
15
|
+
:param context: The current webhook context or a user object to send requests from.
|
|
16
|
+
:param config_name: The name of the CDL configuration to run.
|
|
17
|
+
:param file_name: The name of the file being read by the CDL.
|
|
18
|
+
:param file_data: A string or bytes of the file to be read by the CDL.
|
|
19
|
+
:return: A list of the record IDs of the data records created by the CDL.
|
|
20
|
+
"""
|
|
21
|
+
sub_path = "/ext/cdl/load"
|
|
22
|
+
params = {
|
|
23
|
+
"configName": config_name,
|
|
24
|
+
"fileName": file_name
|
|
25
|
+
}
|
|
26
|
+
user: SapioUser = AliasUtil.to_sapio_user(context)
|
|
27
|
+
with io.BytesIO(file_data.encode() if isinstance(file_data, str) else file_data) as data_stream:
|
|
28
|
+
response = user.post_data_stream(sub_path, params=params, data_stream=data_stream)
|
|
29
|
+
user.raise_for_status(response)
|
|
30
|
+
# The response content is returned as bytes for a comma separated string of record IDs.
|
|
31
|
+
return [int(x) for x in bytes.decode(response.content).split(",")]
|
|
@@ -1,20 +1,55 @@
|
|
|
1
1
|
import base64
|
|
2
2
|
import io
|
|
3
3
|
import urllib.parse
|
|
4
|
+
from typing import Any
|
|
4
5
|
|
|
5
6
|
from requests import Response
|
|
6
|
-
from sapiopylib.rest.
|
|
7
|
+
from sapiopylib.rest.User import SapioUser
|
|
8
|
+
|
|
9
|
+
from sapiopycommons.general.aliases import UserIdentifier, AliasUtil
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# FR-47387: Add support for the metadata endpoints in FileBridge.
|
|
13
|
+
class FileBridgeMetadata:
|
|
14
|
+
"""
|
|
15
|
+
Metadata for a file or directory in FileBridge.
|
|
16
|
+
"""
|
|
17
|
+
file_name: str
|
|
18
|
+
"""The name of the file or directory."""
|
|
19
|
+
is_file: bool
|
|
20
|
+
"""True if the metadata is for a file, False if it is for a directory."""
|
|
21
|
+
is_directory: bool
|
|
22
|
+
"""True if the metadata is for a directory, False if it is for a file."""
|
|
23
|
+
size: int
|
|
24
|
+
"""The size of the file in bytes. For directories, this value will always be zero."""
|
|
25
|
+
creation_time: int
|
|
26
|
+
"""The time the file or directory was created, in milliseconds since the epoch."""
|
|
27
|
+
last_accessed_time: int
|
|
28
|
+
"""The time the file or directory was last accessed, in milliseconds since the epoch."""
|
|
29
|
+
last_modified_time: int
|
|
30
|
+
"""The time the file or directory was last modified, in milliseconds since the epoch."""
|
|
31
|
+
|
|
32
|
+
def __init__(self, json_dict: dict[str, Any]):
|
|
33
|
+
self.file_name = json_dict['fileName']
|
|
34
|
+
self.is_file = json_dict['isFile']
|
|
35
|
+
self.is_directory = json_dict['isDirectory']
|
|
36
|
+
self.size = json_dict['size']
|
|
37
|
+
self.creation_time = json_dict['creationTime']
|
|
38
|
+
self.last_accessed_time = json_dict['lastAccessTime']
|
|
39
|
+
self.last_modified_time = json_dict['lastModifiedTime']
|
|
7
40
|
|
|
8
41
|
|
|
9
42
|
# FR-46064 - Initial port of PyWebhookUtils to sapiopycommons.
|
|
10
43
|
class FileBridge:
|
|
11
44
|
@staticmethod
|
|
12
|
-
def read_file(context:
|
|
45
|
+
def read_file(context: UserIdentifier, bridge_name: str, file_path: str,
|
|
46
|
+
base64_decode: bool = True) -> bytes:
|
|
13
47
|
"""
|
|
14
48
|
Read a file from FileBridge.
|
|
15
49
|
|
|
16
|
-
:param context: The current webhook context.
|
|
17
|
-
:param bridge_name: The name of the bridge to use.
|
|
50
|
+
:param context: The current webhook context or a user object to send requests from.
|
|
51
|
+
:param bridge_name: The name of the bridge to use. This is the "connection name" in the
|
|
52
|
+
file bridge configurations.
|
|
18
53
|
:param file_path: The path to read the file from.
|
|
19
54
|
:param base64_decode: If true, base64 decode the file. Files are by default base64 encoded when retrieved from
|
|
20
55
|
FileBridge.
|
|
@@ -24,8 +59,9 @@ class FileBridge:
|
|
|
24
59
|
params = {
|
|
25
60
|
'Filepath': f"bridge://{bridge_name}/{file_path}"
|
|
26
61
|
}
|
|
27
|
-
|
|
28
|
-
|
|
62
|
+
user: SapioUser = AliasUtil.to_sapio_user(context)
|
|
63
|
+
response = user.get(sub_path, params)
|
|
64
|
+
user.raise_for_status(response)
|
|
29
65
|
|
|
30
66
|
ret_val = response.content
|
|
31
67
|
if base64_decode:
|
|
@@ -33,12 +69,14 @@ class FileBridge:
|
|
|
33
69
|
return ret_val
|
|
34
70
|
|
|
35
71
|
@staticmethod
|
|
36
|
-
def write_file(context:
|
|
72
|
+
def write_file(context: UserIdentifier, bridge_name: str, file_path: str,
|
|
73
|
+
file_data: bytes | str) -> None:
|
|
37
74
|
"""
|
|
38
75
|
Write a file to FileBridge.
|
|
39
76
|
|
|
40
|
-
:param context: The current webhook context.
|
|
41
|
-
:param bridge_name: The name of the bridge to use.
|
|
77
|
+
:param context: The current webhook context or a user object to send requests from.
|
|
78
|
+
:param bridge_name: The name of the bridge to use. This is the "connection name" in the
|
|
79
|
+
file bridge configurations.
|
|
42
80
|
:param file_path: The path to write the file to. If a file already exists at the given path then the file is
|
|
43
81
|
overwritten.
|
|
44
82
|
:param file_data: A string or bytes of the file to be written.
|
|
@@ -47,39 +85,43 @@ class FileBridge:
|
|
|
47
85
|
params = {
|
|
48
86
|
'Filepath': f"bridge://{bridge_name}/{file_path}"
|
|
49
87
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
response =
|
|
53
|
-
|
|
88
|
+
user: SapioUser = AliasUtil.to_sapio_user(context)
|
|
89
|
+
with io.BytesIO(file_data.encode() if isinstance(file_data, str) else file_data) as data_stream:
|
|
90
|
+
response = user.post_data_stream(sub_path, params=params, data_stream=data_stream)
|
|
91
|
+
user.raise_for_status(response)
|
|
54
92
|
|
|
55
93
|
@staticmethod
|
|
56
|
-
def list_directory(context:
|
|
94
|
+
def list_directory(context: UserIdentifier, bridge_name: str,
|
|
95
|
+
file_path: str | None = "") -> list[str]:
|
|
57
96
|
"""
|
|
58
97
|
List the contents of a FileBridge directory.
|
|
59
98
|
|
|
60
|
-
:param context: The current webhook context.
|
|
61
|
-
:param bridge_name: The name of the bridge to use.
|
|
99
|
+
:param context: The current webhook context or a user object to send requests from.
|
|
100
|
+
:param bridge_name: The name of the bridge to use. This is the "connection name" in the
|
|
101
|
+
file bridge configurations.
|
|
62
102
|
:param file_path: The path to read the directory from.
|
|
63
|
-
:return: A list of
|
|
103
|
+
:return: A list of names of files and folders in the directory.
|
|
64
104
|
"""
|
|
65
105
|
sub_path = '/ext/filebridge/listDirectory'
|
|
66
106
|
params = {
|
|
67
107
|
'Filepath': f"bridge://{bridge_name}/{file_path}"
|
|
68
108
|
}
|
|
69
|
-
|
|
70
|
-
|
|
109
|
+
user: SapioUser = AliasUtil.to_sapio_user(context)
|
|
110
|
+
response: Response = user.get(sub_path, params=params)
|
|
111
|
+
user.raise_for_status(response)
|
|
71
112
|
|
|
72
113
|
response_body: list[str] = response.json()
|
|
73
114
|
path_length = len(f"bridge://{bridge_name}/")
|
|
74
|
-
return [urllib.parse.unquote(value[path_length:]
|
|
115
|
+
return [urllib.parse.unquote(value)[path_length:] for value in response_body]
|
|
75
116
|
|
|
76
117
|
@staticmethod
|
|
77
|
-
def create_directory(context:
|
|
118
|
+
def create_directory(context: UserIdentifier, bridge_name: str, file_path: str) -> None:
|
|
78
119
|
"""
|
|
79
120
|
Create a new directory in FileBridge.
|
|
80
121
|
|
|
81
|
-
:param context: The current webhook context.
|
|
82
|
-
:param bridge_name: The name of the bridge to use.
|
|
122
|
+
:param context: The current webhook context or a user object to send requests from.
|
|
123
|
+
:param bridge_name: The name of the bridge to use. This is the "connection name" in the
|
|
124
|
+
file bridge configurations.
|
|
83
125
|
:param file_path: The path to create the directory at. If a directory already exists at the given path then an
|
|
84
126
|
exception is raised.
|
|
85
127
|
"""
|
|
@@ -87,5 +129,87 @@ class FileBridge:
|
|
|
87
129
|
params = {
|
|
88
130
|
'Filepath': f"bridge://{bridge_name}/{file_path}"
|
|
89
131
|
}
|
|
90
|
-
|
|
91
|
-
|
|
132
|
+
user: SapioUser = AliasUtil.to_sapio_user(context)
|
|
133
|
+
response = user.post(sub_path, params=params)
|
|
134
|
+
user.raise_for_status(response)
|
|
135
|
+
|
|
136
|
+
@staticmethod
|
|
137
|
+
def delete_file(context: UserIdentifier, bridge_name: str, file_path: str) -> None:
|
|
138
|
+
"""
|
|
139
|
+
Delete an existing file in FileBridge.
|
|
140
|
+
|
|
141
|
+
:param context: The current webhook context or a user object to send requests from.
|
|
142
|
+
:param bridge_name: The name of the bridge to use. This is the "connection name" in the
|
|
143
|
+
file bridge configurations.
|
|
144
|
+
:param file_path: The path to the file to delete.
|
|
145
|
+
"""
|
|
146
|
+
sub_path = '/ext/filebridge/deleteFile'
|
|
147
|
+
params = {
|
|
148
|
+
'Filepath': f"bridge://{bridge_name}/{file_path}"
|
|
149
|
+
}
|
|
150
|
+
user: SapioUser = AliasUtil.to_sapio_user(context)
|
|
151
|
+
response = user.delete(sub_path, params=params)
|
|
152
|
+
user.raise_for_status(response)
|
|
153
|
+
|
|
154
|
+
@staticmethod
|
|
155
|
+
def delete_directory(context: UserIdentifier, bridge_name: str, file_path: str) -> None:
|
|
156
|
+
"""
|
|
157
|
+
Delete an existing directory in FileBridge.
|
|
158
|
+
|
|
159
|
+
:param context: The current webhook context or a user object to send requests from.
|
|
160
|
+
:param bridge_name: The name of the bridge to use. This is the "connection name" in the
|
|
161
|
+
file bridge configurations.
|
|
162
|
+
:param file_path: The path to the directory to delete.
|
|
163
|
+
"""
|
|
164
|
+
sub_path = '/ext/filebridge/deleteDirectory'
|
|
165
|
+
params = {
|
|
166
|
+
'Filepath': f"bridge://{bridge_name}/{file_path}"
|
|
167
|
+
}
|
|
168
|
+
user: SapioUser = AliasUtil.to_sapio_user(context)
|
|
169
|
+
response = user.delete(sub_path, params=params)
|
|
170
|
+
user.raise_for_status(response)
|
|
171
|
+
|
|
172
|
+
@staticmethod
|
|
173
|
+
def file_metadata(context: UserIdentifier, bridge_name: str, file_path: str) -> FileBridgeMetadata:
|
|
174
|
+
"""
|
|
175
|
+
Get metadata for a file or directory in FileBridge.
|
|
176
|
+
|
|
177
|
+
The file path may be to a directory, in which case only the metadata for that directory will be returned. If you
|
|
178
|
+
want the metadata for the contents of a directory, then use the directory_metadata function.
|
|
179
|
+
|
|
180
|
+
:param context: The current webhook context or a user object to send requests from.
|
|
181
|
+
:param bridge_name: The name of the bridge to use. This is the "connection name" in the
|
|
182
|
+
file bridge configurations.
|
|
183
|
+
:param file_path: The path to the file to retrieve the metadata from.
|
|
184
|
+
:return: The metadata for the file.
|
|
185
|
+
"""
|
|
186
|
+
sub_path = '/ext/filebridge/file/metadata'
|
|
187
|
+
params = {
|
|
188
|
+
'Filepath': f"bridge://{bridge_name}/{file_path}"
|
|
189
|
+
}
|
|
190
|
+
user: SapioUser = AliasUtil.to_sapio_user(context)
|
|
191
|
+
response = user.get(sub_path, params=params)
|
|
192
|
+
user.raise_for_status(response)
|
|
193
|
+
response_body: dict[str, Any] = response.json()
|
|
194
|
+
return FileBridgeMetadata(response_body)
|
|
195
|
+
|
|
196
|
+
@staticmethod
|
|
197
|
+
def directory_metadata(context: UserIdentifier, bridge_name: str, file_path: str) -> list[FileBridgeMetadata]:
|
|
198
|
+
"""
|
|
199
|
+
Get metadata for every file or nested directory in a directory in FileBridge.
|
|
200
|
+
|
|
201
|
+
:param context: The current webhook context or a user object to send requests from.
|
|
202
|
+
:param bridge_name: The name of the bridge to use. This is the "connection name" in the
|
|
203
|
+
file bridge configurations.
|
|
204
|
+
:param file_path: The path to the directory to retrieve the metadata of the contents.
|
|
205
|
+
:return: A list of the metadata for the contents of the directory.
|
|
206
|
+
"""
|
|
207
|
+
sub_path = '/ext/filebridge/directory/metadata'
|
|
208
|
+
params = {
|
|
209
|
+
'Filepath': f"bridge://{bridge_name}/{file_path}"
|
|
210
|
+
}
|
|
211
|
+
user: SapioUser = AliasUtil.to_sapio_user(context)
|
|
212
|
+
response = user.get(sub_path, params=params)
|
|
213
|
+
user.raise_for_status(response)
|
|
214
|
+
response_body: list[dict[str, Any]] = response.json()
|
|
215
|
+
return [FileBridgeMetadata(x) for x in response_body]
|