Пример #1
0
def get_all(events, context):
    """returns paged list with the latest status for the samples in the given experiment"""

    if 'pathParameters' in events:
        logger.info("events: {}".format(events))
        tm = TableManager()
        table = tm.get_acquisition_table()

        if events['pathParameters'] is not None and 'sample' in events['pathParameters'] and 'experiment' in events[
            'pathParameters']:
            logger.info(
                f"Not the first page // {events['pathParameters']['sample']}// {events['pathParameters']['experiment']}")
            last = {
                "id": events['pathParameters']['sample'],
                "experiment": events['pathParameters']['experiment']
            }
        else:
            logger.info("First page")
            last = None

        try:
            if last is None:
                result = table.scan(Limit=500)
            else:
                result = table.scan(ExclusiveStartKey=last, Limit=500)

            items = result['Items']

            body = {"items": items}

            if 'LastEvaluatedKey' in result:
                body['last_item'] = result['LastEvaluatedKey']

            data = {
                'statusCode': 200,
                'headers': __HTTP_HEADERS__,
                'body': json.dumps(body)
            }

            return data
        except Exception as ex:
            logger.info("QUERY-ERROR: %s" % str(ex))
            return {
                "statusCode": 418,
                "headers": __HTTP_HEADERS__,
                "body": json.dumps({"error": ex.args})
            }

    else:
        return {
            "statusCode": 404,
            "headers": __HTTP_HEADERS__,
            "body": json.dumps({"error": "not supported, need's be called from a http event!"})
        }
Пример #2
0
def test_get_with_reference(requireMocking):
    # store data
    tm = TableManager()
    table = tm.get_acquisition_table()
    item = {
        'sample': '180415dZKsa20_1',
        'experiment': '12345',
        'acquisition': {
            'instrument': 'Leco GC-Tof',
            'name': 'GCTOF',
            'ionisation': 'positive',
            'method': 'gcms'
        },
        'metadata': {
            'class': '382172',
            'species': 'rat',
            'organ': 'tissue'
        },
        'userdata': {
            'label': 'GP_S_6_006',
            'comment': ''
        },
        'processing': {
            'method': 'gcms | test | test | positive'
        },
        'time': 1525121375499,
        'id': '180415dZKsa20_1',
        'references': [{
            'name': 'minix',
            'value': '12345'
        }]
    }
    try:
        validate(item, __ACQUISITION_SCHEMA__)
        table.put_item(Item=tm.sanitize_json_for_dynamo(item))
    except ValidationException as vex:
        result = None
        fail(str(vex.body))
    except ClientError as cer:
        result = None
        fail(str(cer.response))

    # process data

    result = get.get({"pathParameters": {"sample": "180415dZKsa20_1"}}, {})

    assert result['statusCode'] == 200
    assert json.loads(result['body'])["id"] == "180415dZKsa20_1"
    assert json.loads(
        result['body'])["acquisition"]["instrument"] == "Leco GC-Tof"
    assert json.loads(result['body'])["references"][0]["name"] == "minix"
    assert json.loads(result['body'])["references"][0]["value"] == "12345"
Пример #3
0
def test_get_experiment(requireMocking, sample_count):
    tm = TableManager()
    table = tm.get_acquisition_table()

    try:
        for x in range(0, sample_count):
            table.put_item(Item=tm.sanitize_json_for_dynamo({
                "sample": f"test-{x:06d}",
                "experiment": "1",
                "id": f"test-{x:06d}",
                "acquisition": {
                    "instrument": "random",
                    "ionisation": "positive",
                    "method": "test-method"
                },
                "metadata": {
                    "class": f"{x%100}",
                    "species": "rat",
                    "organ": "tissue"
                },
                "userdata": {
                    "label": "GP_S_6_006",
                    "comment": ""
                },
                "processing": {
                    "method": "test-method | random | test | positive"
                }
            }))
    except ValidationException as vex:
        result = None
        fail(str(vex.body))
    except ClientError as cer:
        result = None
        fail(str(cer.response))

    page_size = 3

    result = experiment.get(
        {'pathParameters': {
            'experiment': '1',
            'psize': page_size
        }}, {})

    data = json.loads(result['body'])

    assert result['statusCode'] == 200
    assert len(data['items']) == page_size
    assert data['last_item']['id'] == 'test-000002'
Пример #4
0
def get(events, context):
    """returns the specific element from the storage"""

    if 'pathParameters' in events:
        if 'sample' in events['pathParameters']:
            tm = TableManager()
            table = tm.get_acquisition_table()
            versions_table = tm.get_acquisition_table_version()
            sample = urllib.parse.unquote(events['pathParameters']['sample'])

            logger.info("looking for sample: {} ( raw its {} )".format(sample, events['pathParameters']['sample']))
            result = table.query(
                KeyConditionExpression=Key('id').eq(sample)
            )
            versions = versions_table.query(
                KeyConditionExpression=Key('id').eq(sample)
            )

            if "Items" in result and len(result['Items']) > 0:

                record = result['Items'][0]

                if "Items" in versions and len(versions['Items']) > 0:
                    record['versions'] = versions['Items']
                return {
                    "statusCode": 200,
                    "headers": __HTTP_HEADERS__,
                    "body": json.dumps(record)
                }
            else:
                return {
                    "statusCode": 404,
                    "headers": __HTTP_HEADERS__,
                    "body": json.dumps({"error": "no sample found with this identifier : {}".format(
                        events['pathParameters']['sample'])})
                }
        else:
            return {
                "statusCode": 404,
                "headers": __HTTP_HEADERS__,
                "body": json.dumps({"error": "sample name is not provided!"})
            }
    else:
        return {
            "statusCode": 404,
            "headers": __HTTP_HEADERS__,
            "body": json.dumps({"error": "not supported, need's be called from a http event!"})
        }
Пример #5
0
def get(events, context):
    """returns paged list with the latest status for the samples in the given experiment"""

    if 'pathParameters' in events:

        if 'experiment' in events['pathParameters']:
            expId = events['pathParameters']['experiment']

            if 'psize' in events['pathParameters']:
                page_size = int(events['pathParameters']['psize'])
            else:
                page_size = 25

            query_params = {
                'IndexName': 'experiment-id-index',
                'Select': 'ALL_ATTRIBUTES',
                'KeyConditionExpression': Key('experiment').eq(expId),
                'Limit': page_size
            }

            if 'lastSample' in events['pathParameters']:
                logger.info(
                    f"Not the first page // {events['pathParameters']['lastSample']}"
                )
                query_params['ExclusiveStartKey'] = {
                    "experiment": expId,
                    "id": events['pathParameters']['lastSample']
                }

            tm = TableManager()
            table = tm.get_acquisition_table()

            try:
                result = table.query(**query_params)
                items = result['Items']

                body = {"items": items}

                if 'LastEvaluatedKey' in result:
                    body['last_item'] = result['LastEvaluatedKey']

                data = {
                    'statusCode': 200,
                    'headers': __HTTP_HEADERS__,
                    'body': json.dumps(body)
                }

                return data
            except Exception as ex:
                logger.info("QUERY-ERROR: %s" % str(ex))
                return {
                    "statusCode": 418,
                    "headers": __HTTP_HEADERS__,
                    "body": json.dumps({"error": ex.args})
                }
        else:
            return {
                "statusCode": 422,
                "headers": __HTTP_HEADERS__,
                "body": json.dumps({"error": "sample name is not provided!"})
            }

    else:
        return {
            "statusCode":
            404,
            "headers":
            __HTTP_HEADERS__,
            "body":
            json.dumps({
                "error":
                "not supported, need's be called from a http event!"
            })
        }
Пример #6
0
def store_sample_for_job(event, context):
    """
    stores an associated sample for an job
    :param event:
    :param context:
    :return:
    """

    body = json.loads(event['body'])
    try:
        validate(body, __SAMPLE_JOB_SCHEMA__)
    except Exception as e:
        logger.info(f"received body was considered invalid: {body}")
        traceback.print_exc()

        return {
            'body': json.dumps({
                'state': str(FAILED),
                'reason': str(e)
            }),
            'statusCode': 503,
            'isBase64Encoded': False,
            'headers': __HTTP_HEADERS__
        }
    tracking = body.get('meta', {}).get('tracking', [])
    meta = body.get('meta', {})
    meta.pop('tracking', None)

    sample = body.get('sample')
    job = body.get("job")

    try:
        # overwrite tracking states and extension if it's provided
        for track in tracking:
            if 'extension' in track:
                fileHandle = "{}.{}".format(sample, track['extension'])
            else:
                fileHandle = None

            save_sample_state(sample=sample,
                              state=track['state'],
                              fileHandle=fileHandle)

        if len(meta) > 0:
            # update the class here by updating the acquisition part
            # 1. get acquisition data
            # 2. set new metadata
            tm = TableManager()
            acqtable = tm.get_acquisition_table()
            result = acqtable.query(
                KeyConditionExpression=Key('id').eq(sample))

            if "Items" in result and len(result['Items']) > 0:
                data = result['Items'][0]
            else:

                timestamp = int(time.time() * 1000)
                data = {
                    'time': timestamp,
                    'id': sample,
                    'sample': sample,
                    'experiment': _fetch_experiment(sample),
                    'acquisition': {
                        'instrument': 'unknown',
                        'ionisation': 'unknown',
                        'method': 'unknown'
                    },
                    'processing': {
                        'method': 'unknown'
                    },
                }

            try:
                data = Merge().data_merge(data, meta)
                store_acquisition_data(data, tm)
            except Exception as e:
                logger.info(f"generated data was considered invalid: {data}")
                traceback.print_exc()

                return {
                    'body':
                    json.dumps({
                        'state': str(FAILED),
                        'reason': str(traceback.format_exc())
                    }),
                    'statusCode':
                    503,
                    'isBase64Encoded':
                    False,
                    'headers':
                    __HTTP_HEADERS__
                }

        set_sample_job_state(job=job, sample=sample, state=SCHEDULING)

        return {
            'body':
            json.dumps({
                'state': str(SCHEDULING),
                'job': job,
                'sample': sample,
                'reason': 'sample was submitted'
            }),
            'statusCode':
            200,
            'isBase64Encoded':
            False,
            'headers':
            __HTTP_HEADERS__
        }
    except Exception as e:
        # update job state in the system to failed with the related reason

        error_diagnostics = traceback.format_exc()
        set_sample_job_state(job=job,
                             sample=sample,
                             state=FAILED,
                             reason=f"{str(e)} = {error_diagnostics}")

        traceback.print_exc()
        return {
            'body':
            json.dumps({
                'state': str(FAILED),
                'job': job,
                'sample': sample,
                'reason': str(e)
            }),
            'statusCode':
            500,
            'isBase64Encoded':
            False,
            'headers':
            __HTTP_HEADERS__
        }