tol-sdk 1.7.4__py3-none-any.whl → 1.7.5b2__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.
- tol/api_base/__init__.py +1 -0
- tol/api_base/blueprint.py +19 -8
- tol/{s3/data_upload/blueprint.py → api_base/data_upload.py} +21 -6
- tol/api_base/pipeline_steps.py +4 -4
- tol/api_client/api_datasource.py +8 -8
- tol/api_client/converter.py +38 -52
- tol/api_client/factory.py +21 -19
- tol/api_client/parser.py +138 -98
- tol/api_client/view.py +118 -43
- tol/core/__init__.py +2 -1
- tol/core/data_object.py +27 -9
- tol/core/data_object_converter.py +37 -2
- tol/core/factory.py +51 -62
- tol/core/validate.py +1 -0
- tol/ena/client.py +61 -10
- tol/ena/ena_datasource.py +16 -10
- tol/ena/ena_methods.py +33 -32
- tol/ena/parser.py +15 -2
- tol/flows/converters/__init__.py +2 -0
- tol/flows/converters/incoming_sample_to_ena_sample_converter.py +130 -0
- tol/flows/converters/incoming_sample_to_incoming_sample_with_lists_converter.py +46 -0
- tol/s3/__init__.py +0 -1
- tol/sql/model.py +1 -1
- tol/sql/pipeline_step/factory.py +1 -1
- tol/sql/sql_converter.py +7 -1
- tol/validators/__init__.py +12 -1
- tol/validators/allowed_keys.py +17 -12
- tol/validators/allowed_values.py +21 -63
- tol/validators/allowed_values_from_datasource.py +89 -0
- tol/validators/assert_on_condition.py +56 -0
- tol/validators/ena_checklist.py +73 -0
- tol/validators/ena_submittable.py +61 -0
- tol/validators/interfaces/__init__.py +5 -0
- tol/validators/interfaces/condition_evaluator.py +102 -0
- tol/validators/min_one_valid_value.py +55 -0
- tol/validators/mutually_exclusive.py +111 -0
- tol/validators/regex.py +30 -23
- tol/validators/regex_by_value.py +33 -33
- tol/validators/specimens_have_same_taxon.py +60 -0
- tol/validators/sts_fields.py +88 -0
- tol/validators/tolid.py +110 -0
- tol/validators/unique_values.py +25 -17
- tol/validators/unique_whole_organisms.py +109 -0
- {tol_sdk-1.7.4.dist-info → tol_sdk-1.7.5b2.dist-info}/METADATA +1 -1
- {tol_sdk-1.7.4.dist-info → tol_sdk-1.7.5b2.dist-info}/RECORD +49 -36
- tol/s3/data_upload/__init__.py +0 -3
- {tol_sdk-1.7.4.dist-info → tol_sdk-1.7.5b2.dist-info}/WHEEL +0 -0
- {tol_sdk-1.7.4.dist-info → tol_sdk-1.7.5b2.dist-info}/entry_points.txt +0 -0
- {tol_sdk-1.7.4.dist-info → tol_sdk-1.7.5b2.dist-info}/licenses/LICENSE +0 -0
- {tol_sdk-1.7.4.dist-info → tol_sdk-1.7.5b2.dist-info}/top_level.txt +0 -0
tol/validators/tolid.py
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2025 Genome Research Ltd.
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: MIT
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from typing import Any, Dict
|
|
7
|
+
|
|
8
|
+
from tol.core import DataObject, DataSource
|
|
9
|
+
from tol.core import DataSourceError, DataSourceFilter
|
|
10
|
+
from tol.core.validate import Validator
|
|
11
|
+
from tol.sources.tolid import tolid
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class TolidValidator(Validator):
|
|
15
|
+
"""
|
|
16
|
+
Validates that a stream of `DataObject` instances
|
|
17
|
+
contains unique Tol IDs.
|
|
18
|
+
"""
|
|
19
|
+
@dataclass(slots=True, frozen=True, kw_only=True)
|
|
20
|
+
class Config:
|
|
21
|
+
species_id_field: str
|
|
22
|
+
specimen_id_field: str
|
|
23
|
+
error_ignore_field: str
|
|
24
|
+
error_ignore_value: str
|
|
25
|
+
warning_detail: str = 'Species not found in Tol ID source'
|
|
26
|
+
|
|
27
|
+
__slots__ = ['__config', '__datasource', '__cached_species_id', '__cached_tolids']
|
|
28
|
+
__config: Config
|
|
29
|
+
__datasource: DataSource
|
|
30
|
+
__cached_species_ids: Dict[str, Any]
|
|
31
|
+
__cached_tolids: Dict[str, Any]
|
|
32
|
+
|
|
33
|
+
def __init__(
|
|
34
|
+
self,
|
|
35
|
+
config: Config,
|
|
36
|
+
datasource=tolid(),
|
|
37
|
+
) -> None:
|
|
38
|
+
|
|
39
|
+
super().__init__()
|
|
40
|
+
|
|
41
|
+
self.__config = config
|
|
42
|
+
self.__datasource = datasource
|
|
43
|
+
self.__cached_species_ids = {}
|
|
44
|
+
self.__cached_tolids = {}
|
|
45
|
+
|
|
46
|
+
def _validate_data_object(
|
|
47
|
+
self,
|
|
48
|
+
obj: DataObject
|
|
49
|
+
) -> None:
|
|
50
|
+
self.__warning_on_species_not_in_tolid(obj=obj)
|
|
51
|
+
self.__error_on_specimen_id_and_taxon_not_matching_tolid(obj=obj)
|
|
52
|
+
|
|
53
|
+
def __warning_on_species_not_in_tolid(
|
|
54
|
+
self,
|
|
55
|
+
obj: DataObject,
|
|
56
|
+
) -> None:
|
|
57
|
+
|
|
58
|
+
obj_species_id = obj.get_field_by_name(self.__config.species_id_field)
|
|
59
|
+
if self.__config.species_id_field in obj.attributes:
|
|
60
|
+
try:
|
|
61
|
+
if obj_species_id not in self.__cached_species_ids:
|
|
62
|
+
self.__cached_species_ids[obj_species_id] = (
|
|
63
|
+
self.__datasource.get_one('species', obj_species_id) is not None)
|
|
64
|
+
|
|
65
|
+
except DataSourceError as e:
|
|
66
|
+
if e.status_code == 404:
|
|
67
|
+
self.__cached_species_ids[obj_species_id] = False
|
|
68
|
+
|
|
69
|
+
species_in_tolid = self.__cached_species_ids[obj_species_id]
|
|
70
|
+
if species_in_tolid is False:
|
|
71
|
+
self.add_warning(
|
|
72
|
+
object_id=obj.id,
|
|
73
|
+
detail=self.__config.warning_detail,
|
|
74
|
+
field=self.__config.species_id_field,
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
def __error_on_specimen_id_and_taxon_not_matching_tolid(
|
|
78
|
+
self,
|
|
79
|
+
obj: DataObject,
|
|
80
|
+
) -> None:
|
|
81
|
+
|
|
82
|
+
if (obj.get_field_by_name(self.__config.error_ignore_field) is
|
|
83
|
+
self.__config.error_ignore_value):
|
|
84
|
+
return
|
|
85
|
+
|
|
86
|
+
if self.__config.specimen_id_field in obj.attributes:
|
|
87
|
+
specimen_id = obj.get_field_by_name(self.__config.specimen_id_field)
|
|
88
|
+
if specimen_id not in self.__cached_tolids:
|
|
89
|
+
f = DataSourceFilter()
|
|
90
|
+
f.and_ = {'specimen_id': {'eq': {'value': specimen_id}}}
|
|
91
|
+
self.__cached_tolids[specimen_id] = list(self.__datasource.get_list(
|
|
92
|
+
object_type='specimen',
|
|
93
|
+
object_filters=f
|
|
94
|
+
))
|
|
95
|
+
|
|
96
|
+
if (len(self.__cached_tolids[specimen_id]) == 0):
|
|
97
|
+
return
|
|
98
|
+
else:
|
|
99
|
+
taxons = set()
|
|
100
|
+
for tolid_ in self.__cached_tolids[specimen_id]:
|
|
101
|
+
taxons.add(str(tolid_.species.id))
|
|
102
|
+
|
|
103
|
+
if str(obj.get_field_by_name(self.__config.species_id_field)) not in taxons:
|
|
104
|
+
self.add_error(
|
|
105
|
+
object_id=obj.id,
|
|
106
|
+
detail=f'Specimen ID {specimen_id} does not match Taxon ID '
|
|
107
|
+
f'{obj.get_field_by_name(self.__config.species_id_field)}'
|
|
108
|
+
'in TolID source',
|
|
109
|
+
field=[self.__config.specimen_id_field, self.__config.species_id_field]
|
|
110
|
+
)
|
tol/validators/unique_values.py
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
#
|
|
3
3
|
# SPDX-License-Identifier: MIT
|
|
4
4
|
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from typing import Dict, List, Set
|
|
7
|
+
|
|
5
8
|
from tol.core import DataObject
|
|
6
9
|
from tol.core.validate import Validator
|
|
7
10
|
|
|
@@ -11,23 +14,28 @@ class UniqueValuesValidator(Validator):
|
|
|
11
14
|
Validates that a stream of `DataObject` instances
|
|
12
15
|
contains unique values for specified keys.
|
|
13
16
|
"""
|
|
17
|
+
@dataclass(slots=True, frozen=True, kw_only=True)
|
|
18
|
+
class Config:
|
|
19
|
+
unique_keys: List[List[str] | str]
|
|
20
|
+
detail: str = 'Value is not unique'
|
|
21
|
+
is_error: bool = True
|
|
22
|
+
|
|
23
|
+
__slots__ = ['__config', '__duplicates', '__existing_values']
|
|
24
|
+
__config: Config
|
|
25
|
+
__duplicates: Dict[str, List[str]]
|
|
26
|
+
__existing_values: Dict[str, Set]
|
|
14
27
|
|
|
15
28
|
def __init__(
|
|
16
29
|
self,
|
|
17
|
-
|
|
18
|
-
*,
|
|
19
|
-
detail: str = 'Value is not unique',
|
|
20
|
-
is_error: bool = True,
|
|
30
|
+
config: Config
|
|
21
31
|
) -> None:
|
|
22
32
|
|
|
23
33
|
super().__init__()
|
|
24
34
|
|
|
25
|
-
self.
|
|
26
|
-
self.
|
|
27
|
-
self.
|
|
28
|
-
self.
|
|
29
|
-
self.__existing_values: dict[str, set] = {}
|
|
30
|
-
for key in self.__keys:
|
|
35
|
+
self.__config = config
|
|
36
|
+
self.__duplicates = {}
|
|
37
|
+
self.__existing_values = {}
|
|
38
|
+
for key in self.__config.unique_keys:
|
|
31
39
|
if isinstance(key, str):
|
|
32
40
|
self.__existing_values[key] = set()
|
|
33
41
|
elif isinstance(key, list):
|
|
@@ -39,13 +47,13 @@ class UniqueValuesValidator(Validator):
|
|
|
39
47
|
obj: DataObject
|
|
40
48
|
) -> None:
|
|
41
49
|
|
|
42
|
-
for unique_key in self.
|
|
50
|
+
for unique_key in self.__config.unique_keys:
|
|
43
51
|
if isinstance(unique_key, list):
|
|
44
52
|
concat = ''
|
|
45
53
|
for key in unique_key:
|
|
46
54
|
concat = concat + '/' + (str(obj.attributes[key]))
|
|
47
55
|
if concat in self.__existing_values['/'.join(unique_key)]:
|
|
48
|
-
self.
|
|
56
|
+
self.__duplicate_checks(
|
|
49
57
|
key=key,
|
|
50
58
|
value=concat
|
|
51
59
|
)
|
|
@@ -54,14 +62,14 @@ class UniqueValuesValidator(Validator):
|
|
|
54
62
|
|
|
55
63
|
else:
|
|
56
64
|
if obj.attributes[unique_key] in self.__existing_values[unique_key]:
|
|
57
|
-
self.
|
|
65
|
+
self.__duplicate_checks(
|
|
58
66
|
key=unique_key,
|
|
59
67
|
value=obj.attributes[unique_key]
|
|
60
68
|
)
|
|
61
69
|
else:
|
|
62
70
|
self.__existing_values[unique_key].add(obj.attributes[unique_key])
|
|
63
71
|
|
|
64
|
-
def
|
|
72
|
+
def __duplicate_checks(
|
|
65
73
|
self,
|
|
66
74
|
key: str,
|
|
67
75
|
value: str
|
|
@@ -86,15 +94,15 @@ class UniqueValuesValidator(Validator):
|
|
|
86
94
|
key: str,
|
|
87
95
|
) -> None:
|
|
88
96
|
|
|
89
|
-
if self.
|
|
97
|
+
if self.__config.is_error:
|
|
90
98
|
self.add_error(
|
|
91
99
|
object_id=obj.id,
|
|
92
|
-
detail=self.
|
|
100
|
+
detail=self.__config.detail,
|
|
93
101
|
field=key,
|
|
94
102
|
)
|
|
95
103
|
else:
|
|
96
104
|
self.add_warning(
|
|
97
105
|
object_id=obj.id,
|
|
98
|
-
detail=self.
|
|
106
|
+
detail=self.__config.detail,
|
|
99
107
|
field=key,
|
|
100
108
|
)
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2025 Genome Research Ltd.
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: MIT
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from typing import List
|
|
7
|
+
|
|
8
|
+
from tol.core import Validator
|
|
9
|
+
from tol.core.data_object import DataObject
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class UniqueWholeOrganismsValidator(Validator):
|
|
13
|
+
"""
|
|
14
|
+
Validates an incoming stream of `DataObject` instances.
|
|
15
|
+
For each data object (sample) not a SYMBIONT, it checks:
|
|
16
|
+
1. There are no two samples with organism part WHOLE_ORGANISM with the same SPECIMEN_ID
|
|
17
|
+
2. There are no samples with organism part *not* WHOLE_ORGANISM that have a SPECIMEN_ID
|
|
18
|
+
the same as a WHOLE_ORGANISM in the manifest.
|
|
19
|
+
"""
|
|
20
|
+
@dataclass(slots=True, frozen=True, kw_only=True)
|
|
21
|
+
class Config:
|
|
22
|
+
symbiont_field: str
|
|
23
|
+
organism_part_field: str
|
|
24
|
+
specimen_id_field: str
|
|
25
|
+
|
|
26
|
+
__slots__ = ['__config', '__whole_organisms', '__part_organisms']
|
|
27
|
+
__config: Config
|
|
28
|
+
__whole_organisms: List[str]
|
|
29
|
+
__part_organisms: List[str]
|
|
30
|
+
|
|
31
|
+
def __init__(self, config: Config) -> None:
|
|
32
|
+
super().__init__()
|
|
33
|
+
self.__whole_organisms = []
|
|
34
|
+
self.__part_organisms = []
|
|
35
|
+
self.__config = config
|
|
36
|
+
|
|
37
|
+
def _validate_data_object(self, obj: DataObject) -> None:
|
|
38
|
+
# This function uses a bit of a confusing method for its validation, so I'm going to
|
|
39
|
+
# leave an explanation here as to how it works for anyone who needs to modify it
|
|
40
|
+
# in the future!
|
|
41
|
+
#
|
|
42
|
+
# In the original code to be adapted, two loops were used. The first looped over each
|
|
43
|
+
# data object whose ORGANISM_PART was 'WHOLE_ORGANISM', adding them to a list. Before it
|
|
44
|
+
# did this though, it would check to see if the SPECIMEN_ID of this data object was already
|
|
45
|
+
# contained in said list (to ensure the specimen IDs were unique). In the second loop, the
|
|
46
|
+
# rest of the data objects (those whose ORGANISM PART was *not* 'WHOLE_ORGANISM') were
|
|
47
|
+
# looped over, each being checked to see if their SPECIMEN_ID was contained in the list
|
|
48
|
+
# (the one containing the whole organisms). In all, this ensures that all whole organisms
|
|
49
|
+
# have unique specimen IDs, and all part organisms do not share the specimen IDs of any of
|
|
50
|
+
# the whole organisms.
|
|
51
|
+
#
|
|
52
|
+
# The issue when adapting this to a Validator to be used in a pipeline, is that this
|
|
53
|
+
# function only takes in one data object at a time, via a generator (to save needing to
|
|
54
|
+
# load many into memory at once). The problem this left us with is that we could no longer
|
|
55
|
+
# achieve the same result by using two passes of the data, as only one pass was feasible.
|
|
56
|
+
#
|
|
57
|
+
# So here's what I ended up with. This validator stores the SPECIMEN_IDs of both all of the
|
|
58
|
+
# whole organisms *and* part organisms. From this, detecting duplicate whole organisms is
|
|
59
|
+
# the same, but detecting whether a part organism shared the SPECIMEN_ID of a whole
|
|
60
|
+
# organism now has two separate cases: when the data object passed into this function is
|
|
61
|
+
# a whole organism, or a part organism. In the case of it being a part organism, a very
|
|
62
|
+
# similar solution to before can be used: we simply check whether self.__whole_organisms
|
|
63
|
+
# conatins the same SPECIMEN_ID. However, for the case where the data object is a whole
|
|
64
|
+
# organism, effectively the inverse is done; it is the self.__part_organisms list that is
|
|
65
|
+
# checked. This covers all cases:
|
|
66
|
+
# 1. There are no duplicates, in which case there will never be a time when the same
|
|
67
|
+
# SPECIMEN_ID will be in both lists.
|
|
68
|
+
# 2. A whole organism is checked, then a part organism with the same SPECIMEN_ID is
|
|
69
|
+
# checked. In this case, self.__whole_organisms will contain the same SPECIMEN_ID,
|
|
70
|
+
# so the duplicate is detected.
|
|
71
|
+
# 3. A part organism is checked, then a whole organism with the same SPECIMEN_ID is
|
|
72
|
+
# checked. In this case, self.__part_organisms will contain the same SPECIMEN_ID,
|
|
73
|
+
# so the duplicate is detected.
|
|
74
|
+
#
|
|
75
|
+
# From Thomas :)
|
|
76
|
+
|
|
77
|
+
# Ensure the data object is not a SYMBIONT, because organism part checks do not apply
|
|
78
|
+
if obj.attributes.get(self.__config.symbiont_field) != 'SYMBIONT':
|
|
79
|
+
specimen_id = obj.attributes.get(self.__config.specimen_id_field)
|
|
80
|
+
if specimen_id is None:
|
|
81
|
+
return
|
|
82
|
+
|
|
83
|
+
organism_part = obj.attributes.get(self.__config.organism_part_field)
|
|
84
|
+
if organism_part == 'WHOLE_ORGANISM':
|
|
85
|
+
if specimen_id in self.__whole_organisms:
|
|
86
|
+
self.add_error(
|
|
87
|
+
object_id=obj.id,
|
|
88
|
+
detail='No two whole organisms can have the same Specimen ID',
|
|
89
|
+
field=self.__config.specimen_id_field,
|
|
90
|
+
)
|
|
91
|
+
if specimen_id in self.__part_organisms:
|
|
92
|
+
self.add_error(
|
|
93
|
+
object_id=obj.id,
|
|
94
|
+
detail='A whole organism cannot have a Specimen ID already used for'
|
|
95
|
+
'a non-whole organism',
|
|
96
|
+
field=self.__config.specimen_id_field,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
self.__whole_organisms.append(specimen_id)
|
|
100
|
+
else:
|
|
101
|
+
if specimen_id in self.__whole_organisms:
|
|
102
|
+
self.add_error(
|
|
103
|
+
object_id=obj.id,
|
|
104
|
+
detail='A non-whole organism cannot have a Specimen ID already used for'
|
|
105
|
+
'a whole organism',
|
|
106
|
+
field=self.__config.specimen_id_field,
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
self.__part_organisms.append(specimen_id)
|
|
@@ -4,11 +4,12 @@ tol/markdown.py,sha256=X-ooYUYLkkVS8DyBHYib8d2QBBNMPlBP5_ZQz8-mAYc,570
|
|
|
4
4
|
tol/actions/__init__.py,sha256=xOj2kvRYv2GWQLqrpL_xhwZUZDwtOBnxb5CZ9qmP-pk,169
|
|
5
5
|
tol/actions/action.py,sha256=HlfUsfVGd2vuNAwD_01yo1i32nh6UNrt_ytcY2ladgM,651
|
|
6
6
|
tol/actions/upsert_action.py,sha256=DnSz1LhHibF0WcK6Qht5eLIGi3PPXc6GSRsd8Y2dZBE,1366
|
|
7
|
-
tol/api_base/__init__.py,sha256=
|
|
7
|
+
tol/api_base/__init__.py,sha256=K8Gpp7nEROn4t0JzJwEbiR49C3KI091ZxoljgnpXGac,367
|
|
8
8
|
tol/api_base/action.py,sha256=l3MzD3jSDdYiZs-HCT4YEsXkp34X26k6yWugXrRB2XU,6575
|
|
9
|
-
tol/api_base/blueprint.py,sha256=
|
|
9
|
+
tol/api_base/blueprint.py,sha256=AHCvBUwvXbXtKuRv_MmQNtMrXnVEtdNVZMh-_CMsYY0,19345
|
|
10
10
|
tol/api_base/controller.py,sha256=5Fp2FobjXXPlongu1j7adGJKlSVufW0_jpk_wZIMRa4,26818
|
|
11
|
-
tol/api_base/
|
|
11
|
+
tol/api_base/data_upload.py,sha256=z8Kp4BWQ6q06vT9ZwS8cgedWuGxBwZLkT6xpHk1K008,2939
|
|
12
|
+
tol/api_base/pipeline_steps.py,sha256=Y3rcqQh1w4F0tCxMLGI3H8W3pbl54OWLrUYbBR44Y4A,5850
|
|
12
13
|
tol/api_base/system.py,sha256=c47sbcNaCd3teiJLO-Zwg1cUNvfCvRO4GmKzAMNxZrw,1219
|
|
13
14
|
tol/api_base/auth/__init__.py,sha256=LNbVtQDlzKWzLoCmxAPSIAcM6mlVMnn0Aj9HFUudseo,460
|
|
14
15
|
tol/api_base/auth/asserts.py,sha256=3kHP2yW6HZxevIgeO8Rl3iKovi8WHZcguVbPSFUjawQ,2765
|
|
@@ -30,15 +31,15 @@ tol/api_base/misc/list_get_parameters.py,sha256=6DtUgfKPTok3utKPOxceJdwV_ZnJ5nis
|
|
|
30
31
|
tol/api_base/misc/relation_url.py,sha256=qfo-okp8Gv9-PEDghMfGZ2pHdYbHRhohvA9v3Govtlo,1127
|
|
31
32
|
tol/api_base/misc/stats_parameters.py,sha256=IVpHqUeGQyjuih59jwqT-fIQMCBeESi2T9b4r9i4J28,1721
|
|
32
33
|
tol/api_client/__init__.py,sha256=58SAywuMrIUCBAY9us_d_RLTMnaUTYWWts0LRQC5wLo,187
|
|
33
|
-
tol/api_client/api_datasource.py,sha256=
|
|
34
|
+
tol/api_client/api_datasource.py,sha256=9CPNsujgnp__EwkZGwu9ZTmOxSwOldfLraOEQ7GBLng,14490
|
|
34
35
|
tol/api_client/client.py,sha256=gcnX4iCZtjnCC6qylizXxLe3l6xLhME6LEJH0UeW7V4,13979
|
|
35
|
-
tol/api_client/converter.py,sha256=
|
|
36
|
+
tol/api_client/converter.py,sha256=g32fjqga4mC923n95HmQImPuawMfeb9rQcl3ZxUWP2s,4463
|
|
36
37
|
tol/api_client/exception.py,sha256=MkvJaIyRVCzQ2rKOYnCOcT747mpOeQwGJJl3Kkb1BsQ,3999
|
|
37
|
-
tol/api_client/factory.py,sha256=
|
|
38
|
+
tol/api_client/factory.py,sha256=WGHA5wio4XS8OHqG07DLSVjehOeAsVoVCc5phAIq4H8,3737
|
|
38
39
|
tol/api_client/filter.py,sha256=D49RIai5Yj4CiQvIkgaEIXdw_oSU7CD5cn9SdXWRYXU,1474
|
|
39
|
-
tol/api_client/parser.py,sha256=
|
|
40
|
+
tol/api_client/parser.py,sha256=88Q2RlPwn9JJsSIukC2_yxfaM2AaXjsGuDOESqY7se4,8351
|
|
40
41
|
tol/api_client/validate.py,sha256=9wFZotTJ4fI21BdO5AuMZok0rDQ4s8zM_WojLdVvA0A,3071
|
|
41
|
-
tol/api_client/view.py,sha256=
|
|
42
|
+
tol/api_client/view.py,sha256=DvhRTA957Fn5vVPByV7e8ngvJaD9DSa5SaJ48ONWQlU,8753
|
|
42
43
|
tol/barcodes/__init__.py,sha256=k9KoBO0xJyxg1kanLrN0E3HuVSbbpfSInGEsWX-8UsY,214
|
|
43
44
|
tol/barcodes/main.py,sha256=QxueF2AdrclIaQuu7W4lb4eF5tU_l-p3UMsDFIYgCfo,6213
|
|
44
45
|
tol/benchling/__init__.py,sha256=9VIL6PBxvZRaBrN1j2Di75MdEY261kEHs_D-lUutIlg,229
|
|
@@ -83,24 +84,24 @@ tol/copo/converter.py,sha256=DnJvIysyVLa1b4hIK0o146ruuxKBYhEDN4kxKxl7Uuc,1127
|
|
|
83
84
|
tol/copo/copo_datasource.py,sha256=DYOkaUOO2bdW1rmblci_rt4nBo_1Kb7ztxnthbkC-hA,5193
|
|
84
85
|
tol/copo/factory.py,sha256=fzYpPxro6M9GHER4uyJ5dugxDobPskc-f6RNZpLc4ZY,2219
|
|
85
86
|
tol/copo/parser.py,sha256=FRPF0DQNbHTN_nrar80V9a_-3AapXqUErB47zEP0VUQ,2863
|
|
86
|
-
tol/core/__init__.py,sha256=
|
|
87
|
+
tol/core/__init__.py,sha256=ifE1Ji2RF-RWNzo3HTsEKfLIpkRrIBNBPKDwpvzPoMk,1149
|
|
87
88
|
tol/core/attribute_metadata.py,sha256=wYD3NXDdStrpkUZoyTUiEpp7c14f7MLIcyooT1G4GEQ,4091
|
|
88
89
|
tol/core/core_converter.py,sha256=Gn4J507BtqDjnOWV2MFRYGz8YElJAKQItmnCrD72s7k,4504
|
|
89
90
|
tol/core/data_loader.py,sha256=k-ET1nIohIz6PcADbEn9Y7k9TupoiBYxKDkcAl_9pGY,14710
|
|
90
|
-
tol/core/data_object.py,sha256=
|
|
91
|
-
tol/core/data_object_converter.py,sha256=
|
|
91
|
+
tol/core/data_object.py,sha256=GxG04JMcICaiHU1rufkhoD8jb9YQLhE0QWlFU2ZkQsM,4241
|
|
92
|
+
tol/core/data_object_converter.py,sha256=zIGcin3jcoswBfsuUe74C2nxpyzvhHkP4_ZwKZWxh_Y,3765
|
|
92
93
|
tol/core/data_source_attribute_metadata.py,sha256=NHvJ_Gmw7-Oej1MoFCohvq4f6emDJ2HF483UmW2Qd_c,4407
|
|
93
94
|
tol/core/data_source_dict.py,sha256=d-hSmoWTwG6IOc0cQTLap1EBslsxYIWGUd3ScSoeH_Q,1705
|
|
94
95
|
tol/core/datasource.py,sha256=e9GaeDPfO_Gs7cgQhmNxCiSDlRNf64reegzFebcMNkA,6303
|
|
95
96
|
tol/core/datasource_error.py,sha256=TqfqaPANG0gishadhA7myCmTO1Fg9u7hVZOvsY6BdAo,1660
|
|
96
97
|
tol/core/datasource_filter.py,sha256=RY2S9kTx0XwdrFRSE2n2GohB9__fKGzFVsZrkN5hzQk,726
|
|
97
98
|
tol/core/datasource_utils.py,sha256=18mwvFmtJL73_mxtFb56rKXZCGCtZFoEb8sWFKn3Yf0,6232
|
|
98
|
-
tol/core/factory.py,sha256=
|
|
99
|
+
tol/core/factory.py,sha256=pLLu8l-yK8QaLTt52izMhKZ2VlFHqRQlUHwMaLL6DI4,9156
|
|
99
100
|
tol/core/http_client.py,sha256=05Wa_ySmpm_lC8OkxqXkq6jer0t693GexpaKNQBHufI,2244
|
|
100
101
|
tol/core/relationship.py,sha256=etdyCjLbfi2tgkaqzE6cntpNtTzgT_jOPGeNKmPu5yc,4624
|
|
101
102
|
tol/core/requested_fields.py,sha256=QFNky8QmT1Cmfn42EYPciwbCueJ0DVQNKkP0Vz-_7Jk,6715
|
|
102
103
|
tol/core/session.py,sha256=6AohamIEfB8oV3Z414ishKqmlTgVfUaGYWzvxLgZgM4,3803
|
|
103
|
-
tol/core/validate.py,sha256=
|
|
104
|
+
tol/core/validate.py,sha256=kFRPhgYyeZisGbSXR7S1pmD8jvz_aZ7RX40bT-gD_iA,4083
|
|
104
105
|
tol/core/operator/__init__.py,sha256=ircyLdj45IlaL5k0cDzWHjEr-_66BAx7YRbuEvWF30k,1826
|
|
105
106
|
tol/core/operator/_filterable.py,sha256=61qr-58ZPHWdWl4XKatjW1GPAhN-oqfjRpVtHHkipvA,1238
|
|
106
107
|
tol/core/operator/_writer.py,sha256=eO4qe4myLjScCRnXeILU30MPOLyQiAZbIBQQ_awqB5I,1725
|
|
@@ -132,13 +133,13 @@ tol/eln/entities.py,sha256=3-Z4ibZR11zepz5Nw74PnkpxA_HA31FsRUx61FSPYUo,1209
|
|
|
132
133
|
tol/eln/generators.py,sha256=ghRUiohLakiAcMzGVPJrPxYmdWijs63YxfRTqmKu3Zc,1227
|
|
133
134
|
tol/eln/sanitise.py,sha256=fMj-VrQTnw4zn2X0wnjWQAI8gWAa8RYqNuv23LXQssI,406
|
|
134
135
|
tol/ena/__init__.py,sha256=T3TCqaHpgi2Uk2PjPGu60GaG2V8cTrHJlVLtZfLFhTQ,174
|
|
135
|
-
tol/ena/client.py,sha256=
|
|
136
|
+
tol/ena/client.py,sha256=ldmm7Z9_auQf1zVWjsFLXYgbKvGtSHTsr88YO3zfv2Y,6731
|
|
136
137
|
tol/ena/converter.py,sha256=nxbo4IFzzOvKNMq3Aeiw5iDqVWvY33nTngLppjHAoGY,1144
|
|
137
|
-
tol/ena/ena_datasource.py,sha256=
|
|
138
|
-
tol/ena/ena_methods.py,sha256=
|
|
138
|
+
tol/ena/ena_datasource.py,sha256=jEvyUaH4pfFxmdtn6O_PwOdjPz6u80uAT3SLlR2f5nM,8968
|
|
139
|
+
tol/ena/ena_methods.py,sha256=jgpLssZq-F-vgkO-fYu4jrXenmNkdFpFKAY3VKp5HHE,9209
|
|
139
140
|
tol/ena/factory.py,sha256=3IJCmGLo59PWbGmNqmKho5WYG330OjL8SoZYstIwHt4,3423
|
|
140
141
|
tol/ena/filter.py,sha256=UzOx5ivXvA0TY2QuNzFmS-zDPVNnaAx07DMVkAwVsAE,3370
|
|
141
|
-
tol/ena/parser.py,sha256=
|
|
142
|
+
tol/ena/parser.py,sha256=Z4YmUnpfLKng4QwmZkLEj1hUfwYb_bqr-DWgF1Gw-EY,3253
|
|
142
143
|
tol/excel/__init__.py,sha256=M0xL9w9Au8kYOLWzFGuijJ7WoZENOMkZ1XV1ephhlDY,229
|
|
143
144
|
tol/excel/excel.py,sha256=rcA-wfXY9R14OfNKS-NX2sn__9gmQ_G8LoUgWseF1Gk,2124
|
|
144
145
|
tol/excel/excel_datasource.py,sha256=nIMvkCZ1edx8djqsVsPTRi6yCfyKc_dIokTpLy16rwY,3091
|
|
@@ -147,7 +148,7 @@ tol/flows/__init__.py,sha256=M7iSvnBJs6fJ8M38cW0bYQa9WW0TN8FHAMjIHPDNAJ4,166
|
|
|
147
148
|
tol/flows/logger.py,sha256=rWXbaknGcPEZRFvC1CiB1qkhFRZsQk435w7VyJ3cpyw,170
|
|
148
149
|
tol/flows/secrets.py,sha256=1mlbsxaahzYRfVAx3XdztHOmUCtDMSJDzHysdbaCtj0,352
|
|
149
150
|
tol/flows/sequencing_submissions.py,sha256=ukz_y5be-BCBN2y3JPQ2EK6b3jwOCh-187j-jnw3EUY,11027
|
|
150
|
-
tol/flows/converters/__init__.py,sha256=
|
|
151
|
+
tol/flows/converters/__init__.py,sha256=Ee1yMFWwsRoG71ZFCsqtNwF45AR8farmV9h3ERrK994,6154
|
|
151
152
|
tol/flows/converters/benchling_entity_to_benchling_worklist_item_converter_factory.py,sha256=PN27fcvN4JLBnLrtPPAot1cWjAwPQHVcIDoMfPDeKzU,1210
|
|
152
153
|
tol/flows/converters/benchling_extraction_to_elastic_extraction_converter.py,sha256=S8pbmIeKlcXrLPRJHYBUGP0-Q7jTOV2QQk2TeA2naWo,1966
|
|
153
154
|
tol/flows/converters/benchling_extraction_to_elastic_sequencing_request_converter.py,sha256=2RiyRvGRSWzpUwEI4p-s0afshJpFUUxPqv2z-nyDSVg,1992
|
|
@@ -179,6 +180,8 @@ tol/flows/converters/gap_assembly_to_elastic_assembly_converter.py,sha256=XK-es-
|
|
|
179
180
|
tol/flows/converters/genome_notes_genome_note_to_elastic_genome_note_converter.py,sha256=AaUWbVTaWU-NXnUQPaPwI41TE7a-nC4zlg-jrWpPT2s,1166
|
|
180
181
|
tol/flows/converters/goat_taxon_to_elastic_species_converter.py,sha256=1NGs9427OdXGsBaMB467nOF7aTlJsUKYCuoSoABw9L4,1074
|
|
181
182
|
tol/flows/converters/grit_issue_to_elastic_curation_converter.py,sha256=XpRpoRn589MxTqEk6zPWGn6tamJiqY9Ctxk8v0q-dvA,3953
|
|
183
|
+
tol/flows/converters/incoming_sample_to_ena_sample_converter.py,sha256=HmGsg-VCE4W9Dl3lAlcNhWfkVYp1d22DZlFoTaFzeqA,5560
|
|
184
|
+
tol/flows/converters/incoming_sample_to_incoming_sample_with_lists_converter.py,sha256=5Fp1_ojsYqvRcKTgXJbyWqetPisi_vtWFcWr6RtGZoA,1504
|
|
182
185
|
tol/flows/converters/informatics_tolid_to_elastic_tolid_converter.py,sha256=VrvtsDTPlc5Xa3K4rcAMHwV4n71zOH7q5EfALLLQ1tI,587
|
|
183
186
|
tol/flows/converters/labwhere_location_to_elastic_sample_update_converter.py,sha256=NJNmG9sCc2WXc-2J5XfCKXhb2sDH82nZUBekd16PHcw,656
|
|
184
187
|
tol/flows/converters/labwhere_location_to_sts_tray_converter.py,sha256=dSBP5HfdvyIGvNQD6bhi0RKvkwhN8jq69g-0hOXUqEg,672
|
|
@@ -237,13 +240,11 @@ tol/prefect/factory.py,sha256=mO4KVnaEYMv-ojGJuiencNQMq6PAMU8cIc4QN5Kq8Gw,2208
|
|
|
237
240
|
tol/prefect/filter.py,sha256=aNVTSmcrbb_4EllcFtBOSPuUGgwE-f-Kd5_an6lREtM,7044
|
|
238
241
|
tol/prefect/prefect_datasource.py,sha256=JXLS4odWNWUu4mgojQogwE28mBTAbj-OQYFxhYNYHnM,8865
|
|
239
242
|
tol/prefect/prefect_object.py,sha256=Nn3Y6ErQnXubX7M-GzRsfLHEzdHwKr5RWCjIJ4FA28U,495
|
|
240
|
-
tol/s3/__init__.py,sha256=
|
|
243
|
+
tol/s3/__init__.py,sha256=L2Aa12NAYjTRr8W_ArJi3z3ME2bUtCf4CG3JDw1MoMk,282
|
|
241
244
|
tol/s3/converter.py,sha256=KylGAQvu1jRYJl4dcYK1IgbFsmHP3JXRI22MX8UzHz4,1023
|
|
242
245
|
tol/s3/factory.py,sha256=rFcRVy4B8KVsUaaHhtpLUE90_hRnixkO2IjnB6-arkc,2163
|
|
243
246
|
tol/s3/parser.py,sha256=EOiPYJ8ZLigAxKGL4cC8r7OGyjGdSMHmJMnDqHSiG_E,1907
|
|
244
247
|
tol/s3/s3_datasource.py,sha256=tSUc78FN1OudpJcQ-7FI4S_LPT5j-BYIcwFaQPDy_VA,2072
|
|
245
|
-
tol/s3/data_upload/__init__.py,sha256=4dkK7MPB0CzkkujFSVj0FzoG5ri_usQ7XaBB81Vc_qE,85
|
|
246
|
-
tol/s3/data_upload/blueprint.py,sha256=rwZAXsHe_AJXAdRZVdUhtJg3P3SxOs_G_0F1eewPuT4,2574
|
|
247
248
|
tol/sciops/__init__.py,sha256=PaC1_5wZhsZlqeYQRMpDeIf9L6Hi0eXs_pHXaWfscAo,131
|
|
248
249
|
tol/sciops/configuration.py,sha256=21ddgHOmhZE1tcE-5_f4KiV-7CUqkF8yXi4iBYPtfmc,1279
|
|
249
250
|
tol/sciops/consumer.py,sha256=Ikl8glrZ0yQKBhegC84vwNj43iK1Ca_SAn_gcyAhbKQ,2137
|
|
@@ -293,11 +294,11 @@ tol/sql/exception.py,sha256=8c9KOVVNlLhqKU4CfsnxR7sd-JhEMnCk3TQ-s9JyogM,544
|
|
|
293
294
|
tol/sql/ext.py,sha256=9oYHxR3IXUaG17BwTLWFJ-CjdgFrlm3AclctZ1FP0MQ,1752
|
|
294
295
|
tol/sql/factory.py,sha256=cfHq1iH6wqqn5fI0yfOm59Tw6KiZqA7yXScCKBXBc1c,3408
|
|
295
296
|
tol/sql/filter.py,sha256=O711DnBG7RssQKwZ76fqA8Vm2IN7pzVrigxc1I2G4-Y,15417
|
|
296
|
-
tol/sql/model.py,sha256=
|
|
297
|
+
tol/sql/model.py,sha256=MAsQdw4L-SzCWCNQd3UVufxPuXFV3GmREss-ouWfh0U,12091
|
|
297
298
|
tol/sql/relationship.py,sha256=EClMgVx_If5nZV9MV99TQk7Wr7uACWetwQdWAliM5XI,2891
|
|
298
299
|
tol/sql/session.py,sha256=VmqTegr4L2X2zvaOJCpwSrkVRx8fc1RVL0drkL2MXu8,806
|
|
299
300
|
tol/sql/sort.py,sha256=ENrjHGgj4fZtXKmkdlkv1HRi1X14SVlcl-tp8Pu7G0k,2553
|
|
300
|
-
tol/sql/sql_converter.py,sha256=
|
|
301
|
+
tol/sql/sql_converter.py,sha256=taD5FRwadvw2bBaUGrCIiUs0-ATAbBnRYI1M7xe3yEc,4618
|
|
301
302
|
tol/sql/sql_datasource.py,sha256=jLPQSolGtKRKezjVnMrlj8YO6bLepyiFARMbDYEXuN8,16219
|
|
302
303
|
tol/sql/action/__init__.py,sha256=T1zAsCza_lvsNtXF1ecSLt9OFGup8tGnIs68YylBmXI,142
|
|
303
304
|
tol/sql/action/factory.py,sha256=HkareJp_57ud0_Bdd9Kwz3_Rnq2l211sGJgftohFAHg,3589
|
|
@@ -305,7 +306,7 @@ tol/sql/auth/__init__.py,sha256=e3JuwugXmXobklqZ1Mt1w03qPgb1WdUaJVM7oblzHyk,202
|
|
|
305
306
|
tol/sql/auth/blueprint.py,sha256=u0vT_TC9IMKrg08QFa9W29_83mT0y0jzLj3DvXy1BBw,25906
|
|
306
307
|
tol/sql/auth/models.py,sha256=4xNWBvyGiI3mwRyDY5ty48Bv9178ApQXPR-YjIdCsvk,11879
|
|
307
308
|
tol/sql/pipeline_step/__init__.py,sha256=O7u4RrLfuoB0mwLcPxFoUrdTBZGB_4bE1vWCn5ho-qw,147
|
|
308
|
-
tol/sql/pipeline_step/factory.py,sha256=
|
|
309
|
+
tol/sql/pipeline_step/factory.py,sha256=E5_Bs1379UGlRajKnb77iPmqhXBMemQR1C53SSPjXB4,5134
|
|
309
310
|
tol/sql/standard/__init__.py,sha256=2NbLXFk0rneGZosZ2ESIRcT0WMK0KncmPWaLPqvX-i4,142
|
|
310
311
|
tol/sql/standard/factory.py,sha256=yY8iWmZRMvUqphwnzBeOIQtKGgxsU6AcA7YTz53UYvc,20010
|
|
311
312
|
tol/status/__init__.py,sha256=sBo-j1wCmberl89uryVCBEJk8ohbfsYhaNpIp_brR9Y,146
|
|
@@ -319,15 +320,27 @@ tol/treeval/treeval_datasource.py,sha256=GzY6JwH67b5QdV-UVdCFJfgGAIuZ96J2nl53YxZ
|
|
|
319
320
|
tol/utils/__init__.py,sha256=764-Na1OaNGUDWpMIu51ZtXG7n_nB5MccUFK6LmkWRI,138
|
|
320
321
|
tol/utils/csv.py,sha256=mihww25fSn72c4h-RFeqD_pFIG6KHZP4v1_C0rx81ws,421
|
|
321
322
|
tol/utils/s3.py,sha256=aoYCwJ-qcMqFrpxmViFqPa0O1jgp0phtztO3-0CSNjw,491
|
|
322
|
-
tol/validators/__init__.py,sha256=
|
|
323
|
-
tol/validators/allowed_keys.py,sha256=
|
|
324
|
-
tol/validators/allowed_values.py,sha256=
|
|
325
|
-
tol/validators/
|
|
326
|
-
tol/validators/
|
|
327
|
-
tol/validators/
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
323
|
+
tol/validators/__init__.py,sha256=CcamQvWpywu5aXWc1D9CoZAZcbioRBlNUuTX-XOKqQE,1060
|
|
324
|
+
tol/validators/allowed_keys.py,sha256=fX4KqpxOJNmmVNqQq215MtX27v4dbKSjCM1laXuXfZE,1488
|
|
325
|
+
tol/validators/allowed_values.py,sha256=Sxsb6EhiR8Ey90sfPoyGqkehkJN0hHSNXlLYSL_k5f4,1518
|
|
326
|
+
tol/validators/allowed_values_from_datasource.py,sha256=EqHfaTk8VAMQAra7SfkpZYjFUJm9bee_i73vFwwGG_Y,3169
|
|
327
|
+
tol/validators/assert_on_condition.py,sha256=FCzmN2Crhku0bdEpXuKEbDaoU6RbAZCUDUxQ8OHK92M,2017
|
|
328
|
+
tol/validators/ena_checklist.py,sha256=nxoiJWHKDk2HzeJMKgME_KGNYUBSaCx5jbp4yXQMf00,2875
|
|
329
|
+
tol/validators/ena_submittable.py,sha256=ruryfVcQtRJ5JsAFBcVZ_3hzTDwRWGXpdPUAfdrYmWg,1948
|
|
330
|
+
tol/validators/min_one_valid_value.py,sha256=3Fv-b-fojvPLpiWwUqrFfO0YMGtV40KEp15zTmdOlyI,1425
|
|
331
|
+
tol/validators/mutually_exclusive.py,sha256=76AqX4G_syKAbFyDgydbcMHvNAroENazrcWbR5vAN30,4482
|
|
332
|
+
tol/validators/regex.py,sha256=L8ap5oxn_54DoE7Tnqo1VjQ-dr5-fJAe7cCHYg8cBzw,2523
|
|
333
|
+
tol/validators/regex_by_value.py,sha256=bSPloXfeOUMuiSQH-_GkvQ6IiD3Q1fojT0iydlkLanI,2564
|
|
334
|
+
tol/validators/specimens_have_same_taxon.py,sha256=BrkYXhr1KVnJcDe-PrKXf0AF9740BbFV2XVMrtu98CQ,2167
|
|
335
|
+
tol/validators/sts_fields.py,sha256=piHqdzuGepIEv-ZSSwdkYE6ybQpqc4hBN8hN8UrN4Vg,3442
|
|
336
|
+
tol/validators/tolid.py,sha256=gHiaNQGWHos4I6Rz7aKCOATbv0ff8qL4LdObnZ_Lgt8,3876
|
|
337
|
+
tol/validators/unique_values.py,sha256=CZvIdg7GC2VmVAGuPToxJ_r-2YCwy2xkQKp2qwVwbzU,3096
|
|
338
|
+
tol/validators/unique_whole_organisms.py,sha256=Z-PUjlCcn-WHDKMYDyt_WhalXzQFfqLWItM6qywVt_Y,5725
|
|
339
|
+
tol/validators/interfaces/__init__.py,sha256=jtOxnwnwqV_29xjmmMcS_kvlt-pQiWwQYJn2YRP07_w,172
|
|
340
|
+
tol/validators/interfaces/condition_evaluator.py,sha256=nj8Cb8hi47OBy6OVNfeLhF-Pjwtr8MiOSymYL6hfVes,3766
|
|
341
|
+
tol_sdk-1.7.5b2.dist-info/licenses/LICENSE,sha256=RF9Jacy-9BpUAQQ20INhTgtaNBkmdTolYCHtrrkM2-8,1077
|
|
342
|
+
tol_sdk-1.7.5b2.dist-info/METADATA,sha256=FxtTjGw1IxkHprv89dW071kyQ68kiR9sxu-QdfLaF1g,3081
|
|
343
|
+
tol_sdk-1.7.5b2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
344
|
+
tol_sdk-1.7.5b2.dist-info/entry_points.txt,sha256=jH3HfTwxjzog7E3lq8CKpUWGIRY9FSXbyL6CpUmv6D0,36
|
|
345
|
+
tol_sdk-1.7.5b2.dist-info/top_level.txt,sha256=PwKMQLphyZNvagBoriVbl8uwHXQl8IC1niawVG0iXMM,10
|
|
346
|
+
tol_sdk-1.7.5b2.dist-info/RECORD,,
|
tol/s3/data_upload/__init__.py
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|