Skip to content

Commit d774c22

Browse files
ckaipflkuchenb
andauthored
Prepare Release 1.1.1 (#512)
* Bump version 1.1.1 * add module for tween factories add maintenance mode tween factory * fix variable * add test for maintenance mode * add settings for maintenance mode * Revert "add settings for maintenance mode" This reverts commit ba2ad3f. * Revert "add test for maintenance mode" This reverts commit feb0f15. * Revert "fix variable" This reverts commit 29d03ca. * Revert "add module for tween factories" This reverts commit a67241a. * Revert "Bump version 1.1.1" This reverts commit dd790b6. * Bump version 1.1.1 (#510) * Update README (instructions and animation) (#508) * Update deployment instructions * update # CHANGEME tag to # CHANGE THIS * Update deploy/compose_minimal/docker-compose.yml Co-authored-by: Camill Kaipf <[email protected]> * update compose files TFA related settings were not added yet --------- Co-authored-by: Camill Kaipf <[email protected]> Co-authored-by: ckaipf <[email protected]> * Handle MetaDatum unique but not mandatory (#509) * remove not used argument * don't count values which are `None` while ensuring unique constraint if MetaDatum is not mandatory several MetaDatumRecord will have value set to `None` * add empty line * add fixtures for test unique but not mandatory MetaDatum * rename file * add simplified submission test, to submit MetaDataSets with a unique and not mandatory MetaDatum * mypy is not happy here with reassigning this variable, refactored it * fix var name wrote too often None in the last hour * one MetaDataSet should be in an other Submission for global constraint * list to generator Co-authored-by: Leon Kuchenbecker <[email protected]> * flatten nested if --------- Co-authored-by: Leon Kuchenbecker <[email protected]> --------- Co-authored-by: Leon Kuchenbecker <[email protected]>
1 parent f6a0564 commit d774c22

File tree

11 files changed

+281
-28
lines changed

11 files changed

+281
-28
lines changed

README.md

+13-10
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,20 @@ users!
1010

1111
## Quick Installation
1212

13+
1. Create a directory for the datameta configuration (of your choice)
14+
```
15+
mkdir /usr/local/lib/datameta
16+
cd /usr/local/lib/datameta
17+
```
18+
19+
1. Edit the configuration file
20+
21+
The fields that require changing are marked with `# CHANGE THIS`. You may want
22+
to perform additional adjustments to the compose file to fit your needs.
23+
1324
1. Download the Docker compose file
1425
```
15-
curl -LO https://raw.githubusercontent.com/ghga-de/datameta/main/datameta.compose.yml
26+
curl -LO https://datameta.org/minimal/docker-compose.yml
1627
```
1728

1829
1. Create the Docker volumes for persistent file and database storage
@@ -23,13 +34,5 @@ users!
2334

2435
1. Start up your DataMeta Instance
2536
```
26-
docker stack deploy --compose-file datameta.compose.yml datameta
37+
docker-compose up -d
2738
```
28-
29-
1. Connect to your DataMeta instance at http://localhost:9950 and log in with the default
30-
account `[email protected]`. The initial password can be obtained using
31-
`docker logs {your_app_container_id}`.
32-
33-
## Full Installation Instructions
34-
35-
Detailed installation instructions can be found [here](./docs).

datameta/validation.py

+11-7
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from .security import authz
2222
from .api.metadata import get_all_metadata
2323
from .utils import get_record_from_metadataset
24+
from typing import Dict
2425

2526

2627
def validate_submission_access(db, db_files, db_msets, auth_user):
@@ -120,11 +121,14 @@ def validate_submission_association(db_files, db_msets, ignore_submitted_metadat
120121
return f_names_obj, ref_fnames, errors
121122

122123

123-
def validate_submission_uniquekeys(db, db_files, db_msets):
124+
def validate_submission_uniquekeys(
125+
db,
126+
db_msets: Dict[str, MetaDataSet],
127+
):
124128
errors = []
125129

126130
# Submission unique keys (includes those that are globally unique)
127-
keys_submission_unique = [ md.name for md in db.query(MetaDatum).filter(or_(MetaDatum.submission_unique.is_(True), MetaDatum.site_unique.is_(True))) ]
131+
keys_submission_unique = [ md.name for md in db.query(MetaDatum).filter(or_(MetaDatum.submission_unique.is_(True), MetaDatum.site_unique.is_(True))) ]
128132
# Globally unique keys
129133
keys_site_unique = [ md.name for md in db.query(MetaDatum).filter(MetaDatum.site_unique.is_(True)) ]
130134

@@ -134,20 +138,20 @@ def validate_submission_uniquekeys(db, db_files, db_msets):
134138
# Associate all values for that key with the metadatasets it occurs in
135139
for db_mset in db_msets.values():
136140
for mdatrec in db_mset.metadatumrecords:
137-
if mdatrec.metadatum.name == key:
141+
if mdatrec.metadatum.name == key and mdatrec.value:
138142
value_msets[mdatrec.value].append(db_mset)
139143
# Reduce to those values that occur in more than one metadatast
140-
value_msets = { k: v for k, v in value_msets.items() if len(v) > 1 }
144+
not_unique = ( v for v in value_msets.values() if len(v) > 1 )
141145
# Produce errrors
142-
errors += [ (db_mset, key, "Violation of intra-submission unique constraint") for msets in value_msets.values() for db_mset in msets ]
146+
errors += [ (db_mset, key, "Violation of intra-submission unique constraint") for msets in not_unique for db_mset in msets ]
143147

144148
# Validate the set of metadatasets with regard to site-wise unique key constraints
145149
for key in keys_site_unique:
146150
value_msets = defaultdict(list)
147151
# Associate all values for that key with the metadatasets it occurs in
148152
for db_mset in db_msets.values():
149153
for mdatrec in db_mset.metadatumrecords:
150-
if mdatrec.metadatum.name == key:
154+
if mdatrec.metadatum.name == key and mdatrec.value:
151155
value_msets[mdatrec.value].append(db_mset)
152156

153157
# Query the database for the supplied values
@@ -196,7 +200,7 @@ def validate_submission(request, auth_user):
196200
val_errors += [ (db_msets[mset_id], mset_error['field'], mset_error['message']) for mset_error in mset_errors ]
197201

198202
# Validate unique field constraints
199-
val_errors += validate_submission_uniquekeys(db, db_files, db_msets)
203+
val_errors += validate_submission_uniquekeys(db, db_msets)
200204

201205
# If we collected any val_errors, raise 400
202206
if val_errors:

deploy/compose_minimal/docker-compose.yml

+19-10
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,21 @@ services:
1717
appserver:
1818
image: "datameta/datameta:dev"
1919
restart: "always"
20+
volumes:
21+
- datameta-filestorage:/var/datameta/storage
2022
environment:
2123
SQLALCHEMY_URL: postgresql://datameta:datameta@dbserver/datameta
2224
SESSION_URL: sessionserver:11211
2325
SESSION_KEY: datameta
24-
SESSION_SECRET: dummy # TODO: Insert 64 character random string here
26+
SESSION_SECRET: dummy # CHANGE THIS: Insert 64 character random string here
2527
DATAMETA_STORAGE_PATH: /var/datameta/storage
2628

2729
# The initial values can be changed once the DataMeta instance was
2830
# deployed.
29-
DATAMETA_INITIAL_FULLNAME: Joe user # TODO: Insert initial user fullname here
30-
DATAMETA_INITIAL_EMAIL: joe@user # TODO: Insert initial user email address here
31-
DATAMETA_INITIAL_PASS: j03us3r # TODO: Insert initial user password here
32-
DATAMETA_INITIAL_GROUPNAME: Joe's lab # TODO: Insert intial user group name here
31+
DATAMETA_INITIAL_FULLNAME: Joe User # CHANGE THIS: Insert initial user fullname here
32+
DATAMETA_INITIAL_EMAIL: joe@user # CHANGE THIS: Insert initial user email address here
33+
DATAMETA_INITIAL_PASS: j03us3r # CHANGE THIS: Insert initial user password here
34+
DATAMETA_INITIAL_GROUPNAME: Joe's lab # CHANGE THIS: Insert intial user group name here
3335

3436
# The maximum number of days an API key can be valid
3537
DATAMETA_API_KEYS_MAX_EXPIRE_DAYS: 365
@@ -45,12 +47,12 @@ services:
4547
# DataMeta sends out emails for password forgot tokens, registration
4648
# confirmations and to notify admins about new registrations. Configure
4749
# an SMTP server for outgoing email below.
48-
DATAMETA_SMTP_HOST: # TODO: Insert SMTP server address here
50+
DATAMETA_SMTP_HOST: # CHANGE THIS: Insert SMTP server address here
4951
DATAMETA_SMTP_PORT: 587 # Adjust if needed
50-
DATAMETA_SMTP_USER: # TODO: Insert SMTP user here
51-
DATAMETA_SMTP_PASS: # TODO: Insert SMTP password here
52+
DATAMETA_SMTP_USER: # CHANGE THIS: Insert SMTP user here
53+
DATAMETA_SMTP_PASS: # CHANGE THIS: Insert SMTP password here
5254
DATAMETA_SMTP_TLS: "true"
53-
DATAMETA_SMTP_FROM: # TODO: Specify SMTP FROM header here, format 'Example Support <[email protected]>'
55+
DATAMETA_SMTP_FROM: # CHANGE THIS: Specify SMTP FROM header here, format 'Example Support <[email protected]>'
5456

5557
# Site ID prefixes and lengths
5658
# The entites 'user', 'group', 'submission', 'metadataset' and 'file' are
@@ -71,6 +73,11 @@ services:
7173
DATAMETA_SITE_ID_PREFIX_FILES: "DMF-"
7274
DATAMETA_SITE_ID_PREFIX_SERVICES: "DMP-"
7375

76+
# Two factor authentication settings
77+
DATAMETA_TFA_ENABLED: # CHANGE THIS: Insert bool to enable
78+
DATAMETA_TFA_ENCRYPT_KEY: # CHANGE THIS: Insert secret here
79+
DATAMETA_TFA_OTP_ISSUER: # CHANGE THIS: Insert OTP issuer name here
80+
7481
GUNICORN_WORKERS: 4 # Adjust to your needs. 2-4x #CPUs
7582
GUNICORN_PROC_NAME: datameta
7683
GUNICORN_FORWARDED_ALLOW_IPS: "*"
@@ -82,4 +89,6 @@ services:
8289

8390
volumes: # TODO: Create external volumes before first launch
8491
datameta-db:
85-
external: false
92+
external: true
93+
datameta-filestorage:
94+
external: true

deploy/compose_multiprocess/docker-compose.yml

+5
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ services:
7171
DATAMETA_SITE_ID_PREFIX_FILES: "DMF-"
7272
DATAMETA_SITE_ID_PREFIX_SERVICES: "DMP-"
7373

74+
# Two factor authentication settings
75+
DATAMETA_TFA_ENABLED: # CHANGE THIS: Insert bool to enable
76+
DATAMETA_TFA_ENCRYPT_KEY: # CHANGE THIS: Insert secret here
77+
DATAMETA_TFA_OTP_ISSUER: # CHANGE THIS: Insert OTP issuer name here
78+
7479
GUNICORN_WORKERS: 75 # Adjust to your needs. 2-4x #CPUs
7580
GUNICORN_PROC_NAME: datameta
7681
GUNICORN_FORWARDED_ALLOW_IPS: "*"

deploy/compose_scale/docker-compose.yml

+5
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ services:
1616
# The maximum number of days an API key can be valid
1717
DATAMETA_API_KEYS_MAX_EXPIRE_DAYS: 365
1818

19+
# Two factor authentication settings
20+
DATAMETA_TFA_ENABLED: # CHANGE THIS: Insert bool to enable
21+
DATAMETA_TFA_ENCRYPT_KEY: # CHANGE THIS: Insert secret here
22+
DATAMETA_TFA_OTP_ISSUER: # CHANGE THIS: Insert OTP issuer name here
23+
1924
LETSENCRYPT_HOST: # Picked up by nginx-proxy / letsencrypt. Comma separated list of hostnames.
2025
VIRTUAL_HOST: # Picked up by nginx-proxy / letsencrypt. Comma separated list of hostnames. Every hostname in LETSENCRYPT_HOST must appear also here, otherwise cert acquisition will fail
2126
WAITRESS_MAX_REQUEST_BODY_SIZE: 10737418240 # 10 GB

deploy/compose_testing/docker-compose.yml

+5
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ services:
6868
DATAMETA_SITE_ID_PREFIX_FILES: "DMF-"
6969
DATAMETA_SITE_ID_PREFIX_SERVICES: "DMP-"
7070

71+
# Two factor authentication settings
72+
DATAMETA_TFA_ENABLED: # CHANGE THIS: Insert bool to enable
73+
DATAMETA_TFA_ENCRYPT_KEY: # CHANGE THIS: Insert secret here
74+
DATAMETA_TFA_OTP_ISSUER: # CHANGE THIS: Insert OTP issuer name here
75+
7176
GUNICORN_WORKERS: 4 # Adjust to your needs. 2-4x #CPUs
7277
GUNICORN_PROC_NAME: datameta
7378
GUNICORN_FORWARDED_ALLOW_IPS: "*"

img/datameta.demo.gif

2.2 MB
Loading

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767

6868
setup(
6969
name = 'datameta',
70-
version = '1.1.0',
70+
version = '1.1.1',
7171
description = 'DataMeta - submission server for data and associated metadata',
7272
long_description = README + '\n\n' + CHANGES,
7373
author = 'Leon Kuchenbecker',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Copyright 2021 Universität Tübingen, DKFZ and EMBL for the German Human Genome-Phenome Archive (GHGA)
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
metadataset_unique_not_mandatory_0:
16+
class: MetaDataSet
17+
attributes:
18+
site_id: metadataset_unique_not_mandatory_0
19+
records:
20+
unique_not_mandatory_id: null
21+
references:
22+
user:
23+
fixtureset: users
24+
name: user_a
25+
submission:
26+
fixtureset: submissions
27+
name: submission_a
28+
fixtureOnly:
29+
- records
30+
31+
metadataset_unique_not_mandatory_1:
32+
class: MetaDataSet
33+
attributes:
34+
site_id: metadataset_unique_not_mandatory_1
35+
records:
36+
unique_not_mandatory_id: null
37+
references:
38+
user:
39+
fixtureset: users
40+
name: user_a
41+
submission:
42+
fixtureset: submissions
43+
name: submission_a
44+
fixtureOnly:
45+
- records
46+
47+
metadataset_unique_not_mandatory_2:
48+
class: MetaDataSet
49+
attributes:
50+
site_id: metadataset_unique_not_mandatory_2
51+
records:
52+
unique_not_mandatory_id: null
53+
references:
54+
user:
55+
fixtureset: users
56+
name: user_a
57+
submission:
58+
fixtureset: submissions
59+
name: submission_b
60+
fixtureOnly:
61+
- records
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Copyright 2021 Universität Tübingen, DKFZ and EMBL for the German Human Genome-Phenome Archive (GHGA)
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
unique_not_mandatory_id:
16+
class: MetaDatum
17+
attributes:
18+
name: unique_not_mandatory_id
19+
mandatory: false
20+
example: "ID123"
21+
order: 101
22+
isfile: false
23+
submission_unique: true
24+
site_unique: true

0 commit comments

Comments
 (0)