diff --git a/api/config.py b/api/config.py index befc6a227745a5d567f2249661bb7bf58b710261..e12bb18591e9fb337e321427f8b83dd5c861ff98 100644 --- a/api/config.py +++ b/api/config.py @@ -5,6 +5,7 @@ import logging import pymongo import datetime import elasticsearch +from . import util logging.basicConfig( @@ -34,7 +35,7 @@ DEFAULT_CONFIG = { 'api_url': 'https://localhost/api', 'central_url': 'https://sdmc.scitran.io/api', 'registered': False, - 'ssl_cert': None, + 'ssl_cert': None }, 'queue': { 'max_retries': 3, @@ -221,7 +222,7 @@ def get_config(): db_config = db.singletons.find_one({'_id': 'config'}) if db_config is not None: startup_config = copy.deepcopy(__config) - startup_config.update(db_config) + startup_config = util.deep_update(startup_config, db_config) # Precedence order for config is env vars -> db values -> default __config = apply_env_variables(startup_config) else: diff --git a/api/download.py b/api/download.py index c91cebdfc0faaf5b68957be9b9d9096bac59398e..50d3615c5a18e10a79eb37ce06eb9d9faff7ef0c 100644 --- a/api/download.py +++ b/api/download.py @@ -267,7 +267,7 @@ class Download(base.RequestHandler): if self.is_true('bulk'): return self._bulk_preflight_archivestream(req_spec.get('files', [])) else: - payload_schema_uri = util.schema_uri('input', 'download.json') + payload_schema_uri = validators.schema_uri('input', 'download.json') validator = validators.from_schema_path(payload_schema_uri) validator(req_spec, 'POST') log.debug(json.dumps(req_spec, sort_keys=True, indent=4, separators=(',', ': '))) diff --git a/api/handlers/containerhandler.py b/api/handlers/containerhandler.py index 4f35b01368d9461fcbff79136908edfd6c352642..cc385ba630af13f2facf6137aca5a72e97ade5e6 100644 --- a/api/handlers/containerhandler.py +++ b/api/handlers/containerhandler.py @@ -487,9 +487,9 @@ class ContainerHandler(base.RequestHandler): return list(config.db.groups.find({'_id': {'$in': group_ids}}, ['name'])) def _get_validators(self): - mongo_schema_uri = util.schema_uri('mongo', self.config.get('storage_schema_file')) + mongo_schema_uri = validators.schema_uri('mongo', self.config.get('storage_schema_file')) mongo_validator = validators.decorator_from_schema_path(mongo_schema_uri) - payload_schema_uri = util.schema_uri('input', self.config.get('payload_schema_file')) + payload_schema_uri = validators.schema_uri('input', self.config.get('payload_schema_file')) payload_validator = validators.from_schema_path(payload_schema_uri) return mongo_validator, payload_validator diff --git a/api/handlers/grouphandler.py b/api/handlers/grouphandler.py index f8034da62d1d4a42651c2806b62ecfe2af2ded81..6d1e07853c548eb6385893830e7ec25c82535674 100644 --- a/api/handlers/grouphandler.py +++ b/api/handlers/grouphandler.py @@ -63,9 +63,9 @@ class GroupHandler(base.RequestHandler): self.abort(404, 'no such Group: ' + _id) permchecker = groupauth.default(self, group) payload = self.request.json_body - mongo_schema_uri = util.schema_uri('mongo', 'group.json') + mongo_schema_uri = validators.schema_uri('mongo', 'group.json') mongo_validator = validators.decorator_from_schema_path(mongo_schema_uri) - payload_schema_uri = util.schema_uri('input', 'group.json') + payload_schema_uri = validators.schema_uri('input', 'group.json') payload_validator = validators.from_schema_path(payload_schema_uri) payload_validator(payload, 'PUT') result = mongo_validator(permchecker(self.storage.exec_op))('PUT', _id=_id, payload=payload) @@ -78,9 +78,9 @@ class GroupHandler(base.RequestHandler): self._init_storage() permchecker = groupauth.default(self, None) payload = self.request.json_body - mongo_schema_uri = util.schema_uri('mongo', 'group.json') + mongo_schema_uri = validators.schema_uri('mongo', 'group.json') mongo_validator = validators.decorator_from_schema_path(mongo_schema_uri) - payload_schema_uri = util.schema_uri('input', 'group.json') + payload_schema_uri = validators.schema_uri('input', 'group.json') payload_validator = validators.from_schema_path(payload_schema_uri) payload_validator(payload, 'POST') payload['created'] = payload['modified'] = datetime.datetime.utcnow() diff --git a/api/handlers/listhandler.py b/api/handlers/listhandler.py index d95e68d00dd8969a74207d4a3d1023352499740b..51ac5770d3c1c566e3d11b50f14dd7b68cdb165f 100644 --- a/api/handlers/listhandler.py +++ b/api/handlers/listhandler.py @@ -206,9 +206,9 @@ class ListHandler(base.RequestHandler): permchecker = permchecker(self, container) else: self.abort(404, 'Element {} not found in container {}'.format(_id, storage.cont_name)) - mongo_schema_uri = util.schema_uri('mongo', config.get('storage_schema_file')) + mongo_schema_uri = validators.schema_uri('mongo', config.get('storage_schema_file')) mongo_validator = validators.decorator_from_schema_path(mongo_schema_uri) - input_schema_uri = util.schema_uri('input', config.get('input_schema_file')) + input_schema_uri = validators.schema_uri('input', config.get('input_schema_file')) input_validator = validators.from_schema_path(input_schema_uri) keycheck = validators.key_check(mongo_schema_uri) return container, permchecker, storage, mongo_validator, input_validator, keycheck diff --git a/api/handlers/userhandler.py b/api/handlers/userhandler.py index 1bc1dcde502919d72640a55ec751b0026841eaef..844d7d6d5b14514dd044daaf2d052f6151aafc09 100644 --- a/api/handlers/userhandler.py +++ b/api/handlers/userhandler.py @@ -102,9 +102,9 @@ class UserHandler(base.RequestHandler): user = self._get_user(_id) permchecker = userauth.default(self, user) payload = self.request.json_body - mongo_schema_uri = util.schema_uri('mongo', 'user.json') + mongo_schema_uri = validators.schema_uri('mongo', 'user.json') mongo_validator = validators.decorator_from_schema_path(mongo_schema_uri) - payload_schema_uri = util.schema_uri('input', 'user.json') + payload_schema_uri = validators.schema_uri('input', 'user.json') payload_validator = validators.from_schema_path(payload_schema_uri) payload_validator(payload, 'PUT') payload['modified'] = datetime.datetime.utcnow() @@ -147,9 +147,9 @@ class UserHandler(base.RequestHandler): self._init_storage() permchecker = userauth.default(self) payload = self.request.json_body - mongo_schema_uri = util.schema_uri('mongo', 'user.json') + mongo_schema_uri = validators.schema_uri('mongo', 'user.json') mongo_validator = validators.decorator_from_schema_path(mongo_schema_uri) - payload_schema_uri = util.schema_uri('input', 'user.json') + payload_schema_uri = validators.schema_uri('input', 'user.json') payload_validator = validators.from_schema_path(payload_schema_uri) payload_validator(payload, 'POST') payload['created'] = payload['modified'] = datetime.datetime.utcnow() diff --git a/api/placer.py b/api/placer.py index 3aba5648b59b13213ca6966a1d50a09301f0ca2c..25b0a2d9a359e4568f577ca57d19f93373f2699d 100644 --- a/api/placer.py +++ b/api/placer.py @@ -128,7 +128,7 @@ class UIDPlacer(Placer): def check(self): self.requireMetadata() - payload_schema_uri = util.schema_uri('input', self.metadata_schema) + payload_schema_uri = validators.schema_uri('input', self.metadata_schema) metadata_validator = validators.from_schema_path(payload_schema_uri) metadata_validator(self.metadata, 'POST') diff --git a/api/util.py b/api/util.py index 60e1cc1009811df92fbdf23ca0e888e50a75b85a..ee9b9a46e017f5b9843d7d26aa2680eec3e2c936 100644 --- a/api/util.py +++ b/api/util.py @@ -9,7 +9,6 @@ import uuid import requests import hashlib -from . import config MIMETYPES = [ ('.bvec', 'text', 'bvec'), ('.bval', 'text', 'bval'), @@ -65,6 +64,18 @@ def mongo_sanitize_fields(d): else: return d +def deep_update(d, u): + """ + Makes a deep update of dict d with dict u + Adapted from http://stackoverflow.com/a/3233356 + """ + for k, v in u.iteritems(): + if isinstance(v, dict): + r = deep_update(d.get(k, {}), v) + d[k] = r + else: + d[k] = u[k] + return d def user_perm(permissions, _id, site=None): @@ -163,12 +174,6 @@ def send_json_http_exception(response, message, code): response.headers['Content-Type'] = 'application/json; charset=utf-8' response.write(content) -def schema_uri(type_, schema_name): - return '/'.join([ - config.get_item('site', 'api_url'), - 'schemas', - type_, schema_name - ]) class Enum(baseEnum.Enum): # Enum strings are prefixed by their class: "Category.classifier". diff --git a/api/validators.py b/api/validators.py index 2f3350e36b31c9709d3aaeaf6f539154253a5101..9ca334007f409d52efa0db03819776c008e57249 100644 --- a/api/validators.py +++ b/api/validators.py @@ -27,8 +27,8 @@ def validate_data(data, schema_json, schema_type, verb, optional=False): if optional and data is None: return - schema_uri = util.schema_uri(schema_type, schema_json) - validator = from_schema_path(schema_uri) + suri = schema_uri(schema_type, schema_json) + validator = from_schema_path(suri) validator(data, verb) def _validate_json(json_data, schema, resolver): @@ -74,6 +74,13 @@ def _resolve_schema(schema_url): def no_op(g, *args): return g +def schema_uri(type_, schema_name): + return '/'.join([ + config.get_item('site', 'api_url'), + 'schemas', + type_, schema_name + ]) + def decorator_from_schema_path(schema_url): if schema_url is None: return no_op