"""Search related Handlers.""" from typing import Any from flask import Response, request from marshmallow.exceptions import ValidationError from owsresponse import response from owsresponse.adaptors.flask import flaskify from vectororder.api import app from vectororder.constants import error, fields, pagination as pagination_const from vectororder.logic import search from vectororder.schemas import search_schema from vectororder.utils import handlers, pagination @app.route("/jobs/search", methods=["POST"]) def jobs_search() -> Response: """Search for Vector orders.""" pagination_params = pagination.get_pagination(request) order_by = handlers.get_order_by(request.args.get("order_by", "")) request_id = request.args.get("request_id", None) if not request_id: # Get original incoming request data. request_data = request.get_json() else: # Retrieve previously saved request by ID. request_data = search.get_search_request(request_id) try: query = handlers.parse_request_json( schema=search_schema.SearchPOSTSchema, request_data=request_data ) except ValidationError as e: res = response.create_error_response( code=error.ERROR_CODE_VALIDATION, status=400, message=e.messages ) return flaskify(res) items, total_hits = search.search_vector_orders( offset=pagination_params.offset, limit=pagination_params.limit, order_by=order_by, search_kwargs=query, ) result: dict[str, Any] = { fields.RESPONSE_ITEMS: items, pagination_const.PAGINATION_TOTAL: total_hits, } # If search request was successful. if request_id: # Include the original request in the response # if we were searching by ID. result["original_request"] = request_data else: # Save original incoming request data and return its ID. result["request_id"] = search.save_search_request(request_data) # Add pagination to the response. result[pagination_const.PAGINATION_KEY] = { pagination_const.PAGINATION_OFFSET: pagination_params.offset, pagination_const.PAGINATION_LIMIT: pagination_params.limit, pagination_const.PAGINATION_TYPE: pagination_const.PAGINATION_TYPE_STANDARD, pagination_const.PAGINATION_TOTAL: result.pop( pagination_const.PAGINATION_TOTAL ), } return flaskify(response.Response(result))