diff --git a/compendium_v2/routes/api.py b/compendium_v2/routes/api.py index 3bfa5bbe4e1a4909c87a19c15414fdb8d6420ce6..551c08c221251579a637ad45faa0496b05268a91 100644 --- a/compendium_v2/routes/api.py +++ b/compendium_v2/routes/api.py @@ -19,12 +19,14 @@ from compendium_v2.routes.budget import routes as budget_routes from compendium_v2.routes.funding import routes as funding_routes from compendium_v2.routes.charging import routes as charging_routes from compendium_v2.routes.staff import routes as staff_routes +from compendium_v2.routes.organization import routes as org_routes routes = Blueprint('compendium-v2-api', __name__) routes.register_blueprint(budget_routes, url_prefix='/budget') routes.register_blueprint(funding_routes, url_prefix='/funding') routes.register_blueprint(charging_routes, url_prefix='/charging') routes.register_blueprint(staff_routes, url_prefix='/staff') +routes.register_blueprint(org_routes, url_prefix='/organization') logger = logging.getLogger(__name__) diff --git a/compendium_v2/routes/organization.py b/compendium_v2/routes/organization.py new file mode 100644 index 0000000000000000000000000000000000000000..61a43354cbfe53dfc0c9bb7723417a46b134e26e --- /dev/null +++ b/compendium_v2/routes/organization.py @@ -0,0 +1,111 @@ +import logging + +from flask import Blueprint, jsonify, current_app + +from compendium_v2 import db +from compendium_v2.routes import common +from compendium_v2.db import model +from typing import Any + +routes = Blueprint('organization', __name__) + + +@routes.before_request +def before_request(): + config = current_app.config['CONFIG_PARAMS'] + dsn_prn = config['SQLALCHEMY_DATABASE_URI'] + db.init_db_model(dsn_prn) + + +logger = logging.getLogger(__name__) + +ORGANIZATION_RESPONSE_SCHEMA = { + '$schema': 'http://json-schema.org/draft-07/schema#', + + 'definitions': { + 'parent_organization': { + 'type': 'object', + 'properties': { + 'nren': {'type': 'string'}, + 'year': {'type': 'integer'}, + 'name': {'type': 'string'} + }, + 'required': ['nren', 'year', 'name'], + 'additionalProperties': False + }, + 'sub_organization': { + 'type': 'object', + 'properties': { + 'nren': {'type': 'string'}, + 'year': {'type': 'integer'}, + 'name': {'type': 'string'}, + 'role': {'type': 'string'}, + }, + 'required': ['nren', 'year', 'name', 'role'], + 'additionalProperties': False + } + }, + + 'type': 'array', + 'items': { + 'oneOf': [ + {'$ref': '#/definitions/parent_organization'}, + {'$ref': '#/definitions/sub_organization'} + ] + } +} + + +@routes.route('/parent', methods=['GET']) +@common.require_accepts_json +def parent_organization_view() -> Any: + """ + handler for /api/organization/parent requests + returns parent organizations for each NREN/year combination + + response will be formatted as: + + .. asjson:: + compendium_v2.routes.organization.ORGANIZATION_RESPONSE_SCHEMA + + :return: + """ + + def _extract_parent(entry: model.ParentOrganization): + return { + 'nren': entry.nren.name, + 'year': entry.year, + 'name': entry.organization + } + + with db.session_scope() as session: + result = [_extract_parent(org) for org in session.query(model.ParentOrganization)] + return jsonify(result) + + +@routes.route('/sub', methods=['GET']) +@common.require_accepts_json +def sub_organization_view() -> Any: + """ + handler for /api/organization/sub requests + returns sub-organizations for each NREN/year combination + + response will be formatted as: + + .. asjson:: + compendium_v2.routes.organization.ORGANIZATION_RESPONSE_SCHEMA + + :return: + """ + + def _extract_sub(entry: model.SubOrganization): + return { + 'nren': entry.nren.name, + 'year': entry.year, + 'name': entry.organization, + 'role': entry.role + } + + with db.session_scope() as session: + result = [_extract_sub(org) for org in session.query(model.SubOrganization)] + return jsonify(result)