def _before_requests(): """Executed before each request for this blueprint. Get the request form and session details. Returns: None|Response: In case of validation error, returns a Flask response, None otherwise. """ logger.info('API request [endpoint: "%s"]', request.endpoint) if request.endpoint == 'constructive.simplify': form = SimplifyFileForm() if 'resource' in request.files.keys( ) else SimplifyPathForm() else: form = ConstructiveFileForm() if 'resource' in request.files.keys( ) else ConstructivePathForm() if not form.validate_on_submit(): return make_response(form.errors, 400) session = get_session() if 'resource' in request.files.keys(): src_filename = secure_filename(form.resource.data.filename) src_file = os.path.join(session['working_path'], src_filename) form.resource.data.save(src_file) else: src_file = os.path.join(os.environ['INPUT_DIR'], form.resource.data) g.src_file = src_file g.form = form g.session = session read_options = parse_read_options(form) crs = form.crs.data if form.crs.data != '' else None g.parameters = {'crs': crs, 'read_options': read_options}
def _before_requests(): """Executed before each request for this blueprint. Get the request form and session details. Returns: None|Response: In case of validation error, returns a Flask response, None otherwise. """ logger.info('API request [endpoint: "%s"]', request.endpoint) file_keys = request.files.keys() if 'resource' in file_keys and 'other' in file_keys: form = JoinDWithinFileForm( ) if request.endpoint == 'join.join_dwithin' else JoinFileForm() elif 'resource' in file_keys: form = JoinDWithinResourceFileForm( ) if request.endpoint == 'join.join_dwithin' else JoinResourceFileForm( ) elif 'other' in file_keys: form = JoinDWithinOtherFileForm( ) if request.endpoint == 'join.join_dwithin' else JoinOtherFileForm() else: form = JoinDWithinPathForm( ) if request.endpoint == 'join.join_dwithin' else JoinPathForm() if not form.validate_on_submit(): return make_response(form.errors, 400) session = get_session() if 'resource' in request.files.keys(): left_filename = secure_filename(form.resource.data.filename) left_file = os.path.join(session['working_path'], left_filename) form.resource.data.save(left_file) else: left_file = os.path.join(os.environ['INPUT_DIR'], form.resource.data) if 'other' in request.files.keys(): right_filename = secure_filename(form.other.data.filename) right_file = os.path.join(session['working_path'], right_filename) form.other.data.save(right_file) else: right_file = os.path.join(os.environ['INPUT_DIR'], form.other.data) g.left_file = left_file g.right_file = right_file g.form = form g.session = session left_read_options = parse_read_options(form) left_crs = form.crs.data if form.crs.data != '' else None right_read_options = parse_read_options(form, prefix="other_") right_crs = form.other_crs.data if form.other_crs.data != '' else None g.parameters = { 'left_crs': left_crs, 'left_read_options': left_read_options, 'right_crs': right_crs, 'right_read_options': right_read_options }
def info(): """**Flask GET rule**. Get the running processes. --- get: summary: Get the running processes. description: Get the running processes among all sessions. tags: - Jobs responses: 200: description: The list of the running processes. content: application/json: schema: type: array items: description: Details of the process. type: object properties: ticket: type: string description: The ticket assigne to the process. example: caff960ab6f1627c11b0de3c6406a140 idempotencyKey: type: string description: The X-Idempotency-Key sent in the headers of the request (null if the request was not associated with an idempotency key). example: e5d16e99-dee1-4d16-acce-ca0f20a83a0a requestType: type: string description: Type of the request. initiated: type: string format: date-time description: The timestamp of the request. """ logger.info('API request [endpoint: "%s"]', request.endpoint) running = db_get_active_jobs() return make_response(jsonify(running), 200)
def health(): """**Flask GET rule** Perform basic health checks. --- get: summary: Get health status. tags: - Misc responses: 200: description: An object with status information. content: application/json: schema: type: object properties: status: type: string enum: - OK - FAILED description: A status of 'OK' or 'FAILED'. details: type: object description: The reason of failure for each component, or 'OK' if not failed. properties: gdal: type: string example: OK filesystem: type: string example: OK db: type: string example: OK """ from osgeo import ogr logger.info('Performing health checks...') msg = {'gdal': 'OK', 'filesystem': 'OK', 'db': 'OK'} status = True for drv in ['CSV', 'GeoJSON', 'ESRI Shapefile']: if ogr.GetDriverByName(drv) is None: msg['gdal'] = 'GDAL is not properly installed.' status = False break for path in [os.environ['WORKING_DIR'], os.environ['OUTPUT_DIR']]: try: _checkDirectoryWritable(path) except Exception as e: msg['filesystem'] = str(e) status = False break try: _checkConnectToDB() except Exception as e: msg['db'] = str(e) status = False return make_response({'status': 'OK' if status else 'FAILED', 'details': msg}, 200)
def download(ticket, filename): """**Flask GET rule Download a resource. --- get: summary: Download a resource. tags: - Misc parameters: - name: ticket in: path schema: type: string description: The ticket of the request resulted in the resource. - name: filename in: path schema: type: string description: The requested file name. responses: 200: description: The requested file. content: application/x-tar: schema: type: string format: binary 404: description: Ticket not found. content: application/json: schema: type: object properties: status: type: string description: Error message example: Ticket not found. 410: description: Resource not available. content: application/json: schema: type: object properties: status: type: string description: Error message example: Resource not available. """ logger.info('API request [endpoint: "%s"]', request.endpoint) queue = Queue().get(ticket=ticket) if queue is None: return make_response({"status": "Ticket not found."}, 404) path = os.path.join(os.environ['OUTPUT_DIR'], queue['result']) if filename != os.path.basename(queue['result']) or not os.path.isfile(path): return make_response({"status": "Resource not available."}, 410) return send_file(path)
def status(): """**Flask GET rule**. Returns the status of a process. --- get: summary: Returns the status of a process. description: Returns the status of the process identified by a ticket or idempotency key. tags: - Jobs parameters: - name: ticket in: query schema: type: string required: false description: The request ticket (required if *idempotency-key* is not given). - name: idempotency-key in: query schema: type: string required: false description: The idempotency-key sent with the request (required if *ticket* is not given). responses: 200: description: The process was found and the response contains its status details. content: application/json: schema: type: object properties: ticket: type: string description: Request ticket. example: caff960ab6f1627c11b0de3c6406a140 idempotencyKey: type: string description: The X-Idempotency-Key sent in the headers of the request (null if the request was not associated with an idempotency key). example: e5d16e99-dee1-4d16-acce-ca0f20a83a0a requestType: type: string enum: - ingest - export description: Type of the request. initiated: type: string format: date-time description: The timestamp of the request. executionTime: type: number format: float description: The execution time in seconds. example: 8.29 completed: type: boolean description: Whether the process has been completed. success: type: boolean description: Whether the process has been completed succesfully. errorMessage: type: string description: The error message in case of failure. resource: type: object description: The resources associated with the process result. properties: link: type: string description: The link to download a resource resulted from an export request; null for any other type of request. example: /download/my_dataset.tar.gz outputPath: type: string description: The relative path of the resource resulted from an export request in the output directory; null for any other type of request or if copy to the output directory was not requested. example: 2102/{token}/caff960ab6f1627c11b0de3c6406a140/my_dataset.tar.gz 400: description: Both query parameters are missing. content: application/json: schema: type: object properties: status: type: string description: Error message example: One of 'ticket', 'idempotency-key' is required in query parameters. 404: description: The ticket or idempotency-key not found. content: application/json: schema: type: object properties: status: type: string description: Error message example: Process not found. """ ticket = request.args.get('ticket') key = request.args.get('idempotency-key') logger.info( 'API request [endpoint: "%s", ticket: "%s", idempotency-key: "%s"]', request.endpoint, ticket, key) if ticket is not None: queue = Queue().get(ticket=ticket) elif key is not None: queue = Queue().get(idempotency_key=key) else: return make_response( { "status": "One of 'ticket', 'idempotency-key' is required in query parameters." }, 400) if queue is None: return make_response({"status": "Process not found."}, 404) if queue['result'] is not None: resource = { 'link': '/download/{ticket}/{filename}'.format(ticket=queue['ticket'], filename=os.path.basename( queue['result'])), 'outputPath': queue['result'] } else: resource = {'link': None, 'outputPath': None} info = { "ticket": queue['ticket'], "idempotencyKey": queue['idempotency_key'], "requestType": queue['request'], "initiated": queue['initiated'], "executionTime": queue['execution_time'], "completed": queue['completed'], "success": queue['success'], "errorMessage": queue['error_msg'], "resource": resource } return make_response(info, 200)