API searches

To run API searches, it is often necessary to represent a query in the form of a URL as opposed to a query string. Using the Crossref API as an example, the following illustrates how to construct such a URL to retrieve and store records.

 1import datetime
 2from pathlib import Path
 3from colrev.packages.crossref.src import crossref_api
 4from colrev.writer.write_utils import write_file
 5
 6from search_query.constants import Fields, Operators
 7from search_query.or_query import OrQuery
 8from search_query.search_file import SearchFile
 9
10def to_crossref_url(query):
11    """Translate query into a Crossref-compatible URL."""
12    if query.value != Operators.OR:
13        raise ValueError("Crossref serializer only supports OR queries.")
14
15    query_parts = []
16    for child in query.children:
17        if child.operator:
18            raise ValueError("Nested operators are not supported in Crossref serializer.")
19        if child.search_field.value != Fields.TITLE:
20            raise ValueError(f"Only title field is supported in Crossref serializer ({child.search_field})")
21        query_parts.append(child.value.strip())
22
23    # Crossref uses '+' for spaces in query values
24    query_string = "+".join(query_parts)
25    return f"https://api.crossref.org/works?query.title={query_string}"
26
27if __name__ == "__main__":
28
29    query = OrQuery(["microsourcing", "lululemon"], search_field="ti")
30
31    url = to_crossref_url(query)
32    api_crossref = crossref_api.CrossrefAPI(params={"url": url})
33    records = api_crossref.get_records()
34
35    sf = SearchFile(
36        search_string=query.to_string(),
37        platform="crossref",
38        authors=[{"name": "Tom Brady"}],
39        record_info={"source": "manual", "url": url},
40        date={"data_entry": datetime.datetime.now().strftime("%Y-%m-%d %H:%M")},
41        search_field="title",
42        description="Search for work authored by Tom Brady",
43        tags=["microsourcing", "lululemon", "research"]
44    )
45
46    sf.save("test/tom_brady_search.json")
47
48    records_dict = {record.get_value("doi"): record.get_data() for record in records}
49    write_file(records_dict=records_dict, filename=Path("test/crossref_records.bib"))