Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to use the v2 API as v1 has been fully discontinued #6

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ a heat-shock transcription factor.
print(assemblyid)

For a full list of attributes, please refer to the [RCSB
schema](http://search.rcsb.org/rcsbsearch/v1/metadata/schema).
schema](http://search.rcsb.org/rcsbsearch/v2/metadata/schema).

### Fluent Example

Expand Down
2 changes: 1 addition & 1 deletion docs/queries.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ return `Terminal` objects for the comparisons.
Attributes are available from the rcsb_attributes object and can be tab-completed.
They can additionally be constructed from strings using the `Attr(attribute)`
constructor. For a full list of attributes, please refer to the [RCSB
schema](http://search.rcsb.org/rcsbsearch/v1/metadata/schema).
schema](http://search.rcsb.org/rcsbsearch/v2/metadata/schema).

`Terminal`s are combined into `Group`s using python's bitwise operators. This is
analogous to how bitwise operators act on python `set` objects. The operators are
Expand Down
2 changes: 1 addition & 1 deletion docs/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ a heat-shock transcription factor.
print(assemblyid)

For a full list of attributes, please refer to the [RCSB
schema](http://search.rcsb.org/rcsbsearch/v1/metadata/schema).
schema](http://search.rcsb.org/rcsbsearch/v2/metadata/schema).

### Fluent Example

Expand Down
2 changes: 1 addition & 1 deletion rcsbsearch/resources/metadata_schema.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions rcsbsearch/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

from .search import Attr

METADATA_SCHEMA_URL = "http://search.rcsb.org/rcsbsearch/v1/metadata/schema"
METADATA_SCHEMA_URL = "http://search.rcsb.org/rcsbsearch/v2/metadata/schema"
SEARCH_SCHEMA_URL = "http://search.rcsb.org/json-schema-rcsb_search_query.json"

ENV_RCSBSEARCH_DOWNLOAD_SCHEMA = "RCSBSEARCH_DOWNLOAD_SCHEMA"
Expand Down Expand Up @@ -42,7 +42,7 @@ def _download_json_schema():
"Get the current JSON schema from the web"
url = METADATA_SCHEMA_URL

logging.info(f"Dowloading {url}")
logging.info(f"Downloading {url}")
response = requests.get(url)
response.raise_for_status()
return response.json()
Expand Down
55 changes: 18 additions & 37 deletions rcsbsearch/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from dataclasses import dataclass
from datetime import date
from typing import (
Any,
Callable,
Dict,
Generic,
Expand Down Expand Up @@ -52,6 +53,7 @@
Tuple[int, ...],
Tuple[float, ...],
Tuple[date, ...],
Dict[str, Any],
]
# Types valid for numeric operators
TNumberLike = Union[int, float, date, "Value[int]", "Value[float]", "Value[date]"]
Expand Down Expand Up @@ -195,7 +197,7 @@ class Terminal(Query):
>>> Terminal(value="tubulin")

A full list of attributes is available in the
`schema <http://search.rcsb.org/rcsbsearch/v1/metadata/schema>`_.
`schema <http://search.rcsb.org/rcsbsearch/v2/metadata/schema>`_.
Operators are documented `here <http://search.rcsb.org/#field-queries>`_.

The :py:class:`Attr` class provides a more pythonic way of constructing Terminals.
Expand All @@ -205,7 +207,7 @@ class Terminal(Query):
operator: Optional[str] = None
value: Optional[TValue] = None
service: str = "text"
negation: bool = False
negation: Optional[bool] = False
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally I think we should swap this to None as well, but I was afraid of breaking existing workflows which depend on this default. Instead I am passing negation=None in the TextQuery class super().__init__.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I'm now seeing that this might have been a longer-standing error which was raised in another PR:
#5

node_id: int = 0

def to_dict(self):
Expand Down Expand Up @@ -274,14 +276,14 @@ def __str__(self):
class TextQuery(Terminal):
"""Special case of a Terminal for free-text queries"""

def __init__(self, value: str, negation: bool = False):
def __init__(self, value: str):
"""Search for the string value anywhere in the text

Args:
value: free-text query
negation: find structures without the pattern
"""
super().__init__(value=value, negation=negation)
super().__init__(service="full_text", value=value, negation=None)


@dataclass(frozen=True)
Expand Down Expand Up @@ -343,7 +345,7 @@ def _assign_ids(self, node_id=0) -> Tuple[Query, int]:
return (self, node_id)

def __str__(self):
"" # hide in documentation
"""""" # hide in documentation
if self.operator == "and":
return f"({' & '.join((str(n) for n in self.nodes))})"
elif self.operator == "or":
Expand Down Expand Up @@ -378,9 +380,7 @@ class Attr:
+--------------------+---------------------+
| equals | attr == date,number |
+--------------------+---------------------+
| range | attr[start:end] |
+--------------------+---------------------+
| range_closed | |
| range | dict (keys below)* |
+--------------------+---------------------+
| exists | bool(attr) |
+--------------------+---------------------+
Expand All @@ -392,8 +392,13 @@ class Attr:
Pre-instantiated attributes are available from the
:py:data:`rcsbsearch.rcsb_attributes` object. These are generally easier to use
than constructing Attr objects by hand. A complete list of valid attributes is
available in the `schema <http://search.rcsb.org/rcsbsearch/v1/metadata/schema>`_.
available in the `schema <http://search.rcsb.org/rcsbsearch/v2/metadata/schema>`_.

* The `range` dictionary requires the following keys:
* "from" -> int
* "to" -> int
* "include_lower" -> bool
* "include_upper" -> bool
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's unclear to me if this is the best change of API that we want in the library, but it is a direct change to the new format specified in v2. Open to suggestions!

"""

attribute: str
Expand Down Expand Up @@ -454,7 +459,7 @@ def equals(self, value: TNumberLike) -> Terminal:
value = value.value
return Terminal(self.attribute, "equals", value)

def range(self, value: Union[List[int], Tuple[int, int]]) -> Terminal:
def range(self, value: Dict[str, Any]) -> Terminal:
"""Attribute is within the specified half-open range

Args:
Expand All @@ -464,21 +469,6 @@ def range(self, value: Union[List[int], Tuple[int, int]]) -> Terminal:
value = value.value
return Terminal(self.attribute, "range", value)

def range_closed(
self,
value: Union[
List[int], Tuple[int, int], "Value[List[int]]", "Value[Tuple[int, int]]"
],
) -> Terminal:
"""Attribute is within the specified closed range

Args:
value: lower and upper bounds `[a, b]`
"""
if isinstance(value, Value):
value = value.value
return Terminal(self.attribute, "range_closed", value)

def exists(self) -> Terminal:
"""Attribute is defined for the structure"""
return Terminal(self.attribute, "exists")
Expand Down Expand Up @@ -729,16 +719,7 @@ def equals(self, value: TNumberLike) -> Query:
...

@_attr_delegate(Attr.range)
def range(self, value: Union[List[int], Tuple[int, int]]) -> Query:
...

@_attr_delegate(Attr.range_closed)
def range_closed(
self,
value: Union[
List[int], Tuple[int, int], "Value[List[int]]", "Value[Tuple[int, int]]"
],
) -> Query:
def range(self, value: Dict[str, Any]) -> Query:
...

@_attr_delegate(Attr.exists)
Expand Down Expand Up @@ -974,7 +955,7 @@ class Session(Iterable[str]):
Handles paging the query and parsing results
"""

url = "http://search.rcsb.org/rcsbsearch/v1/query"
url = "http://search.rcsb.org/rcsbsearch/v2/query"
query_id: str
query: Query
return_type: ReturnType
Expand Down Expand Up @@ -1012,7 +993,7 @@ def _make_params(self, start=0):
query=self.query.to_dict(),
return_type=self.return_type,
request_info=dict(query_id=self.query_id, src="ui"), # TODO src deprecated?
request_options=dict(pager=dict(start=start, rows=self.rows)),
request_options=dict(paginate=dict(start=start, rows=self.rows)),
)

def _single_query(self, start=0) -> Optional[Dict]:
Expand Down
2 changes: 1 addition & 1 deletion tests/test_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ def test_example1():
def test_example2():
"'X-Ray Structures Search' from http://search.rcsb.org/#examples"
q = (
Terminal(value='"thymidine kinase"')
TextQuery('"thymidine kinase"')
& Terminal(
"rcsb_entity_source_organism.taxonomy_lineage.name",
"exact_match",
Expand Down