Skip to content

Commit 68ca61e

Browse files
Add search book via ISBN using openlibrary.org API (#5736)
* Add search book via ISBN using openlibrary.org API * FIX: parameters type hints and isbn sizes * Add doctests * Update search_books_by_isbn.py Co-authored-by: Christian Clauss <[email protected]>
1 parent 71ba3a1 commit 68ca61e

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed
+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
"""
2+
Get book and author data from https://openlibrary.org
3+
4+
ISBN: https://en.wikipedia.org/wiki/International_Standard_Book_Number
5+
"""
6+
from json import JSONDecodeError # Workaround for requests.exceptions.JSONDecodeError
7+
8+
import requests
9+
10+
11+
def get_openlibrary_data(olid: str = "isbn/0140328726") -> dict:
12+
"""
13+
Given an 'isbn/0140328726', return book data from Open Library as a Python dict.
14+
Given an '/authors/OL34184A', return authors data as a Python dict.
15+
This code must work for olids with or without a leading slash ('/').
16+
17+
# Comment out doctests if they take too long or have results that may change
18+
# >>> get_openlibrary_data(olid='isbn/0140328726') # doctest: +ELLIPSIS
19+
{'publishers': ['Puffin'], 'number_of_pages': 96, 'isbn_10': ['0140328726'], ...
20+
# >>> get_openlibrary_data(olid='/authors/OL7353617A') # doctest: +ELLIPSIS
21+
{'name': 'Adrian Brisku', 'created': {'type': '/type/datetime', ...
22+
>>> pass # Placate https://github.com/apps/algorithms-keeper
23+
"""
24+
new_olid = olid.strip().strip("/") # Remove leading/trailing whitespace & slashes
25+
if new_olid.count("/") != 1:
26+
raise ValueError(f"{olid} is not a valid Open Library olid")
27+
return requests.get(f"https://openlibrary.org/{new_olid}.json").json()
28+
29+
30+
def summerize_book(ol_book_data: dict) -> dict:
31+
"""
32+
Given Open Library book data, return a summary as a Python dict.
33+
34+
>>> pass # Placate TheAlgorithms @
35+
"""
36+
desired_keys = {
37+
"title": "Title",
38+
"publish_date": "Publish date",
39+
"authors": "Authors",
40+
"number_of_pages": "Number of pages:",
41+
"first_sentence": "First sentence",
42+
"isbn_10": "ISBN (10)",
43+
"isbn_13": "ISBN (13)",
44+
}
45+
data = {better_key: ol_book_data[key] for key, better_key in desired_keys.items()}
46+
data["Authors"] = [
47+
get_openlibrary_data(author["key"])["name"] for author in data["Authors"]
48+
]
49+
data["First sentence"] = data["First sentence"]["value"]
50+
for key, value in data.items():
51+
if isinstance(value, list):
52+
data[key] = ", ".join(value)
53+
return data
54+
55+
56+
if __name__ == "__main__":
57+
import doctest
58+
59+
doctest.testmod()
60+
61+
while True:
62+
isbn = input("\nEnter the ISBN code to search (or 'quit' to stop): ").strip()
63+
if isbn.lower() in ("", "q", "quit", "exit", "stop"):
64+
break
65+
66+
if len(isbn) not in (10, 13) or not isbn.isdigit():
67+
print(f"Sorry, {isbn} is not a valid ISBN. Please, input a valid ISBN.")
68+
continue
69+
70+
print(f"\nSearching Open Library for ISBN: {isbn}...\n")
71+
72+
try:
73+
book_summary = summerize_book(get_openlibrary_data(f"isbn/{isbn}"))
74+
print("\n".join(f"{key}: {value}" for key, value in book_summary.items()))
75+
except JSONDecodeError: # Workaround for requests.exceptions.RequestException:
76+
print(f"Sorry, there are no results for ISBN: {isbn}.")

0 commit comments

Comments
 (0)