nci-cidc-api-modules 1.1.10__py3-none-any.whl → 1.1.12__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.
- cidc_api/models/models.py +58 -17
- {nci_cidc_api_modules-1.1.10.dist-info → nci_cidc_api_modules-1.1.12.dist-info}/METADATA +1 -1
- {nci_cidc_api_modules-1.1.10.dist-info → nci_cidc_api_modules-1.1.12.dist-info}/RECORD +6 -6
- {nci_cidc_api_modules-1.1.10.dist-info → nci_cidc_api_modules-1.1.12.dist-info}/WHEEL +0 -0
- {nci_cidc_api_modules-1.1.10.dist-info → nci_cidc_api_modules-1.1.12.dist-info}/licenses/LICENSE +0 -0
- {nci_cidc_api_modules-1.1.10.dist-info → nci_cidc_api_modules-1.1.12.dist-info}/top_level.txt +0 -0
cidc_api/models/models.py
CHANGED
@@ -24,9 +24,9 @@ __all__ = [
|
|
24
24
|
"with_default_session",
|
25
25
|
]
|
26
26
|
|
27
|
-
import re
|
28
27
|
import hashlib
|
29
28
|
import os
|
29
|
+
import re
|
30
30
|
from collections import defaultdict
|
31
31
|
from datetime import datetime, timedelta
|
32
32
|
from enum import Enum as EnumBaseClass
|
@@ -46,8 +46,10 @@ from typing import (
|
|
46
46
|
)
|
47
47
|
|
48
48
|
import pandas as pd
|
49
|
+
from cidc_schemas import prism, unprism, json_validation
|
49
50
|
from flask import current_app as app
|
50
51
|
from google.cloud.storage import Blob
|
52
|
+
from jsonschema.exceptions import ValidationError
|
51
53
|
from sqlalchemy import (
|
52
54
|
and_,
|
53
55
|
Column,
|
@@ -76,11 +78,15 @@ from sqlalchemy import (
|
|
76
78
|
Table,
|
77
79
|
MetaData,
|
78
80
|
)
|
81
|
+
from sqlalchemy.dialects.postgresql import JSONB, UUID
|
82
|
+
from sqlalchemy.engine import ResultProxy
|
83
|
+
from sqlalchemy.exc import IntegrityError
|
84
|
+
from sqlalchemy.ext.hybrid import hybrid_property
|
79
85
|
from sqlalchemy.orm import relationship, validates
|
80
86
|
from sqlalchemy.orm.attributes import flag_modified
|
81
87
|
from sqlalchemy.orm.exc import NoResultFound
|
82
|
-
from sqlalchemy.orm.session import Session
|
83
88
|
from sqlalchemy.orm.query import Query
|
89
|
+
from sqlalchemy.orm.session import Session
|
84
90
|
from sqlalchemy.sql import (
|
85
91
|
# This is unfortunate but other code in this file relies on sqlalchemy.and_, or_, etc
|
86
92
|
# instead of the sqlalchemy.sql versions we are importing here. The solution is to
|
@@ -91,12 +97,7 @@ from sqlalchemy.sql import (
|
|
91
97
|
text,
|
92
98
|
)
|
93
99
|
from sqlalchemy.sql.functions import coalesce
|
94
|
-
from
|
95
|
-
from sqlalchemy.ext.hybrid import hybrid_property
|
96
|
-
from sqlalchemy.dialects.postgresql import JSONB, UUID
|
97
|
-
from sqlalchemy.engine import ResultProxy
|
98
|
-
|
99
|
-
from cidc_schemas import prism, unprism, json_validation
|
100
|
+
from werkzeug.exceptions import BadRequest
|
100
101
|
|
101
102
|
from .files import (
|
102
103
|
build_trial_facets,
|
@@ -107,8 +108,8 @@ from .files import (
|
|
107
108
|
FilePurpose,
|
108
109
|
FACET_NAME_DELIM,
|
109
110
|
)
|
110
|
-
|
111
111
|
from ..config.db import BaseModel
|
112
|
+
from ..config.logging import get_logger
|
112
113
|
from ..config.settings import (
|
113
114
|
PAGINATION_PAGE_SIZE,
|
114
115
|
MAX_PAGINATION_PAGE_SIZE,
|
@@ -121,13 +122,13 @@ from ..shared.gcloud_client import (
|
|
121
122
|
grant_lister_access,
|
122
123
|
grant_download_access,
|
123
124
|
publish_artifact_upload,
|
125
|
+
publish_patient_sample_update,
|
124
126
|
refresh_intake_access,
|
125
127
|
revoke_download_access,
|
126
128
|
revoke_intake_access,
|
127
129
|
revoke_lister_access,
|
128
130
|
revoke_bigquery_access,
|
129
131
|
)
|
130
|
-
from ..config.logging import get_logger
|
131
132
|
|
132
133
|
os.environ["TZ"] = "UTC"
|
133
134
|
logger = get_logger(__name__)
|
@@ -1120,13 +1121,15 @@ class TrialMetadata(CommonColumns):
|
|
1120
1121
|
_metadata_idx = Index("metadata_idx", metadata_json, postgresql_using="gin")
|
1121
1122
|
|
1122
1123
|
@staticmethod
|
1123
|
-
def validate_metadata_json(metadata_json: dict) -> dict:
|
1124
|
-
# Prior to running trial_metadata_validator.iter_error_messages on the metadata_json,
|
1125
|
-
# strip out unnecessary manifest data for the validation so that
|
1126
|
-
# that no longer conform to the post-CSMS-integration schema can be kept.
|
1124
|
+
def validate_metadata_json(metadata_json: dict, strip_metadata=True) -> dict:
|
1125
|
+
# Prior to running trial_metadata_validator.iter_error_messages on the metadata_json, if
|
1126
|
+
# strip_metadata=True, will strip out unnecessary manifest data for the validation so that
|
1127
|
+
# existing manifest data that no longer conform to the post-CSMS-integration schema can be kept.
|
1127
1128
|
# See more details in the strip_metadata_for_validation function docs.
|
1128
|
-
metadata_to_validate =
|
1129
|
-
metadata_json
|
1129
|
+
metadata_to_validate = (
|
1130
|
+
json_validation.strip_metadata_for_validation(metadata_json)
|
1131
|
+
if strip_metadata
|
1132
|
+
else metadata_json
|
1130
1133
|
)
|
1131
1134
|
errs = trial_metadata_validator.iter_error_messages(metadata_to_validate)
|
1132
1135
|
messages = list(f"'metadata_json': {err}" for err in errs)
|
@@ -2184,7 +2187,7 @@ class UploadJobs(CommonColumns):
|
|
2184
2187
|
job.insert(session=session, commit=commit)
|
2185
2188
|
|
2186
2189
|
if send_email:
|
2187
|
-
trial = TrialMetadata.find_by_trial_id(trial_id)
|
2190
|
+
trial = TrialMetadata.find_by_trial_id(trial_id, session=session)
|
2188
2191
|
job.alert_upload_success(trial)
|
2189
2192
|
|
2190
2193
|
return job
|
@@ -3295,3 +3298,41 @@ def result_proxy_to_models(
|
|
3295
3298
|
) -> List[BaseModel]:
|
3296
3299
|
"""Materialize a sqlalchemy `result_proxy` iterable as a list of `model` instances"""
|
3297
3300
|
return [model(**dict(row_proxy)) for row_proxy in result_proxy.all()]
|
3301
|
+
|
3302
|
+
|
3303
|
+
@with_default_session
|
3304
|
+
def upload_manifest_json(
|
3305
|
+
uploader_email: str,
|
3306
|
+
trial_id: str,
|
3307
|
+
template_type: str,
|
3308
|
+
md_patch: dict,
|
3309
|
+
session: Session,
|
3310
|
+
):
|
3311
|
+
"""
|
3312
|
+
Ingest manifest data from JSON.
|
3313
|
+
|
3314
|
+
* Tries to load existing trial metadata blob (if fails, merge request fails; nothing saved).
|
3315
|
+
* Merges the request JSON into the trial metadata (if fails, merge request fails; nothing saved).
|
3316
|
+
* The merge request JSON is saved to `UploadJobs`.
|
3317
|
+
* The updated trial metadata object is updated in the `TrialMetadata` table.
|
3318
|
+
"""
|
3319
|
+
try:
|
3320
|
+
TrialMetadata.patch_manifest(trial_id, md_patch, session=session, commit=False)
|
3321
|
+
except ValidationError as e:
|
3322
|
+
raise BadRequest(json_validation.format_validation_error(e)) from e
|
3323
|
+
except ValidationMultiError as e:
|
3324
|
+
raise BadRequest({"errors": e.args[0]}) from e
|
3325
|
+
|
3326
|
+
manifest_upload = UploadJobs.create(
|
3327
|
+
upload_type=template_type,
|
3328
|
+
uploader_email=uploader_email,
|
3329
|
+
metadata=md_patch,
|
3330
|
+
gcs_xlsx_uri="", # not saving xlsx so we won't have phi-ish stuff in it
|
3331
|
+
gcs_file_map=None,
|
3332
|
+
session=session,
|
3333
|
+
send_email=True,
|
3334
|
+
status=UploadJobStatus.MERGE_COMPLETED.value,
|
3335
|
+
)
|
3336
|
+
# Publish that a manifest upload has been received
|
3337
|
+
publish_patient_sample_update(manifest_upload.id)
|
3338
|
+
return manifest_upload.id
|
@@ -8,7 +8,7 @@ cidc_api/csms/auth.py,sha256=25Yma2Kz3KLENAPSeBYacFuSZXng-EDgmgInKBsRyP0,3191
|
|
8
8
|
cidc_api/models/__init__.py,sha256=bl445G8Zic9YbhZ8ZBni07wtBMhLJRMBA-JqjLxx2bw,66
|
9
9
|
cidc_api/models/csms_api.py,sha256=_uB9ZoxCFxKO8ZDTxCjS0CpeQg14EdlkEqnwyAFyYFQ,31377
|
10
10
|
cidc_api/models/migrations.py,sha256=gp9vtkYbA9FFy2s-7woelAmsvQbJ41LO2_DY-YkFIrQ,11464
|
11
|
-
cidc_api/models/models.py,sha256=
|
11
|
+
cidc_api/models/models.py,sha256=xoTl1b92EzwOby5Dct6AgtN9l3wEUB1NdhhrSEHwMR4,129248
|
12
12
|
cidc_api/models/schemas.py,sha256=7tDYtmULuzTt2kg7RorWhte06ffalgpQKrFiDRGcPEQ,2711
|
13
13
|
cidc_api/models/files/__init__.py,sha256=8BMTnUSHzUbz0lBeEQY6NvApxDD3GMWMduoVMos2g4Y,213
|
14
14
|
cidc_api/models/files/details.py,sha256=h6R0p_hi-ukHsO7HV-3Wukccp0zRLJ1Oie_JNA_7Pl0,62274
|
@@ -19,8 +19,8 @@ cidc_api/shared/emails.py,sha256=FXW9UfI2bCus350SQuL7ZQYq1Vg-vGXaGWmRfA6z2nM,440
|
|
19
19
|
cidc_api/shared/gcloud_client.py,sha256=7dDs0crLMJKdIp4IDSfrZBMB3h-zvWNieB81azoeLO4,33746
|
20
20
|
cidc_api/shared/jose.py,sha256=QO30uIhbYDwzPEWWJXz0PfyV7E1AZHReEZJUVT70UJY,1844
|
21
21
|
cidc_api/shared/rest_utils.py,sha256=LMfBpvJRjkfQjCzVXuhTTe4Foz4wlvaKg6QntyR-Hkc,6648
|
22
|
-
nci_cidc_api_modules-1.1.
|
23
|
-
nci_cidc_api_modules-1.1.
|
24
|
-
nci_cidc_api_modules-1.1.
|
25
|
-
nci_cidc_api_modules-1.1.
|
26
|
-
nci_cidc_api_modules-1.1.
|
22
|
+
nci_cidc_api_modules-1.1.12.dist-info/licenses/LICENSE,sha256=pNYWVTHaYonnmJyplmeAp7tQAjosmDpAWjb34jjv7Xs,1102
|
23
|
+
nci_cidc_api_modules-1.1.12.dist-info/METADATA,sha256=d000X8YPVI4KWjmw1ty9vXrcb1C-C-qUUHheW8_3d2U,41284
|
24
|
+
nci_cidc_api_modules-1.1.12.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
25
|
+
nci_cidc_api_modules-1.1.12.dist-info/top_level.txt,sha256=rNiRzL0lJGi5Q9tY9uSoMdTbJ-7u5c_D2E86KA94yRA,9
|
26
|
+
nci_cidc_api_modules-1.1.12.dist-info/RECORD,,
|
File without changes
|
{nci_cidc_api_modules-1.1.10.dist-info → nci_cidc_api_modules-1.1.12.dist-info}/licenses/LICENSE
RENAMED
File without changes
|
{nci_cidc_api_modules-1.1.10.dist-info → nci_cidc_api_modules-1.1.12.dist-info}/top_level.txt
RENAMED
File without changes
|