aind-data-transfer-service 1.15.0__tar.gz → 1.16.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.15.0/src/aind_data_transfer_service.egg-info → aind_data_transfer_service-1.16.0}/PKG-INFO +3 -3
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/examples/remove_source_folders.py +1 -1
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/pyproject.toml +2 -2
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/src/aind_data_transfer_service/__init__.py +1 -1
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/src/aind_data_transfer_service/configs/csv_handler.py +57 -6
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/src/aind_data_transfer_service/server.py +15 -9
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0/src/aind_data_transfer_service.egg-info}/PKG-INFO +3 -3
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/src/aind_data_transfer_service.egg-info/SOURCES.txt +1 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/src/aind_data_transfer_service.egg-info/requires.txt +2 -2
- aind_data_transfer_service-1.16.0/tests/resources/nested_sample.csv +2 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/test_csv_handler.py +63 -5
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/.flake8 +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/.github/ISSUE_TEMPLATE/user-story.md +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/.github/workflows/add_issue_to_project_board.yml +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/.github/workflows/publish_dev.yml +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/.github/workflows/publish_main.yml +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/.github/workflows/run_dev_tests.yml +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/.github/workflows/run_main_tests.yml +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/.gitignore +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/.readthedocs.yaml +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/CODE_OF_CONDUCT.md +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/Dockerfile +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/LICENSE +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/README.md +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/Makefile +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/diagrams/system_container.png +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/diagrams/system_container.puml +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/diagrams/system_context.png +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/diagrams/system_context.puml +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/examples/basic_upload.py +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/examples/behavior_videos_compression.py +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/examples/custom_codeocean_pipeline_settings.py +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/examples/custom_metadata_mapper_settings.py +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/examples/example1.csv +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/examples/hcr_example.py +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/examples/skip_s3_check.py +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/examples/upload_with_custom_slurm_settings.py +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/examples/upload_with_notification.py +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/make.bat +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/source/Contributing.rst +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/source/UserGuideV1.rst +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/source/UserGuideV2.rst +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/source/_static/dark-logo.svg +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/source/_static/favicon.ico +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/source/_static/light-logo.svg +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/source/aind_data_transfer_service.configs.rst +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/source/aind_data_transfer_service.hpc.rst +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/source/aind_data_transfer_service.models.rst +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/source/aind_data_transfer_service.rst +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/source/conf.py +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/source/index.rst +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/source/modules.rst +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/setup.cfg +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/setup.py +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/src/aind_data_transfer_service/configs/__init__.py +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/src/aind_data_transfer_service/configs/job_configs.py +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/src/aind_data_transfer_service/configs/job_upload_template.py +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/src/aind_data_transfer_service/hpc/__init__.py +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/src/aind_data_transfer_service/hpc/client.py +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/src/aind_data_transfer_service/hpc/models.py +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/src/aind_data_transfer_service/log_handler.py +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/src/aind_data_transfer_service/models/__init__.py +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/src/aind_data_transfer_service/models/core.py +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/src/aind_data_transfer_service/models/internal.py +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/src/aind_data_transfer_service/templates/admin.html +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/src/aind_data_transfer_service/templates/index.html +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/src/aind_data_transfer_service/templates/job_params.html +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/src/aind_data_transfer_service/templates/job_status.html +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/src/aind_data_transfer_service/templates/job_tasks_table.html +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/src/aind_data_transfer_service/templates/task_logs.html +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/src/aind_data_transfer_service.egg-info/dependency_links.txt +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/src/aind_data_transfer_service.egg-info/top_level.txt +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/__init__.py +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/resources/airflow_dag_run_response.json +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/resources/airflow_dag_runs_response.json +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/resources/airflow_task_instances_response.json +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/resources/describe_parameters_response.json +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/resources/get_parameter_response.json +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/resources/get_secrets_response.json +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/resources/job_upload_template.xlsx +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/resources/legacy_sample.csv +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/resources/legacy_sample2.csv +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/resources/new_sample.csv +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/resources/sample.csv +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/resources/sample.xlsx +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/resources/sample_alt_modality_case.csv +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/resources/sample_empty_rows.csv +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/resources/sample_empty_rows.xlsx +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/resources/sample_empty_rows_2.csv +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/resources/sample_invalid_ext.txt +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/resources/sample_malformed.csv +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/resources/sample_malformed.xlsx +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/resources/sample_malformed_2.csv +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/test_configs.py +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/test_core.py +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/test_hpc_client.py +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/test_hpc_models.py +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/test_internal.py +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/test_job_upload_template.py +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/test_log_handler.py +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/test_server/Dockerfile +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/test_server/db.json +0 -0
- {aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/test_server.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aind-data-transfer-service
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.16.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
|
|
@@ -28,10 +28,10 @@ Requires-Dist: aind-data-transfer-models==0.17.0; extra == "server"
|
|
|
28
28
|
Requires-Dist: aind-metadata-mapper==0.23.0; extra == "server"
|
|
29
29
|
Requires-Dist: boto3; extra == "server"
|
|
30
30
|
Requires-Dist: boto3-stubs[ssm]; extra == "server"
|
|
31
|
-
Requires-Dist: fastapi; extra == "server"
|
|
31
|
+
Requires-Dist: fastapi>=0.115.13; extra == "server"
|
|
32
32
|
Requires-Dist: httpx; extra == "server"
|
|
33
33
|
Requires-Dist: jinja2; extra == "server"
|
|
34
|
-
Requires-Dist: starlette; extra == "server"
|
|
34
|
+
Requires-Dist: starlette<0.47.0,>=0.40.0; extra == "server"
|
|
35
35
|
Requires-Dist: starlette_wtf; extra == "server"
|
|
36
36
|
Requires-Dist: uvicorn[standard]; extra == "server"
|
|
37
37
|
Requires-Dist: wtforms; extra == "server"
|
|
@@ -55,7 +55,7 @@ upload_job_configs_v2 = UploadJobConfigsV2(
|
|
|
55
55
|
tasks={
|
|
56
56
|
"modality_transformation_settings": modality_transformation_settings,
|
|
57
57
|
"gather_preliminary_metadata": gather_preliminary_metadata,
|
|
58
|
-
"remove_source_folders": remove_source_folders
|
|
58
|
+
"remove_source_folders": remove_source_folders,
|
|
59
59
|
},
|
|
60
60
|
)
|
|
61
61
|
|
|
@@ -44,10 +44,10 @@ server = [
|
|
|
44
44
|
'aind-metadata-mapper==0.23.0',
|
|
45
45
|
'boto3',
|
|
46
46
|
'boto3-stubs[ssm]',
|
|
47
|
-
'fastapi',
|
|
47
|
+
'fastapi>=0.115.13',
|
|
48
48
|
'httpx',
|
|
49
49
|
'jinja2',
|
|
50
|
-
'starlette',
|
|
50
|
+
'starlette>=0.40.0,<0.47.0',
|
|
51
51
|
'starlette_wtf',
|
|
52
52
|
'uvicorn[standard]',
|
|
53
53
|
'wtforms',
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
"""Module to handle processing legacy csv files"""
|
|
2
2
|
|
|
3
3
|
import re
|
|
4
|
+
from collections.abc import Mapping
|
|
5
|
+
from copy import deepcopy
|
|
4
6
|
from datetime import datetime
|
|
7
|
+
from typing import Any, Dict
|
|
5
8
|
|
|
6
9
|
from aind_data_schema_models.modalities import Modality
|
|
7
10
|
from aind_data_schema_models.platforms import Platform
|
|
@@ -13,6 +16,45 @@ DATETIME_PATTERN2 = re.compile(
|
|
|
13
16
|
)
|
|
14
17
|
|
|
15
18
|
|
|
19
|
+
def nested_update(dict_to_update: Dict[str, Any], updates: Mapping):
|
|
20
|
+
"""
|
|
21
|
+
Update a nested dictionary in-place.
|
|
22
|
+
Parameters
|
|
23
|
+
----------
|
|
24
|
+
dict_to_update : Dict[str, Any]
|
|
25
|
+
updates : Mapping
|
|
26
|
+
|
|
27
|
+
"""
|
|
28
|
+
for k, v in updates.items():
|
|
29
|
+
if isinstance(v, Mapping):
|
|
30
|
+
dict_to_update[k] = nested_update(dict_to_update.get(k, {}), v)
|
|
31
|
+
else:
|
|
32
|
+
dict_to_update[k] = v
|
|
33
|
+
return dict_to_update
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def create_nested_dict(
|
|
37
|
+
dict_to_update: Dict[str, Any], key_string: str, value: Any
|
|
38
|
+
):
|
|
39
|
+
"""
|
|
40
|
+
Updates in-place a nested dictionary with a period delimited key and value.
|
|
41
|
+
Parameters
|
|
42
|
+
----------
|
|
43
|
+
dict_to_update : Dict[str, Any]
|
|
44
|
+
key_string : str
|
|
45
|
+
value : Any
|
|
46
|
+
|
|
47
|
+
"""
|
|
48
|
+
keys = key_string.split(".", 1)
|
|
49
|
+
current_key = keys[0]
|
|
50
|
+
if len(keys) == 1:
|
|
51
|
+
dict_to_update[current_key] = value
|
|
52
|
+
else:
|
|
53
|
+
if current_key not in dict_to_update:
|
|
54
|
+
dict_to_update[current_key] = dict()
|
|
55
|
+
create_nested_dict(dict_to_update[current_key], keys[1], value)
|
|
56
|
+
|
|
57
|
+
|
|
16
58
|
def map_csv_row_to_job(row: dict) -> UploadJobConfigsV2:
|
|
17
59
|
"""
|
|
18
60
|
Maps csv row into a UploadJobConfigsV2 model. This attempts to be somewhat
|
|
@@ -29,7 +71,6 @@ def map_csv_row_to_job(row: dict) -> UploadJobConfigsV2:
|
|
|
29
71
|
modality_configs = dict()
|
|
30
72
|
job_configs = dict()
|
|
31
73
|
check_s3_folder_exists_task = None
|
|
32
|
-
final_check_s3_folder_exist = None
|
|
33
74
|
codeocean_tasks = dict()
|
|
34
75
|
for key, value in row.items():
|
|
35
76
|
# Strip white spaces and replace dashes with underscores
|
|
@@ -42,7 +83,9 @@ def map_csv_row_to_job(row: dict) -> UploadJobConfigsV2:
|
|
|
42
83
|
modality_parts = clean_key.split(".")
|
|
43
84
|
modality_key = modality_parts[0]
|
|
44
85
|
sub_key = (
|
|
45
|
-
"modality"
|
|
86
|
+
"modality"
|
|
87
|
+
if len(modality_parts) == 1
|
|
88
|
+
else ".".join(modality_parts[1:])
|
|
46
89
|
)
|
|
47
90
|
modality_configs.setdefault(modality_key, dict())
|
|
48
91
|
# Temp backwards compatibility check
|
|
@@ -66,13 +109,22 @@ def map_csv_row_to_job(row: dict) -> UploadJobConfigsV2:
|
|
|
66
109
|
job_settings=codeocean_pipeline_monitor_settings,
|
|
67
110
|
)
|
|
68
111
|
else:
|
|
69
|
-
|
|
112
|
+
nested_val = dict()
|
|
113
|
+
create_nested_dict(
|
|
114
|
+
dict_to_update=nested_val,
|
|
115
|
+
key_string=sub_key,
|
|
116
|
+
value=clean_val,
|
|
117
|
+
)
|
|
118
|
+
current_dict = deepcopy(
|
|
119
|
+
modality_configs.get(modality_key, dict())
|
|
120
|
+
)
|
|
121
|
+
nested_update(current_dict, nested_val)
|
|
122
|
+
modality_configs[modality_key] = current_dict
|
|
70
123
|
elif clean_key == "force_cloud_sync" and clean_val.upper() in [
|
|
71
124
|
"TRUE",
|
|
72
125
|
"T",
|
|
73
126
|
]:
|
|
74
127
|
check_s3_folder_exists_task = {"skip_task": True}
|
|
75
|
-
final_check_s3_folder_exist = {"skip_task": True}
|
|
76
128
|
else:
|
|
77
129
|
job_configs[clean_key] = clean_val
|
|
78
130
|
# Rename codeocean config keys with correct modality
|
|
@@ -93,8 +145,7 @@ def map_csv_row_to_job(row: dict) -> UploadJobConfigsV2:
|
|
|
93
145
|
)
|
|
94
146
|
tasks = {
|
|
95
147
|
"gather_preliminary_metadata": metadata_task,
|
|
96
|
-
"
|
|
97
|
-
"final_check_s3_folder_exist": final_check_s3_folder_exist,
|
|
148
|
+
"check_s3_folder_exists": check_s3_folder_exists_task,
|
|
98
149
|
"modality_transformation_settings": modality_tasks,
|
|
99
150
|
"codeocean_pipeline_settings": None
|
|
100
151
|
if codeocean_tasks == dict()
|
|
@@ -29,7 +29,9 @@ from starlette.middleware.sessions import SessionMiddleware
|
|
|
29
29
|
from starlette.responses import RedirectResponse
|
|
30
30
|
from starlette.routing import Route
|
|
31
31
|
|
|
32
|
-
from aind_data_transfer_service import
|
|
32
|
+
from aind_data_transfer_service import (
|
|
33
|
+
OPEN_DATA_BUCKET_NAME,
|
|
34
|
+
)
|
|
33
35
|
from aind_data_transfer_service import (
|
|
34
36
|
__version__ as aind_data_transfer_service_version,
|
|
35
37
|
)
|
|
@@ -37,14 +39,18 @@ from aind_data_transfer_service.configs.csv_handler import map_csv_row_to_job
|
|
|
37
39
|
from aind_data_transfer_service.configs.job_configs import (
|
|
38
40
|
BasicUploadJobConfigs as LegacyBasicUploadJobConfigs,
|
|
39
41
|
)
|
|
40
|
-
from aind_data_transfer_service.configs.job_configs import
|
|
42
|
+
from aind_data_transfer_service.configs.job_configs import (
|
|
43
|
+
HpcJobConfigs,
|
|
44
|
+
)
|
|
41
45
|
from aind_data_transfer_service.configs.job_upload_template import (
|
|
42
46
|
JobUploadTemplate,
|
|
43
47
|
)
|
|
44
48
|
from aind_data_transfer_service.hpc.client import HpcClient, HpcClientConfigs
|
|
45
49
|
from aind_data_transfer_service.hpc.models import HpcJobSubmitSettings
|
|
46
50
|
from aind_data_transfer_service.log_handler import LoggingConfigs, get_logger
|
|
47
|
-
from aind_data_transfer_service.models.core import
|
|
51
|
+
from aind_data_transfer_service.models.core import (
|
|
52
|
+
SubmitJobRequestV2,
|
|
53
|
+
)
|
|
48
54
|
from aind_data_transfer_service.models.core import (
|
|
49
55
|
validation_context as validation_context_v2,
|
|
50
56
|
)
|
|
@@ -929,10 +935,10 @@ async def get_task_logs(request: Request):
|
|
|
929
935
|
async def index(request: Request):
|
|
930
936
|
"""GET|POST /: form handler"""
|
|
931
937
|
return templates.TemplateResponse(
|
|
938
|
+
request=request,
|
|
932
939
|
name="index.html",
|
|
933
940
|
context=(
|
|
934
941
|
{
|
|
935
|
-
"request": request,
|
|
936
942
|
"project_names_url": project_names_url,
|
|
937
943
|
}
|
|
938
944
|
),
|
|
@@ -945,10 +951,10 @@ async def job_tasks_table(request: Request):
|
|
|
945
951
|
response_tasks_json = json.loads(response_tasks.body)
|
|
946
952
|
data = response_tasks_json.get("data")
|
|
947
953
|
return templates.TemplateResponse(
|
|
954
|
+
request=request,
|
|
948
955
|
name="job_tasks_table.html",
|
|
949
956
|
context=(
|
|
950
957
|
{
|
|
951
|
-
"request": request,
|
|
952
958
|
"status_code": response_tasks.status_code,
|
|
953
959
|
"message": response_tasks_json.get("message"),
|
|
954
960
|
"errors": data.get("errors", []),
|
|
@@ -965,10 +971,10 @@ async def task_logs(request: Request):
|
|
|
965
971
|
response_tasks_json = json.loads(response_tasks.body)
|
|
966
972
|
data = response_tasks_json.get("data")
|
|
967
973
|
return templates.TemplateResponse(
|
|
974
|
+
request=request,
|
|
968
975
|
name="task_logs.html",
|
|
969
976
|
context=(
|
|
970
977
|
{
|
|
971
|
-
"request": request,
|
|
972
978
|
"status_code": response_tasks.status_code,
|
|
973
979
|
"message": response_tasks_json.get("message"),
|
|
974
980
|
"errors": data.get("errors", []),
|
|
@@ -982,10 +988,10 @@ async def jobs(request: Request):
|
|
|
982
988
|
"""Get Job Status page with pagination"""
|
|
983
989
|
dag_ids = AirflowDagRunsRequestParameters.model_fields["dag_ids"].default
|
|
984
990
|
return templates.TemplateResponse(
|
|
991
|
+
request=request,
|
|
985
992
|
name="job_status.html",
|
|
986
993
|
context=(
|
|
987
994
|
{
|
|
988
|
-
"request": request,
|
|
989
995
|
"project_names_url": project_names_url,
|
|
990
996
|
"dag_ids": dag_ids,
|
|
991
997
|
}
|
|
@@ -996,10 +1002,10 @@ async def jobs(request: Request):
|
|
|
996
1002
|
async def job_params(request: Request):
|
|
997
1003
|
"""Get Job Parameters page"""
|
|
998
1004
|
return templates.TemplateResponse(
|
|
1005
|
+
request=request,
|
|
999
1006
|
name="job_params.html",
|
|
1000
1007
|
context=(
|
|
1001
1008
|
{
|
|
1002
|
-
"request": request,
|
|
1003
1009
|
"project_names_url": os.getenv(
|
|
1004
1010
|
"AIND_METADATA_SERVICE_PROJECT_NAMES_URL"
|
|
1005
1011
|
),
|
|
@@ -1122,10 +1128,10 @@ async def admin(request: Request):
|
|
|
1122
1128
|
user = {"name": "local user"}
|
|
1123
1129
|
if user:
|
|
1124
1130
|
return templates.TemplateResponse(
|
|
1131
|
+
request=request,
|
|
1125
1132
|
name="admin.html",
|
|
1126
1133
|
context=(
|
|
1127
1134
|
{
|
|
1128
|
-
"request": request,
|
|
1129
1135
|
"project_names_url": project_names_url,
|
|
1130
1136
|
"user_name": user.get("name", "unknown"),
|
|
1131
1137
|
"user_email": user.get("email", "unknown"),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aind-data-transfer-service
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.16.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
|
|
@@ -28,10 +28,10 @@ Requires-Dist: aind-data-transfer-models==0.17.0; extra == "server"
|
|
|
28
28
|
Requires-Dist: aind-metadata-mapper==0.23.0; extra == "server"
|
|
29
29
|
Requires-Dist: boto3; extra == "server"
|
|
30
30
|
Requires-Dist: boto3-stubs[ssm]; extra == "server"
|
|
31
|
-
Requires-Dist: fastapi; extra == "server"
|
|
31
|
+
Requires-Dist: fastapi>=0.115.13; extra == "server"
|
|
32
32
|
Requires-Dist: httpx; extra == "server"
|
|
33
33
|
Requires-Dist: jinja2; extra == "server"
|
|
34
|
-
Requires-Dist: starlette; extra == "server"
|
|
34
|
+
Requires-Dist: starlette<0.47.0,>=0.40.0; extra == "server"
|
|
35
35
|
Requires-Dist: starlette_wtf; extra == "server"
|
|
36
36
|
Requires-Dist: uvicorn[standard]; extra == "server"
|
|
37
37
|
Requires-Dist: wtforms; extra == "server"
|
|
@@ -87,6 +87,7 @@ tests/resources/get_secrets_response.json
|
|
|
87
87
|
tests/resources/job_upload_template.xlsx
|
|
88
88
|
tests/resources/legacy_sample.csv
|
|
89
89
|
tests/resources/legacy_sample2.csv
|
|
90
|
+
tests/resources/nested_sample.csv
|
|
90
91
|
tests/resources/new_sample.csv
|
|
91
92
|
tests/resources/sample.csv
|
|
92
93
|
tests/resources/sample.xlsx
|
{aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/test_csv_handler.py
RENAMED
|
@@ -9,11 +9,16 @@ from pathlib import Path
|
|
|
9
9
|
from aind_data_schema_models.modalities import Modality
|
|
10
10
|
from aind_data_schema_models.platforms import Platform
|
|
11
11
|
|
|
12
|
-
from aind_data_transfer_service.configs.csv_handler import
|
|
12
|
+
from aind_data_transfer_service.configs.csv_handler import (
|
|
13
|
+
create_nested_dict,
|
|
14
|
+
map_csv_row_to_job,
|
|
15
|
+
nested_update,
|
|
16
|
+
)
|
|
13
17
|
from aind_data_transfer_service.models.core import Task, UploadJobConfigsV2
|
|
14
18
|
|
|
15
19
|
RESOURCES_DIR = Path(os.path.dirname(os.path.realpath(__file__))) / "resources"
|
|
16
20
|
SAMPLE_FILE = RESOURCES_DIR / "new_sample.csv"
|
|
21
|
+
NESTED_SAMPLE_FILE = RESOURCES_DIR / "nested_sample.csv"
|
|
17
22
|
LEGACY_FILE = RESOURCES_DIR / "legacy_sample.csv"
|
|
18
23
|
LEGACY_FILE_2 = RESOURCES_DIR / "legacy_sample2.csv"
|
|
19
24
|
|
|
@@ -21,6 +26,26 @@ LEGACY_FILE_2 = RESOURCES_DIR / "legacy_sample2.csv"
|
|
|
21
26
|
class TestCsvHandler(unittest.TestCase):
|
|
22
27
|
"""Tests methods in csv_handler module"""
|
|
23
28
|
|
|
29
|
+
def test_create_nested_dict(self):
|
|
30
|
+
"""Tests create_nested_dict method"""
|
|
31
|
+
|
|
32
|
+
key = "abc.def.ghi"
|
|
33
|
+
value = "my_val"
|
|
34
|
+
nested_dict = dict()
|
|
35
|
+
create_nested_dict(
|
|
36
|
+
dict_to_update=nested_dict, key_string=key, value=value
|
|
37
|
+
)
|
|
38
|
+
expected_dict = {"abc": {"def": {"ghi": "my_val"}}}
|
|
39
|
+
self.assertEqual(expected_dict, nested_dict)
|
|
40
|
+
|
|
41
|
+
def test_nested_update(self):
|
|
42
|
+
"""Tests nested_update method."""
|
|
43
|
+
current_dict = {"abc": {"def": {"ghi": "my_val"}}}
|
|
44
|
+
updates = {"abc": {"def": {"jkl": 123}}}
|
|
45
|
+
nested_update(current_dict, updates)
|
|
46
|
+
expected_dict = {"abc": {"def": {"ghi": "my_val", "jkl": 123}}}
|
|
47
|
+
self.assertEqual(expected_dict, current_dict)
|
|
48
|
+
|
|
24
49
|
def test_map_csv_row_to_job(self):
|
|
25
50
|
"""Tests map_csv_row_to_job method"""
|
|
26
51
|
|
|
@@ -87,6 +112,42 @@ class TestCsvHandler(unittest.TestCase):
|
|
|
87
112
|
]
|
|
88
113
|
self.assertEqual(expected_jobs, jobs)
|
|
89
114
|
|
|
115
|
+
def test_map_nested_csv_row_to_job(self):
|
|
116
|
+
"""Tests map_csv_row_to_job method with nested keys"""
|
|
117
|
+
|
|
118
|
+
jobs = []
|
|
119
|
+
with open(NESTED_SAMPLE_FILE, newline="") as csvfile:
|
|
120
|
+
reader = csv.DictReader(csvfile, skipinitialspace=True)
|
|
121
|
+
for row in reader:
|
|
122
|
+
jobs.append(map_csv_row_to_job(row))
|
|
123
|
+
expected_jobs = [
|
|
124
|
+
UploadJobConfigsV2(
|
|
125
|
+
job_type="ecephys",
|
|
126
|
+
s3_bucket="default",
|
|
127
|
+
project_name="Ephys Platform",
|
|
128
|
+
platform=Platform.ECEPHYS,
|
|
129
|
+
modalities=[Modality.ECEPHYS],
|
|
130
|
+
subject_id="123454",
|
|
131
|
+
acq_datetime=datetime(2020, 10, 10, 14, 10, 10),
|
|
132
|
+
tasks={
|
|
133
|
+
"modality_transformation_settings": {
|
|
134
|
+
"ecephys": Task(
|
|
135
|
+
skip_task=False,
|
|
136
|
+
job_settings={
|
|
137
|
+
"input_source": "dir/data_set_1",
|
|
138
|
+
"compression_requested": {
|
|
139
|
+
"compression_enum": "gamma fix colorspace"
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
)
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
s3_prefix="ecephys_123454_2020-10-10_14-10-10",
|
|
146
|
+
)
|
|
147
|
+
]
|
|
148
|
+
|
|
149
|
+
self.assertEqual(expected_jobs, jobs)
|
|
150
|
+
|
|
90
151
|
def test_map_legacy_csv_row_to_job(self):
|
|
91
152
|
"""Tests map_csv_row_to_job method"""
|
|
92
153
|
|
|
@@ -105,10 +166,7 @@ class TestCsvHandler(unittest.TestCase):
|
|
|
105
166
|
subject_id="123454",
|
|
106
167
|
acq_datetime=datetime(2020, 10, 10, 14, 10, 10),
|
|
107
168
|
tasks={
|
|
108
|
-
"
|
|
109
|
-
skip_task=True,
|
|
110
|
-
),
|
|
111
|
-
"final_check_s3_folder_exist": Task(
|
|
169
|
+
"check_s3_folder_exists": Task(
|
|
112
170
|
skip_task=True,
|
|
113
171
|
),
|
|
114
172
|
"modality_transformation_settings": {
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/examples/example1.csv
RENAMED
|
File without changes
|
{aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/examples/hcr_example.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/source/Contributing.rst
RENAMED
|
File without changes
|
{aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/source/UserGuideV1.rst
RENAMED
|
File without changes
|
{aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/source/UserGuideV2.rst
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/source/index.rst
RENAMED
|
File without changes
|
{aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/docs/source/modules.rst
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/resources/sample.csv
RENAMED
|
File without changes
|
{aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/resources/sample.xlsx
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/test_configs.py
RENAMED
|
File without changes
|
|
File without changes
|
{aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/test_hpc_client.py
RENAMED
|
File without changes
|
{aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/test_hpc_models.py
RENAMED
|
File without changes
|
{aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/test_internal.py
RENAMED
|
File without changes
|
|
File without changes
|
{aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/test_log_handler.py
RENAMED
|
File without changes
|
{aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/test_server/Dockerfile
RENAMED
|
File without changes
|
{aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/test_server/db.json
RENAMED
|
File without changes
|
{aind_data_transfer_service-1.15.0 → aind_data_transfer_service-1.16.0}/tests/test_server.py
RENAMED
|
File without changes
|