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}
Example #2
0
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
    }
Example #3
0
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)
Example #4
0
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)
Example #5
0
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)
Example #6
0
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)