Skip to content

Commit ff18da1

Browse files
geritwagnerannaglr
andauthored
Update docs: illustration of API searches (#31)
* add page * extend API docs * revisions * update index * update SearchFile * Update api_search docs --------- Co-authored-by: Anna Geßler <76491696+annaglr@users.noreply.github.com>
1 parent bb41b15 commit ff18da1

File tree

5 files changed

+73
-4
lines changed

5 files changed

+73
-4
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
.. _api_search:
2+
3+
API searches
4+
==========================================================
5+
6+
To run API searches, it is often necessary to represent a query in the form of a URL as opposed to a query string.
7+
Using the Crossref API as an example, the following illustrates how to construct such a URL to retrieve and store records.
8+
9+
.. code-block:: python
10+
:linenos:
11+
12+
import datetime
13+
from pathlib import Path
14+
from colrev.packages.crossref.src import crossref_api
15+
from colrev.writer.write_utils import write_file
16+
17+
from search_query.constants import Fields, Operators
18+
from search_query.or_query import OrQuery
19+
from search_query.search_file import SearchFile
20+
21+
def to_crossref_url(query):
22+
"""Translate query into a Crossref-compatible URL."""
23+
if query.value != Operators.OR:
24+
raise ValueError("Crossref serializer only supports OR queries.")
25+
26+
query_parts = []
27+
for child in query.children:
28+
if child.operator:
29+
raise ValueError("Nested operators are not supported in Crossref serializer.")
30+
if child.search_field.value != Fields.TITLE:
31+
raise ValueError(f"Only title field is supported in Crossref serializer ({child.search_field})")
32+
query_parts.append(child.value.strip())
33+
34+
# Crossref uses '+' for spaces in query values
35+
query_string = "+".join(query_parts)
36+
return f"https://api.crossref.org/works?query.title={query_string}"
37+
38+
if __name__ == "__main__":
39+
40+
query = OrQuery(["microsourcing", "lululemon"], search_field="ti")
41+
42+
url = to_crossref_url(query)
43+
api_crossref = crossref_api.CrossrefAPI(params={"url": url})
44+
records = api_crossref.get_records()
45+
46+
sf = SearchFile(
47+
search_string=query.to_string(),
48+
platform="crossref",
49+
authors=[{"name": "Tom Brady"}],
50+
record_info={"source": "manual", "url": url},
51+
date={"data_entry": datetime.datetime.now().strftime("%Y-%m-%d %H:%M")},
52+
search_field="title",
53+
description="Search for work authored by Tom Brady",
54+
tags=["microsourcing", "lululemon", "research"]
55+
)
56+
57+
sf.save("test/tom_brady_search.json")
58+
59+
records_dict = {record.get_value("doi"): record.get_data() for record in records}
60+
write_file(records_dict=records_dict, filename=Path("test/crossref_records.bib"))
61+

docs/source/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,3 +246,4 @@ References
246246
:maxdepth: 1
247247

248248
dev_docs/parser
249+
api_search/api_search

search_query/__init__.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,18 @@
77
from search_query.or_query import OrQuery
88
from search_query.and_query import AndQuery
99
from search_query.near_query import NEARQuery
10+
from search_query.search_file import SearchFile, load_search_file
1011
from .__version__ import __version__
1112

12-
__all__ = ["__version__", "Query", "OrQuery", "AndQuery", "NEARQuery"]
13+
__all__ = [
14+
"__version__",
15+
"Query",
16+
"OrQuery",
17+
"AndQuery",
18+
"NEARQuery",
19+
"SearchFile",
20+
"load_search_file",
21+
]
1322

1423
# Instead of adding elements to __all__,
1524
# prefixing methods/variables with "__" is preferred.

search_query/linter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def pre_commit_hook() -> int:
3535
file_path = sys.argv[1]
3636

3737
try:
38-
search_file = load_search_file(file_path)
38+
search_file = SearchFile(file_path, platform="unknown")
3939
platform = search_query.parser.get_platform(search_file.platform)
4040
except Exception as e: # pylint: disable=broad-except
4141
print(e)

search_query/search_file.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ def __init__(
2222
authors: Optional[list[dict]] = None,
2323
record_info: Optional[dict] = None,
2424
date: Optional[dict] = None,
25-
search_field: Optional[str] = None,
2625
filepath: Optional[str | Path] = None,
2726
**kwargs: dict,
2827
) -> None:
@@ -31,7 +30,6 @@ def __init__(
3130
self.authors = authors or []
3231
self.record_info = record_info or {}
3332
self.date = date or {}
34-
self.search_field = search_field or ""
3533
self._filepath = Path(filepath) if filepath else None
3634

3735
for key, value in kwargs.items():

0 commit comments

Comments
 (0)