aind-data-transfer-service 1.17.2__tar.gz → 1.18.0__tar.gz
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 aind-data-transfer-service might be problematic. Click here for more details.
- {aind_data_transfer_service-1.17.2/src/aind_data_transfer_service.egg-info → aind_data_transfer_service-1.18.0}/PKG-INFO +4 -6
- {aind_data_transfer_service-1.17.2 → aind_data_transfer_service-1.18.0}/pyproject.toml +3 -5
- {aind_data_transfer_service-1.17.2 → aind_data_transfer_service-1.18.0}/src/aind_data_transfer_service/__init__.py +2 -1
- {aind_data_transfer_service-1.17.2 → aind_data_transfer_service-1.18.0}/src/aind_data_transfer_service/configs/csv_handler.py +10 -5
- {aind_data_transfer_service-1.17.2 → aind_data_transfer_service-1.18.0}/src/aind_data_transfer_service/configs/job_upload_template.py +2 -1
- aind_data_transfer_service-1.18.0/src/aind_data_transfer_service/configs/platforms_v1.py +177 -0
- {aind_data_transfer_service-1.17.2 → aind_data_transfer_service-1.18.0}/src/aind_data_transfer_service/log_handler.py +3 -3
- {aind_data_transfer_service-1.17.2 → aind_data_transfer_service-1.18.0}/src/aind_data_transfer_service/models/core.py +25 -4
- {aind_data_transfer_service-1.17.2 → aind_data_transfer_service-1.18.0}/src/aind_data_transfer_service/server.py +174 -447
- {aind_data_transfer_service-1.17.2 → aind_data_transfer_service-1.18.0/src/aind_data_transfer_service.egg-info}/PKG-INFO +4 -6
- {aind_data_transfer_service-1.17.2 → aind_data_transfer_service-1.18.0}/src/aind_data_transfer_service.egg-info/SOURCES.txt +2 -7
- {aind_data_transfer_service-1.17.2 → aind_data_transfer_service-1.18.0}/src/aind_data_transfer_service.egg-info/requires.txt +2 -4
- {aind_data_transfer_service-1.17.2 → aind_data_transfer_service-1.18.0}/tests/test_core.py +33 -7
- {aind_data_transfer_service-1.17.2 → aind_data_transfer_service-1.18.0}/tests/test_csv_handler.py +1 -1
- aind_data_transfer_service-1.18.0/tests/test_proxy.py +54 -0
- {aind_data_transfer_service-1.17.2 → aind_data_transfer_service-1.18.0}/tests/test_server.py +78 -768
- aind_data_transfer_service-1.17.2/src/aind_data_transfer_service/configs/job_configs.py +0 -545
- aind_data_transfer_service-1.17.2/src/aind_data_transfer_service/hpc/__init__.py +0 -1
- aind_data_transfer_service-1.17.2/src/aind_data_transfer_service/hpc/client.py +0 -154
- aind_data_transfer_service-1.17.2/src/aind_data_transfer_service/hpc/models.py +0 -492
- aind_data_transfer_service-1.17.2/tests/test_configs.py +0 -361
- aind_data_transfer_service-1.17.2/tests/test_hpc_client.py +0 -174
- aind_data_transfer_service-1.17.2/tests/test_hpc_models.py +0 -139
- {aind_data_transfer_service-1.17.2 → aind_data_transfer_service-1.18.0}/LICENSE +0 -0
- {aind_data_transfer_service-1.17.2 → aind_data_transfer_service-1.18.0}/README.md +0 -0
- {aind_data_transfer_service-1.17.2 → aind_data_transfer_service-1.18.0}/setup.cfg +0 -0
- {aind_data_transfer_service-1.17.2 → aind_data_transfer_service-1.18.0}/setup.py +0 -0
- {aind_data_transfer_service-1.17.2 → aind_data_transfer_service-1.18.0}/src/aind_data_transfer_service/configs/__init__.py +0 -0
- {aind_data_transfer_service-1.17.2 → aind_data_transfer_service-1.18.0}/src/aind_data_transfer_service/models/__init__.py +0 -0
- {aind_data_transfer_service-1.17.2 → aind_data_transfer_service-1.18.0}/src/aind_data_transfer_service/models/internal.py +0 -0
- {aind_data_transfer_service-1.17.2 → aind_data_transfer_service-1.18.0}/src/aind_data_transfer_service.egg-info/dependency_links.txt +0 -0
- {aind_data_transfer_service-1.17.2 → aind_data_transfer_service-1.18.0}/src/aind_data_transfer_service.egg-info/top_level.txt +0 -0
- {aind_data_transfer_service-1.17.2 → aind_data_transfer_service-1.18.0}/tests/test_internal.py +0 -0
- {aind_data_transfer_service-1.17.2 → aind_data_transfer_service-1.18.0}/tests/test_job_upload_template.py +0 -0
- {aind_data_transfer_service-1.17.2 → aind_data_transfer_service-1.18.0}/tests/test_log_handler.py +0 -0
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aind-data-transfer-service
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.18.0
|
|
4
4
|
Summary: Service that handles requests to upload data to the cloud
|
|
5
5
|
Author: Allen Institute for Neural Dynamics
|
|
6
6
|
License: MIT
|
|
7
7
|
Classifier: Programming Language :: Python :: 3
|
|
8
|
-
Requires-Python: >=3.
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
9
|
Description-Content-Type: text/markdown
|
|
10
10
|
License-File: LICENSE
|
|
11
|
-
Requires-Dist: aind-data-schema-models
|
|
11
|
+
Requires-Dist: aind-data-schema-models>=0.3.2
|
|
12
12
|
Requires-Dist: email-validator
|
|
13
13
|
Requires-Dist: pydantic>=2.0
|
|
14
14
|
Requires-Dist: pydantic-settings>=2.0
|
|
@@ -23,9 +23,7 @@ Provides-Extra: docs
|
|
|
23
23
|
Requires-Dist: Sphinx; extra == "docs"
|
|
24
24
|
Requires-Dist: furo; extra == "docs"
|
|
25
25
|
Provides-Extra: server
|
|
26
|
-
Requires-Dist: aind-data-schema
|
|
27
|
-
Requires-Dist: aind-data-transfer-models==0.17.0; extra == "server"
|
|
28
|
-
Requires-Dist: aind-metadata-mapper>=0.23.0; extra == "server"
|
|
26
|
+
Requires-Dist: aind-data-schema==2.0.0; extra == "server"
|
|
29
27
|
Requires-Dist: boto3; extra == "server"
|
|
30
28
|
Requires-Dist: boto3-stubs[ssm]; extra == "server"
|
|
31
29
|
Requires-Dist: fastapi>=0.115.13; extra == "server"
|
|
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
|
|
|
6
6
|
name = "aind-data-transfer-service"
|
|
7
7
|
description = "Service that handles requests to upload data to the cloud"
|
|
8
8
|
license = {text = "MIT"}
|
|
9
|
-
requires-python = ">=3.
|
|
9
|
+
requires-python = ">=3.10"
|
|
10
10
|
authors = [
|
|
11
11
|
{name = "Allen Institute for Neural Dynamics"}
|
|
12
12
|
]
|
|
@@ -17,7 +17,7 @@ readme = "README.md"
|
|
|
17
17
|
dynamic = ["version"]
|
|
18
18
|
|
|
19
19
|
dependencies = [
|
|
20
|
-
'aind-data-schema-models>=0.3.2
|
|
20
|
+
'aind-data-schema-models>=0.3.2',
|
|
21
21
|
'email-validator',
|
|
22
22
|
'pydantic>=2.0',
|
|
23
23
|
'pydantic-settings>=2.0',
|
|
@@ -39,9 +39,7 @@ docs = [
|
|
|
39
39
|
]
|
|
40
40
|
|
|
41
41
|
server = [
|
|
42
|
-
'aind-data-schema
|
|
43
|
-
'aind-data-transfer-models==0.17.0',
|
|
44
|
-
'aind-metadata-mapper>=0.23.0',
|
|
42
|
+
'aind-data-schema==2.0.0',
|
|
45
43
|
'boto3',
|
|
46
44
|
'boto3-stubs[ssm]',
|
|
47
45
|
'fastapi>=0.115.13',
|
|
@@ -7,8 +7,8 @@ from datetime import datetime
|
|
|
7
7
|
from typing import Any, Dict
|
|
8
8
|
|
|
9
9
|
from aind_data_schema_models.modalities import Modality
|
|
10
|
-
from aind_data_schema_models.platforms import Platform
|
|
11
10
|
|
|
11
|
+
from aind_data_transfer_service.configs.platforms_v1 import Platform
|
|
12
12
|
from aind_data_transfer_service.models.core import Task, UploadJobConfigsV2
|
|
13
13
|
|
|
14
14
|
DATETIME_PATTERN2 = re.compile(
|
|
@@ -147,13 +147,18 @@ def map_csv_row_to_job(row: dict) -> UploadJobConfigsV2:
|
|
|
147
147
|
"gather_preliminary_metadata": metadata_task,
|
|
148
148
|
"check_s3_folder_exists": check_s3_folder_exists_task,
|
|
149
149
|
"modality_transformation_settings": modality_tasks,
|
|
150
|
-
"codeocean_pipeline_settings":
|
|
151
|
-
|
|
152
|
-
|
|
150
|
+
"codeocean_pipeline_settings": (
|
|
151
|
+
None if codeocean_tasks == dict() else codeocean_tasks
|
|
152
|
+
),
|
|
153
153
|
}
|
|
154
|
+
platform = (
|
|
155
|
+
None
|
|
156
|
+
if job_configs.get("platform") is None
|
|
157
|
+
else Platform.from_abbreviation(job_configs["platform"])
|
|
158
|
+
)
|
|
154
159
|
job_configs.update(
|
|
155
160
|
{
|
|
156
|
-
"platform":
|
|
161
|
+
"platform": platform,
|
|
157
162
|
"modalities": [
|
|
158
163
|
Modality.from_abbreviation(m) for m in modality_tasks.keys()
|
|
159
164
|
],
|
|
@@ -5,13 +5,14 @@ from io import BytesIO
|
|
|
5
5
|
from typing import Any, ClassVar, Dict, List
|
|
6
6
|
|
|
7
7
|
from aind_data_schema_models.modalities import Modality
|
|
8
|
-
from aind_data_schema_models.platforms import Platform
|
|
9
8
|
from openpyxl import Workbook
|
|
10
9
|
from openpyxl.styles import Font
|
|
11
10
|
from openpyxl.utils import get_column_letter
|
|
12
11
|
from openpyxl.worksheet.datavalidation import DataValidation
|
|
13
12
|
from pydantic import BaseModel
|
|
14
13
|
|
|
14
|
+
from aind_data_transfer_service.configs.platforms_v1 import Platform
|
|
15
|
+
|
|
15
16
|
|
|
16
17
|
class JobUploadTemplate(BaseModel):
|
|
17
18
|
"""Class to configure and create xlsx job upload template"""
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"""Platforms"""
|
|
2
|
+
|
|
3
|
+
from typing import Literal, Union
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
6
|
+
from typing_extensions import Annotated
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class _PlatformModel(BaseModel):
|
|
10
|
+
"""Base model for platform"""
|
|
11
|
+
|
|
12
|
+
model_config = ConfigDict(frozen=True)
|
|
13
|
+
name: str
|
|
14
|
+
abbreviation: str
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class _Behavior(_PlatformModel):
|
|
18
|
+
"""Model behavior"""
|
|
19
|
+
|
|
20
|
+
name: Literal["Behavior platform"] = "Behavior platform"
|
|
21
|
+
abbreviation: Literal["behavior"] = "behavior"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class _Confocal(_PlatformModel):
|
|
25
|
+
"""Model confocal"""
|
|
26
|
+
|
|
27
|
+
name: Literal["Confocal microscopy platform"] = (
|
|
28
|
+
"Confocal microscopy platform"
|
|
29
|
+
)
|
|
30
|
+
abbreviation: Literal["confocal"] = "confocal"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class _Ecephys(_PlatformModel):
|
|
34
|
+
"""Model ecephys"""
|
|
35
|
+
|
|
36
|
+
name: Literal["Electrophysiology platform"] = "Electrophysiology platform"
|
|
37
|
+
abbreviation: Literal["ecephys"] = "ecephys"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class _Exaspim(_PlatformModel):
|
|
41
|
+
"""Model exaSPIM"""
|
|
42
|
+
|
|
43
|
+
name: Literal["ExaSPIM platform"] = "ExaSPIM platform"
|
|
44
|
+
abbreviation: Literal["exaSPIM"] = "exaSPIM"
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class _Fip(_PlatformModel):
|
|
48
|
+
"""Model FIP"""
|
|
49
|
+
|
|
50
|
+
name: Literal["Frame-projected independent-fiber photometry platform"] = (
|
|
51
|
+
"Frame-projected independent-fiber photometry platform"
|
|
52
|
+
)
|
|
53
|
+
abbreviation: Literal["FIP"] = "FIP"
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class _Hcr(_PlatformModel):
|
|
57
|
+
"""Model HCR"""
|
|
58
|
+
|
|
59
|
+
name: Literal["Hybridization chain reaction platform"] = (
|
|
60
|
+
"Hybridization chain reaction platform"
|
|
61
|
+
)
|
|
62
|
+
abbreviation: Literal["HCR"] = "HCR"
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class _Hsfp(_PlatformModel):
|
|
66
|
+
"""Model HSFP"""
|
|
67
|
+
|
|
68
|
+
name: Literal["Hyperspectral fiber photometry platform"] = (
|
|
69
|
+
"Hyperspectral fiber photometry platform"
|
|
70
|
+
)
|
|
71
|
+
abbreviation: Literal["HSFP"] = "HSFP"
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class _Isi(_PlatformModel):
|
|
75
|
+
"""Model ISI"""
|
|
76
|
+
|
|
77
|
+
name: Literal["Intrinsic signal imaging platform"] = (
|
|
78
|
+
"Intrinsic signal imaging platform"
|
|
79
|
+
)
|
|
80
|
+
abbreviation: Literal["ISI"] = "ISI"
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class _Merfish(_PlatformModel):
|
|
84
|
+
"""Model MERFISH"""
|
|
85
|
+
|
|
86
|
+
name: Literal["MERFISH platform"] = "MERFISH platform"
|
|
87
|
+
abbreviation: Literal["MERFISH"] = "MERFISH"
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class _Mri(_PlatformModel):
|
|
91
|
+
"""Model MRI"""
|
|
92
|
+
|
|
93
|
+
name: Literal["Magnetic resonance imaging platform"] = (
|
|
94
|
+
"Magnetic resonance imaging platform"
|
|
95
|
+
)
|
|
96
|
+
abbreviation: Literal["MRI"] = "MRI"
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class _Mesospim(_PlatformModel):
|
|
100
|
+
"""Model mesoSPIM"""
|
|
101
|
+
|
|
102
|
+
name: Literal["MesoSPIM platform"] = "MesoSPIM platform"
|
|
103
|
+
abbreviation: Literal["mesoSPIM"] = "mesoSPIM"
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
class _Motor_Observatory(_PlatformModel):
|
|
107
|
+
"""Model motor-observatory"""
|
|
108
|
+
|
|
109
|
+
name: Literal["Motor observatory platform"] = "Motor observatory platform"
|
|
110
|
+
abbreviation: Literal["motor-observatory"] = "motor-observatory"
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class _Multiplane_Ophys(_PlatformModel):
|
|
114
|
+
"""Model multiplane-ophys"""
|
|
115
|
+
|
|
116
|
+
name: Literal["Multiplane optical physiology platform"] = (
|
|
117
|
+
"Multiplane optical physiology platform"
|
|
118
|
+
)
|
|
119
|
+
abbreviation: Literal["multiplane-ophys"] = "multiplane-ophys"
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class _Slap2(_PlatformModel):
|
|
123
|
+
"""Model SLAP2"""
|
|
124
|
+
|
|
125
|
+
name: Literal["SLAP2 platform"] = "SLAP2 platform"
|
|
126
|
+
abbreviation: Literal["SLAP2"] = "SLAP2"
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class _Single_Plane_Ophys(_PlatformModel):
|
|
130
|
+
"""Model single-plane-ophys"""
|
|
131
|
+
|
|
132
|
+
name: Literal["Single-plane optical physiology platform"] = (
|
|
133
|
+
"Single-plane optical physiology platform"
|
|
134
|
+
)
|
|
135
|
+
abbreviation: Literal["single-plane-ophys"] = "single-plane-ophys"
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class _Smartspim(_PlatformModel):
|
|
139
|
+
"""Model SmartSPIM"""
|
|
140
|
+
|
|
141
|
+
name: Literal["SmartSPIM platform"] = "SmartSPIM platform"
|
|
142
|
+
abbreviation: Literal["SmartSPIM"] = "SmartSPIM"
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
class Platform:
|
|
146
|
+
"""Platforms"""
|
|
147
|
+
|
|
148
|
+
BEHAVIOR = _Behavior()
|
|
149
|
+
CONFOCAL = _Confocal()
|
|
150
|
+
ECEPHYS = _Ecephys()
|
|
151
|
+
EXASPIM = _Exaspim()
|
|
152
|
+
FIP = _Fip()
|
|
153
|
+
HCR = _Hcr()
|
|
154
|
+
HSFP = _Hsfp()
|
|
155
|
+
ISI = _Isi()
|
|
156
|
+
MERFISH = _Merfish()
|
|
157
|
+
MRI = _Mri()
|
|
158
|
+
MESOSPIM = _Mesospim()
|
|
159
|
+
MOTOR_OBSERVATORY = _Motor_Observatory()
|
|
160
|
+
MULTIPLANE_OPHYS = _Multiplane_Ophys()
|
|
161
|
+
SLAP2 = _Slap2()
|
|
162
|
+
SINGLE_PLANE_OPHYS = _Single_Plane_Ophys()
|
|
163
|
+
SMARTSPIM = _Smartspim()
|
|
164
|
+
|
|
165
|
+
ALL = tuple(_PlatformModel.__subclasses__())
|
|
166
|
+
|
|
167
|
+
ONE_OF = Annotated[
|
|
168
|
+
Union[tuple(_PlatformModel.__subclasses__())],
|
|
169
|
+
Field(discriminator="name"),
|
|
170
|
+
]
|
|
171
|
+
|
|
172
|
+
abbreviation_map = {m().abbreviation: m() for m in ALL}
|
|
173
|
+
|
|
174
|
+
@classmethod
|
|
175
|
+
def from_abbreviation(cls, abbreviation: str):
|
|
176
|
+
"""Get platform from abbreviation"""
|
|
177
|
+
return cls.abbreviation_map.get(abbreviation, None)
|
|
@@ -17,9 +17,9 @@ class LoggingConfigs(BaseSettings):
|
|
|
17
17
|
loki_uri: Optional[str] = Field(
|
|
18
18
|
default=None, description="URI of Loki logging server."
|
|
19
19
|
)
|
|
20
|
-
log_level: Literal[
|
|
21
|
-
"DEBUG", "
|
|
22
|
-
|
|
20
|
+
log_level: Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] = (
|
|
21
|
+
Field(default="DEBUG", description="Log level")
|
|
22
|
+
)
|
|
23
23
|
|
|
24
24
|
@property
|
|
25
25
|
def app_name(self):
|
|
@@ -8,7 +8,6 @@ from typing import Any, Dict, List, Literal, Optional, Set, Union
|
|
|
8
8
|
|
|
9
9
|
from aind_data_schema_models.data_name_patterns import build_data_name
|
|
10
10
|
from aind_data_schema_models.modalities import Modality
|
|
11
|
-
from aind_data_schema_models.platforms import Platform
|
|
12
11
|
from pydantic import (
|
|
13
12
|
BaseModel,
|
|
14
13
|
ConfigDict,
|
|
@@ -21,6 +20,8 @@ from pydantic import (
|
|
|
21
20
|
)
|
|
22
21
|
from pydantic_settings import BaseSettings
|
|
23
22
|
|
|
23
|
+
from aind_data_transfer_service.configs.platforms_v1 import Platform
|
|
24
|
+
|
|
24
25
|
_validation_context: ContextVar[Union[Dict[str, Any], None]] = ContextVar(
|
|
25
26
|
"_validation_context", default=None
|
|
26
27
|
)
|
|
@@ -163,8 +164,13 @@ class UploadJobConfigsV2(BaseSettings):
|
|
|
163
164
|
project_name: str = Field(
|
|
164
165
|
..., description="Name of project", title="Project Name"
|
|
165
166
|
)
|
|
166
|
-
platform: Platform.ONE_OF = Field(
|
|
167
|
-
|
|
167
|
+
platform: Optional[Platform.ONE_OF] = Field(
|
|
168
|
+
default=None,
|
|
169
|
+
title="Platform",
|
|
170
|
+
description=(
|
|
171
|
+
"Legacy field required for aind-data-schema v1. Will be removed"
|
|
172
|
+
" in future versions."
|
|
173
|
+
),
|
|
168
174
|
)
|
|
169
175
|
modalities: List[Modality.ONE_OF] = Field(
|
|
170
176
|
...,
|
|
@@ -190,11 +196,26 @@ class UploadJobConfigsV2(BaseSettings):
|
|
|
190
196
|
@computed_field
|
|
191
197
|
def s3_prefix(self) -> str:
|
|
192
198
|
"""Construct s3_prefix from configs."""
|
|
199
|
+
if self.platform is not None:
|
|
200
|
+
label = f"{self.platform.abbreviation}_{self.subject_id}"
|
|
201
|
+
else:
|
|
202
|
+
label = self.subject_id
|
|
193
203
|
return build_data_name(
|
|
194
|
-
label=
|
|
204
|
+
label=label,
|
|
195
205
|
creation_datetime=self.acq_datetime,
|
|
196
206
|
)
|
|
197
207
|
|
|
208
|
+
@field_validator("platform", mode="before")
|
|
209
|
+
def validate_platform(cls, v):
|
|
210
|
+
"""
|
|
211
|
+
For backwards compatibility, allow a user to input an
|
|
212
|
+
aind-data-schema-model platform and then convert it.
|
|
213
|
+
"""
|
|
214
|
+
if type(v).__module__ == "aind_data_schema_models.platforms":
|
|
215
|
+
return v.model_dump()
|
|
216
|
+
else:
|
|
217
|
+
return v
|
|
218
|
+
|
|
198
219
|
@field_validator("job_type", "project_name", mode="before")
|
|
199
220
|
def validate_with_context(cls, v: str, info: ValidationInfo) -> str:
|
|
200
221
|
"""
|