"""Application Handlers. Requests are redirected to handlers, which are responsible for getting information from the URL and passing it down to the logic layer. The way each layer talks to each other is through Response objects which defines the type status of the data and the data itself. Please note: the Orchard uses the term handlers over views as convention for clarity See: oto.response for more details. """ from flask import g from flask import jsonify from flask import request from owsresponse import response from owsresponse.adaptors.flask import flaskify from vector_job_rules import config from vector_job_rules.api import app from vector_job_rules.constants import error from vector_job_rules.logic import rule from vector_job_rules.logic import rule_condition_field from vector_job_rules.schemas.rule import UpdateRuleSchema @app.route('/rules', methods=['GET']) def get_rules(): """Get rules on /rules.""" status = request.args.get('status') or None if status not in [None, 'active', 'inactive']: return flaskify( response.create_error_response( code='INVALID_QUERY_PARAM_VALUE', message=error.INVALID_QUERY_PARAM_VALUE, ) ) rule_ids = None if request.args.get('rule_ids'): try: rule_ids = tuple(map(int, request.args['rule_ids'].split(','))) except ValueError: return flaskify( response.create_error_response( code='INVALID_QUERY_PARAM_VALUE', message=error.INVALID_QUERY_PARAM_VALUE, ) ) return flaskify(rule.get_rules(status=status, rule_ids=rule_ids)) @app.route('/rules', methods=['PATCH']) def update_rules_route(): """Update rules at /rules.""" payload = request.get_json(silent=True, force=True) or [] many = True if type(payload) is dict: many = False result = UpdateRuleSchema(many=many).load(payload) if result.errors: return flaskify( response.create_error_response( code=error.ERROR_CODE_INVALID_REQUEST, message=result.errors ) ) return flaskify(rule.update_rules(result.data)) @app.route('/rules/', methods=['GET']) def get_rules_by_id(rule_id): """Get rules on /rules.""" result = rule.get_rules(rule_ids=(rule_id,)) if not result.message['items']: return flaskify( response.create_not_found_response( message='Rule id {} not found'.format(rule_id) ) ) return flaskify(result) @app.route('/rules/conditions', methods=['GET']) def get_rule_condition_fields(): """Get rule condition fields on /rule/conditions.""" return flaskify(rule_condition_field.get_fields()) @app.route(config.HEALTH_CHECK, methods=['GET']) def health(): """Check the health of the application.""" return jsonify({'status': 'ok'}) @app.errorhandler(500) def exception_handler(error): """Handle error when uncaught exception is raised. Default exception handler. Note: Exception will also be sent to Sentry if config.SENTRY is set. Returns: flask.Response: A 500 response with JSON 'code' & 'message' payload. """ message = ( 'The server encountered an internal error ' 'and was unable to complete your request.' ) g.log.exception(error) return flaskify(response.create_fatal_response(message))