Skip to content

Commit

Permalink
Allow to search by passing a dictionary
Browse files Browse the repository at this point in the history
  • Loading branch information
krassowski committed Sep 17, 2021
1 parent d5e8b56 commit aadbd18
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 2 deletions.
31 changes: 31 additions & 0 deletions README.md
Expand Up @@ -92,6 +92,37 @@ print(gene_names)

> `{'rs6311': ['HTR2A'], 'rs662138': ['SLC22A1']}`
#### Example: obtaining the SNP rs ID number from chromosomal position

You can use the query string directly:

```python
results = entrez_api.search(
'13[CHROMOSOME] AND human[ORGANISM] AND 31873085[POSITION]',
database='snp',
max_results=10
)
results.data['esearchresult']['idlist']
```

> `['59296319', '17076752', '7336701', '4']`
Or pass a dictionary (no validation of argument is performed, 'AND' conjunction is used):

```python
results = entrez_api.search(
dict(chromosome=13, organism='human', position=31873085),
database='snp',
max_results=10
)
results.data['esearchresult']['idlist']
```

> `['59296319', '17076752', '7336701', '4']`
The base position should use the latest genome assembly (GRCh38 at the time of writing);
you can use the position in previous assembly coordinates by replacing `POSITION` with `POSITION_GRCH37`.
For more information of the arguments accepted by the SNP database see the [entrez help page](https://www.ncbi.nlm.nih.gov/snp/docs/entrez_help/) on NCBI website.

### Installation

Expand Down
14 changes: 12 additions & 2 deletions easy_entrez/api.py
@@ -1,6 +1,6 @@
import requests
from requests import Response
from typing import Dict, List, Optional
from typing import Dict, List, Optional, Union
from xml.etree import ElementTree
from copy import copy
from time import time, sleep
Expand All @@ -12,6 +12,13 @@
)


def _match_all(**kwargs):
return ' AND '.join([
f'{value}[{field}]'
for field, value in kwargs.items()
])


class EntrezResponse:
"""The wrapper around the Entrez response."""

Expand Down Expand Up @@ -119,9 +126,12 @@ def _request(self, query: EntrezQuery, custom_payload=None) -> EntrezResponse:
# TODO: make entrez response a generic and provide better typing of responses
@uses_query(SearchQuery)
def search(
self, term: str, max_results: int,
self, term: Union[str, dict], max_results: int,
database: EntrezDatabase = 'pubmed', min_date=None, max_date=None
):
if isinstance(term, dict):
term = _match_all(**term)

assert not min_date and not max_date # TODO
query = SearchQuery(term=term, max_results=max_results, database=database)
return self._request(query=query)
Expand Down
9 changes: 9 additions & 0 deletions tests/test_api.py
@@ -1,5 +1,6 @@
from pytest import raises
from easy_entrez import EntrezAPI
from easy_entrez.api import _match_all


entrez_api = EntrezAPI(
Expand All @@ -11,6 +12,14 @@
)


def test_query_helpers():
assert (
_match_all(chromosome=13, organism='human', position=31873085)
==
'13[chromosome] AND human[organism] AND 31873085[position]'
)


def test_search():
result = entrez_api.search('cancer AND human[organism]', max_results=1)
assert result.data['esearchresult']['count'] != 0
Expand Down

0 comments on commit aadbd18

Please sign in to comment.