Ejemplo n.º 1
0
    def test_safe_redis_get_json(self, mock_redis, mock_logger):
        # test with valid json
        mock_redis.return_value.get.side_effect = lambda key: json.dumps(
            {key: 'test'})
        self.assertDictEqual(safe_redis_get_json('test_key'),
                             {'test_key': 'test'})
        mock_logger.info.assert_called_with('Loaded test_key from redis')
        mock_logger.warn.assert_not_called()

        # test with no value in cache
        mock_logger.reset_mock()
        mock_redis.return_value.get.side_effect = lambda key: None
        self.assertIsNone(safe_redis_get_json('test_key'))
        mock_logger.info.assert_not_called()
        mock_logger.warn.assert_not_called()

        # test with invalid json in cache
        mock_logger.reset_mock()
        mock_redis.return_value.get.side_effect = lambda key: key
        self.assertIsNone(safe_redis_get_json('test_key'))
        mock_logger.info.assert_called_with('Loaded test_key from redis')
        self.assertEqual(mock_logger.warn.call_args.args[0].split('\t')[0],
                         'Unable to fetch "test_key" from redis:')

        # test with redis connection error
        mock_logger.reset_mock()
        mock_redis.side_effect = Exception('invalid redis')
        self.assertIsNone(safe_redis_get_json('test_key'))
        mock_logger.info.assert_not_called()
        mock_logger.warn.assert_called_with(
            'Unable to connect to redis host localhost: invalid redis')
Ejemplo n.º 2
0
def get_index_metadata(index_name,
                       client,
                       include_fields=False,
                       use_cache=True):
    if use_cache:
        cache_key = 'index_metadata__{}'.format(index_name)
        cached_metadata = safe_redis_get_json(cache_key)
        if cached_metadata:
            return cached_metadata

    try:
        mappings = client.indices.get_mapping(index=index_name)
    except Exception as e:
        raise InvalidIndexException('{} - Error accessing index: {}'.format(
            index_name, e.error if hasattr(e, 'error') else str(e)))
    index_metadata = {}
    for index_name, mapping in mappings.items():
        variant_mapping = mapping['mappings']
        index_metadata[index_name] = variant_mapping.get('_meta', {})
        if include_fields:
            index_metadata[index_name]['fields'] = {
                field: field_props.get('type')
                for field, field_props in
                variant_mapping['properties'].items()
            }
    if use_cache and include_fields:
        # Only cache metadata with fields
        safe_redis_set_json(cache_key, index_metadata)
    return index_metadata
Ejemplo n.º 3
0
def get_project_guids_user_can_view(user):
    cache_key = 'projects__{}'.format(user)
    project_guids = safe_redis_get_json(cache_key)
    if project_guids is not None:
        return project_guids

    is_data_manager = user_is_data_manager(user)
    if is_data_manager:
        projects = Project.objects.all()
    else:
        projects = get_local_access_projects(user)

    project_guids = [p.guid for p in projects.only('guid')]
    if is_anvil_authenticated(user) and not is_data_manager:
        workspaces = [
            '/'.join([ws['workspace']['namespace'], ws['workspace']['name']])
            for ws in list_anvil_workspaces(user)
        ]
        project_guids += [
            p.guid for p in Project.objects.filter(
                workspace_name__isnull=False).exclude(
                    workspace_name='').exclude(
                        guid__in=project_guids).annotate(
                            workspace=Concat('workspace_namespace', Value(
                                '/'), 'workspace_name')).filter(
                                    workspace__in=workspaces).only('guid')
        ]

    safe_redis_set_json(cache_key,
                        project_guids,
                        expire=TERRA_WORKSPACE_CACHE_EXPIRE_SECONDS)

    return project_guids
Ejemplo n.º 4
0
def list_anvil_workspaces(user):
    """Get all the workspaces accessible by the logged-in user.

    :param
    user (User model): who's credentials will be used to access AnVIL
    :return
    A list of workspaces that the user has access (OWNER, WRITER, or READER). Each of the workspace has
    its name and namespace.

    """
    path = 'api/workspaces?fields=public,workspace.name,workspace.namespace'
    cache_key = 'terra_req__{}__{}'.format(user, path)
    r = safe_redis_get_json(cache_key)
    if r:
        logger.info('Terra API cache hit for: GET {} {}'.format(path, user))
        return r

    r = _user_anvil_call('get', path, user)

    # remove the public workspaces which can't be the projects in seqr
    r = [{'workspace': ws['workspace']} for ws in r if not ws.get('public', True)]

    safe_redis_set_json(cache_key, r, TERRA_WORKSPACE_CACHE_EXPIRE_SECONDS)

    return r
Ejemplo n.º 5
0
def user_get_workspace_access_level(user, workspace_namespace, workspace_name, meta_fields=None):
    fields = ',{}'.format(','.join(meta_fields)) if meta_fields else ''
    path = "api/workspaces/{0}/{1}?fields=accessLevel,canShare{2}".format(workspace_namespace, workspace_name, fields)

    cache_key = 'terra_req__{}__{}'.format(user, path)
    r = safe_redis_get_json(cache_key)
    if r:
        logger.info('Terra API cache hit for: GET {} {}'.format(path, user))
        return r

    # Exceptions are handled to return an empty result for users who have no permission to access the workspace
    r = _user_anvil_call('get', path, user, handle_errors=True)

    if r:
        safe_redis_set_json(cache_key, r, TERRA_PERMS_CACHE_EXPIRE_SECONDS)

    return r
Ejemplo n.º 6
0
def user_get_workspace_access_level(user, workspace_namespace, workspace_name):
    path = "api/workspaces/{0}/{1}?fields=accessLevel".format(
        workspace_namespace, workspace_name)

    cache_key = 'terra_req__{}__{}'.format(user, path)
    r = safe_redis_get_json(cache_key)
    if r:
        logger.info('Terra API cache hit for: GET {} {}'.format(path, user))
        return r

    try:
        r = _user_anvil_call('get', path, user)
    except TerraNotFoundException as et:
        logger.warning(str(et))
        return {}

    safe_redis_set_json(cache_key, r, TERRA_PERMS_CACHE_EXPIRE_SECONDS)

    return r
Ejemplo n.º 7
0
Archivo: utils.py Proyecto: uwgsit/seqr
def get_index_metadata(index_name, client):
    cache_key = 'index_metadata__{}'.format(index_name)
    cached_metadata = safe_redis_get_json(cache_key)
    if cached_metadata:
        return cached_metadata

    try:
        mappings = client.indices.get_mapping(index=index_name)
    except Exception as e:
        raise InvalidIndexException('Error accessing index "{}": {}'.format(
            index_name, e.error if hasattr(e, 'error') else e.message))
    index_metadata = {}
    for index_name, mapping in mappings.items():
        variant_mapping = mapping['mappings'].get(
            VARIANT_DOC_TYPE) or mapping['mappings'].get(SV_DOC_TYPE, {})
        index_metadata[index_name] = variant_mapping.get('_meta', {})
        index_metadata[index_name]['fields'] = variant_mapping[
            'properties'].keys()
    safe_redis_set_json(cache_key, index_metadata)
    return index_metadata
Ejemplo n.º 8
0
Archivo: utils.py Proyecto: uwgsit/seqr
def get_es_variants(search_model,
                    es_search_cls=EsSearch,
                    sort=XPOS_SORT_KEY,
                    **kwargs):
    cache_key = 'search_results__{}__{}'.format(search_model.guid, sort
                                                or XPOS_SORT_KEY)
    previous_search_results = safe_redis_get_json(cache_key) or {}

    previously_loaded_results, search_kwargs = es_search_cls.process_previous_results(
        previous_search_results, **kwargs)
    if previously_loaded_results is not None:
        return previously_loaded_results, previous_search_results.get(
            'total_results')

    search = search_model.variant_search.search

    genes, intervals, invalid_items = parse_locus_list_items(
        search.get('locus', {}))
    if invalid_items:
        raise Exception('Invalid genes/intervals: {}'.format(
            ', '.join(invalid_items)))
    rs_ids, variant_ids, invalid_items = _parse_variant_items(
        search.get('locus', {}))
    if invalid_items:
        raise Exception('Invalid variants: {}'.format(
            ', '.join(invalid_items)))

    es_search = es_search_cls(
        search_model.families.all(),
        previous_search_results=previous_search_results,
        skip_unaffected_families=search.get('inheritance'),
    )

    if search.get('customQuery'):
        custom_q = search['customQuery']
        if not isinstance(custom_q, list):
            custom_q = [custom_q]
        for q_dict in custom_q:
            es_search.filter(Q(q_dict))

    if sort:
        es_search.sort(sort)

    if genes or intervals or rs_ids or variant_ids:
        es_search.filter_by_location(genes=genes,
                                     intervals=intervals,
                                     rs_ids=rs_ids,
                                     variant_ids=variant_ids,
                                     locus=search['locus'])
        if (variant_ids or rs_ids) and not (
                genes
                or intervals) and not search['locus'].get('excludeLocations'):
            search_kwargs['num_results'] = len(variant_ids) + len(rs_ids)

    if search.get('freqs'):
        es_search.filter_by_frequency(search['freqs'])

    es_search.filter_by_annotation_and_genotype(
        search.get('inheritance'),
        quality_filter=search.get('qualityFilter'),
        annotations=search.get('annotations'),
        annotations_secondary=search.get('annotations_secondary'),
        pathogenicity=search.get('pathogenicity'))

    if hasattr(es_search, 'aggregate_by_gene'):
        es_search.aggregate_by_gene()

    variant_results = es_search.search(**search_kwargs)

    safe_redis_set_json(cache_key, es_search.previous_search_results)

    return variant_results, es_search.previous_search_results['total_results']