Commit 1af5d2b1 authored by Markus Scheidgen's avatar Markus Scheidgen
Browse files

Clean up and refactorings.

parent cf68693b
......@@ -31,8 +31,7 @@ from ..decorators import json
from ..decorators.paginate import paginate_queryparams, paginate
from ..dmss import diagram_data_types
from ..errors import InvalidEncRequest
from ..utils import generate_auth_token, verify_auth_token, flag_to_gitlab, reformat_user_formula, hill_decomposition, \
get_atom_symbol
from ..utils import generate_auth_token, verify_auth_token, flag_to_gitlab, reformat_user_formula, hill_decomposition
LOGGER = logging.getLogger(__name__)
......@@ -437,6 +436,7 @@ def get_calc(material_id, calc_id):
query = query.join("energy")
return query.project(property).result()
# Energy_decomposition
@api.route('/materials/<int:material_id>/calculations/<int:calc_id>/energies', methods=['GET'])
@http_auth.login_required
......
......@@ -17,16 +17,14 @@ import argparse
SECRET_KEY = 'InVzZXIxQGdtlsLmNvbSI.YH6iB4wE5dDMNjpf-cX2Q9MIjyY'
# not used right now
# SAML_PATH = 'saml'
_default_dmss_host = os.environ.get('ENC_API_DMSS_HOST', 'localhost')
_default_dmss_port = int(os.environ.get('ENC_API_DMSS_PORT', '27017'))
_default_dmss_db = os.environ.get('ENC_API_DMSS_DB', 'nomad_dmss')
_default_dmss_host = os.environ.get('ENC_DMSS_HOST', 'localhost')
_default_dmss_port = int(os.environ.get('ENC_DMSS_PORT', '27017'))
_default_dmss_db = os.environ.get('ENC_DMSS_DB', 'nomad_dmss')
_default_es_host = os.environ.get('ENC_API_ES_HOST', 'localhost')
_default_es_port = int(os.environ.get('ENC_API_ES_PORT', '9200'))
_default_es_index = os.environ.get('ENC_API_ES_INDEX', 'nomad_aggregated')
_default_es_host = os.environ.get('ENC_ES_HOST', 'localhost')
_default_es_port = int(os.environ.get('ENC_ES_PORT', '9200'))
_default_es_index = os.environ.get('ENC_ES_INDEX', 'nomad')
parser = argparse.ArgumentParser(description='The encyclopedia API.')
parser.add_argument('--dmss-host', help='the mongo dmss host name or ip address', default=_default_dmss_host)
......
# Copyright 2016-2018 Ioan Vancea, Markus Scheidgen
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from datetime import timedelta
from flask import current_app
from functools import update_wrapper
# Decorator to accept cross-domain AJAX requests
# Will not be needed when the GUI will be on the same server
# -*- coding: utf-8 -*-
def crossdomain(origin=None, methods=None, headers=None,
max_age=21600, attach_to_all=True,
automatic_options=True):
if methods is not None:
methods = ', '.join(sorted(x.upper() for x in methods))
if headers is not None and not isinstance(headers, basestring):
headers = ', '.join(x.upper() for x in headers)
if not isinstance(origin, basestring):
origin = ', '.join(origin)
if isinstance(max_age, timedelta):
max_age = max_age.total_seconds()
def get_methods():
if methods is not None:
return methods
options_resp = current_app.make_default_options_response()
return options_resp.headers['allow']
def decorator(f):
def wrapped_function(*args, **kwargs):
if automatic_options and request.method == 'OPTIONS':
resp = current_app.make_default_options_response()
else:
resp = make_response(f(*args, **kwargs))
if not attach_to_all and request.method != 'OPTIONS':
return resp
h = resp.headers
h['Access-Control-Allow-Origin'] = origin
h['Access-Control-Allow-Methods'] = get_methods()
h['Access-Control-Max-Age'] = str(max_age)
h['Access-Control-Allow-Credentials'] = 'true'
h['Access-Control-Allow-Headers'] = \
"Origin, X-Requested-With, Content-Type, Accept, Authorization"
if headers is not None:
h['Access-Control-Allow-Headers'] = headers
return resp
f.provide_automatic_options = False
return update_wrapper(wrapped_function, f)
return decorator
......@@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
class InvalidEncRequest(Exception):
def __init__(self, message, status_code):
......
......@@ -13,7 +13,6 @@
# limitations under the License.
import re
import datetime
from flask import current_app
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from itsdangerous import BadSignature, SignatureExpired
......@@ -219,7 +218,6 @@ def split_and_order(search_formula):
return final_list
########################################################################
# Calculate the formula using the same algorithm as in Preprocessing
########################################################################
......@@ -377,7 +375,6 @@ def hill_decomposition(atom_labels):
# - oxides, acids, hydroxides...
return (names, counts)
#return form_string(names, counts)
def formula_hill_as_string(atom_labels):
......@@ -394,6 +391,7 @@ def formula_hill_as_string(atom_labels):
names, counts = hill_decomposition(atom_labels)
return form_string(names, counts)
def formula_hill_as_list(atom_labels):
"""Given a list of atomic labels, returns the chemical formula using the
Hill system (https://en.wikipedia.org/wiki/Hill_system).
......@@ -429,100 +427,6 @@ def reformat_user_formula(search_formula):
return formula_hill_as_list(final_list)
def check_value_type(attr, value):
""" Function to check the type of "value" for each pair key-value
from the dictionary containing the filter expressions
:param attr: represents the key in dictionary
:param value: represents the value for the corresponding key
:return: an expression which can be used in the list comprehension for
building the filters
"""
if isinstance(value, str):
return attr == value
elif isinstance(value, list):
return attr.in_(value)
elif isinstance(value, dict):
return attr.between(value['min'], value['max'])
else:
raise ValueError("Unexpected value type: {}".format(type(value)))
def validate_date(date_query_arg):
""" Function to validate a data string sent in URI as
query param value
"""
try:
if date_query_arg != datetime.datetime.strptime(date_query_arg, "%d-%m-%Y").strftime('%d-%m-%Y'):
raise ValueError
return True
except ValueError:
return False
def collect_insert_dbstats():
""" Function to collect the needed statistics from main database and then
insert them into the "stats" table
"""
# imports needed for RQ worker function
from sqlalchemy import func, or_
import json
from . import db
from .models import Material, Calc, Stats
from app import create_app
app = create_app()
with app.app_context():
# Material related statistics
materials = Material.query.count()
materials_with_band_structure = Material.query.filter(Material.calc.any(Calc.has_band_structure)).count()
materials_with_dos = Material.query.filter(Material.calc.any(Calc.has_dos)).count()
materials_with_fermi_surface = Material.query.filter(Material.calc.any(Calc.has_fermi_surface)).count()
materials_with_thermal_properties = Material.query.filter(Material.calc.any(Calc.has_thermal_properties)).count()
# to be added - Materials: Equation of state
materials_system_type = Material.query.with_entities(Material.system_type, func.count()).group_by(Material.system_type).all()
# to convert the list of lists into a dictionary
shown_materials_system_type = {d[0]: d[1] for d in materials_system_type}
# print(type(materials_system_type))
# materials_system_type = Material.query.filter(Material.system_type == 'bulk').count()
# Calculations related statistics
calculations = Calc.query.count()
calculations_with_band_structure = Calc.query.filter(Calc.has_band_structure).count()
calculations_with_dos = Calc.query.filter(Calc.has_dos).count()
calculations_with_fermi_surface = Calc.query.filter(Calc.has_fermi_surface).count()
calculations_with_thermal_properties = Calc.query.filter(or_(Calc.has_thermal_properties)).count()
# to be added - Calculations: Equation of state
calculations_functional_type = Calc.query.with_entities(Calc.functional_type, func.count()).group_by(Calc.functional_type).all()
# to convert the list of lists into a dictionary
shown_calculations_functional_type = {d[0]: d[1] for d in calculations_functional_type}
calculations_code_name = Calc.query.with_entities(Calc.code_name, func.count()).group_by(Calc.code_name).all()
# to convert the list of lists into a dictionary
shown_calculations_code_name = {d[0]: d[1] for d in calculations_code_name}
# to be added - Methodology (for now only "DFT")
dbstats = dict(materials=materials,
materials_with_band_structure=materials_with_band_structure,
materials_with_dos=materials_with_dos,
materials_with_fermi_surface=materials_with_fermi_surface,
materials_with_thermal_properties=materials_with_thermal_properties,
materials_system_type=shown_materials_system_type,
calculations=calculations,
calculations_with_band_structure=calculations_with_band_structure,
# here equation of state
calculations_with_dos=calculations_with_dos,
calculations_with_fermi_surface=calculations_with_fermi_surface,
calculations_with_thermal_properties=calculations_with_thermal_properties,
calculations_functional_type=shown_calculations_functional_type,
calculations_code_name=shown_calculations_code_name)
# print(json.dumps(dbstats, indent=4, sort_keys=True))
# return dbstats
# Insert the collected statistics into the corresponding table
item = Stats(summary=dbstats)
db.session.add(item)
db.session.commit()
def flag_to_gitlab(title, description, label):
""" Create a new issue to our GitLab issue tracker for review
"""
......
arrow==0.10.0
click==6.6
croniter==0.3.16
Flask==0.11.1
Flask-Cors==3.0.2
Flask-HTTPAuth==3.2.2
itsdangerous==0.24
Jinja2==2.8
MarkupSafe==0.23
psycopg2
python-dateutil==2.6.0
redis==2.10.5
requests==2.18.3
rq==0.7.1
rq-scheduler==0.7.0
six==1.10.0
python3-saml==1.2.3
pymongo
Elasticsearch
redis==2.10.5
rq==0.7.1
rq-scheduler==0.7.0
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment