Skip to content

Add search book via ISBN using openlibrary.org API #5736

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

Merged
merged 4 commits into from
Nov 1, 2021
Merged
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
76 changes: 76 additions & 0 deletions web_programming/search_books_by_isbn.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
"""
Get book and author data from https://openlibrary.org

ISBN: https://en.wikipedia.org/wiki/International_Standard_Book_Number
"""
from json import JSONDecodeError # Workaround for requests.exceptions.JSONDecodeError

import requests


def get_openlibrary_data(olid: str = "isbn/0140328726") -> dict:
"""
Given an 'isbn/0140328726', return book data from Open Library as a Python dict.
Given an '/authors/OL34184A', return authors data as a Python dict.
This code must work for olids with or without a leading slash ('/').

# Comment out doctests if they take too long or have results that may change
# >>> get_openlibrary_data(olid='isbn/0140328726') # doctest: +ELLIPSIS
{'publishers': ['Puffin'], 'number_of_pages': 96, 'isbn_10': ['0140328726'], ...
# >>> get_openlibrary_data(olid='/authors/OL7353617A') # doctest: +ELLIPSIS
{'name': 'Adrian Brisku', 'created': {'type': '/type/datetime', ...
>>> pass # Placate https://github.com/apps/algorithms-keeper
"""
new_olid = olid.strip().strip("/") # Remove leading/trailing whitespace & slashes
if new_olid.count("/") != 1:
raise ValueError(f"{olid} is not a valid Open Library olid")
return requests.get(f"https://openlibrary.org/{new_olid}.json").json()


def summerize_book(ol_book_data: dict) -> dict:
"""
Given Open Library book data, return a summary as a Python dict.

>>> pass # Placate TheAlgorithms @
"""
desired_keys = {
"title": "Title",
"publish_date": "Publish date",
"authors": "Authors",
"number_of_pages": "Number of pages:",
"first_sentence": "First sentence",
"isbn_10": "ISBN (10)",
"isbn_13": "ISBN (13)",
}
data = {better_key: ol_book_data[key] for key, better_key in desired_keys.items()}
data["Authors"] = [
get_openlibrary_data(author["key"])["name"] for author in data["Authors"]
]
data["First sentence"] = data["First sentence"]["value"]
for key, value in data.items():
if isinstance(value, list):
data[key] = ", ".join(value)
return data


if __name__ == "__main__":
import doctest

doctest.testmod()

while True:
isbn = input("\nEnter the ISBN code to search (or 'quit' to stop): ").strip()
if isbn.lower() in ("", "q", "quit", "exit", "stop"):
break

if len(isbn) not in (10, 13) or not isbn.isdigit():
print(f"Sorry, {isbn} is not a valid ISBN. Please, input a valid ISBN.")
continue

print(f"\nSearching Open Library for ISBN: {isbn}...\n")

try:
book_summary = summerize_book(get_openlibrary_data(f"isbn/{isbn}"))
print("\n".join(f"{key}: {value}" for key, value in book_summary.items()))
except JSONDecodeError: # Workaround for requests.exceptions.RequestException:
print(f"Sorry, there are no results for ISBN: {isbn}.")