AnnNaser commited on
Commit
ffea045
·
verified ·
1 Parent(s): ad72f6c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +62 -129
app.py CHANGED
@@ -1,141 +1,74 @@
1
  import streamlit as st
2
  import requests
3
- from bs4 import BeautifulSoup
4
- from typing import List, Dict
5
- import time
6
 
7
- # Predefined list of top subjects
8
- top_subjects = [
9
- 'Art', 'Biography', 'Business', 'Children', 'Classics', 'Comics', 'Cookbooks', 'Design', 'Drama',
10
- 'Economics', 'Education', 'Fiction', 'Health', 'History', 'Horror', 'Humor', 'Literature', 'Music',
11
- 'Mystery', 'Non-fiction', 'Philosophy', 'Poetry', 'Politics', 'Psychology', 'Religion', 'Romance',
12
- 'Science', 'Science Fiction', 'Self Help', 'Sports', 'Technology', 'Travel', 'True Crime', 'Young Adult',
13
- 'Architecture', 'Adventure', 'Anthropology', 'Art History', 'Astronomy', 'Biology', 'Business & Finance',
14
- 'Chemistry', 'Cultural Studies', 'Current Affairs', 'Education & Teaching', 'Engineering', 'Ethics',
15
- 'Family & Relationships', 'Geography', 'Graphic Novels', 'Health & Fitness', 'History & Archaeology',
16
- 'Home & Garden', 'Law', 'Linguistics', 'Management', 'Mathematics', 'Music Theory', 'Natural Sciences',
17
- 'Philosophy of Science', 'Physics', 'Political Science', 'Sociology', 'Technology & Engineering', 'Theology',
18
- 'Environmental Science', 'Film & Television', 'Food & Drink', 'Games', 'Gardening', 'Genealogy', 'Health Policy',
19
- 'History of Science', 'Humanities', 'Journalism', 'Languages', 'Linguistics', 'Mathematical Logic', 'Mental Health',
20
- 'Museum Studies', 'Mythology', 'Nursing', 'Nutrition', 'Pharmacology', 'Physical Education', 'Physics & Astronomy',
21
- 'Public Health', 'Public Policy', 'Rehabilitation', 'Research Methods', 'Robotics', 'Social Work', 'Statistics',
22
- 'Technology & Innovation', 'The Arts', 'The Environment', 'Urban Studies', 'Veterinary Medicine', 'Women\'s Studies',
23
- 'Zoology', 'Accounting', 'Advertising', 'Architecture & Design', 'Artificial Intelligence', 'Automotive',
24
- 'Biotechnology', 'Business Strategy', 'Climate Change', 'Data Science', 'Digital Marketing', 'Environmental Studies',
25
- 'Entrepreneurship', 'Finance', 'Global Studies', 'Graphic Design', 'Human Resource Management', 'Humanities',
26
- 'Industrial Design', 'International Relations', 'Journalism & Media', 'Law & Legal Studies', 'Literary Theory',
27
- 'Marketing', 'Media Studies', 'Mental Health & Counseling', 'Natural Resources', 'Philosophy & Ethics', 'Public Relations',
28
- 'Real Estate', 'Renewable Energy', 'Software Engineering', 'Supply Chain Management', 'Sustainability', 'Technology', 'Veganism'
29
- ]
30
-
31
- # OpenLibrary Search API base URL
32
- OPENLIBRARY_SEARCH_API_URL = "https://openlibrary.org/search.json"
33
 
34
- # Function to fetch books by subject and time frame
35
- @st.cache_data(ttl=3600)
36
- def fetch_books_by_subject_and_timeframe(subjects: List[str], start_year: int, end_year: int) -> List[Dict]:
37
- books = []
38
- for subject in subjects:
39
- params = {
40
- "subject": subject.lower(),
41
- "published_in": f"{start_year}-{end_year}", # Filter by year range
42
- "limit": 100, # Fetch up to 100 books per subject
43
- "fields": "key,title,first_publish_year,author_name,cover_i,description" # Specify fields to fetch
44
- }
45
- response = requests.get(OPENLIBRARY_SEARCH_API_URL, params=params)
46
- if response.status_code == 200:
47
- data = response.json()
48
- books.extend(data.get("docs", []))
49
- else:
50
- st.error(f"Failed to fetch books for subject: {subject}")
51
- return books
 
 
 
 
 
52
 
53
- # Function to fetch book details using Book Search API
54
- @st.cache_data(ttl=3600)
55
- def fetch_book_details(book_key: str) -> Dict:
56
- response = requests.get(f"https://openlibrary.org{book_key}.json")
 
 
 
 
57
  if response.status_code == 200:
58
- book_data = response.json()
59
-
60
- # Get Title
61
- title = book_data.get("title", "N/A")
62
-
63
- # Get First Published Year
64
- first_published = book_data.get("first_publish_year", "N/A")
65
 
66
- # Get Author(s)
67
- authors = [author.get("name", "N/A") for author in book_data.get("authors", [])]
 
 
 
 
 
68
 
69
- # Get Description (handle both string and dict cases)
70
- description = book_data.get("description", "N/A")
71
- if isinstance(description, dict):
72
- description = description.get("value", "N/A")
73
-
74
- # Get Book Cover (using cover API)
75
- cover_id = book_data.get("covers", [None])[0]
76
- book_cover = f"https://covers.openlibrary.org/b/id/{cover_id}-M.jpg" if cover_id else "N/A"
77
-
78
- return {
79
- 'Title': title,
80
- 'First Published Year': first_published,
81
- 'Authors': ", ".join(authors) if authors else "N/A",
82
- 'Description': description,
83
- 'Book Cover': book_cover
84
- }
85
  else:
86
- st.error(f"Failed to fetch details for book: {book_key}")
87
- return None
88
 
89
- # Function to scrape book description from OpenLibrary
90
- @st.cache_data(ttl=3600)
91
- def scrape_book_description(book_key: str) -> str:
92
- response = requests.get(f"https://openlibrary.org{book_key}")
93
- if response.status_code == 200:
94
- soup = BeautifulSoup(response.text, 'html.parser')
95
- description_div = soup.find("div", class_="read-more__content")
96
- if description_div:
97
- paragraphs = description_div.find_all('p')
98
- return " ".join(paragraph.get_text(strip=True) for paragraph in paragraphs)
99
- return "N/A"
100
 
101
- # Streamlit App
102
- def main():
103
- st.title("📚 Book Recommendation System")
104
-
105
- # Sidebar for user inputs
106
- st.sidebar.header("Filters")
107
- selected_subjects = st.sidebar.multiselect(
108
- "Select Subjects",
109
- top_subjects,
110
- default=["Fiction", "Philosophy"]
111
- )
112
- start_year, end_year = st.sidebar.slider(
113
- "Select Year Range",
114
- 1800, 2025, (1900, 2000)
115
- )
116
-
117
- if st.sidebar.button("Fetch Books"):
118
- if not selected_subjects:
119
- st.error("Please select at least one subject.")
120
  else:
121
- with st.spinner("Fetching books..."):
122
- start_time = time.time()
123
- books = fetch_books_by_subject_and_timeframe(selected_subjects, start_year, end_year)
124
- if books:
125
- st.success(f"Found {len(books)} books in {time.time() - start_time:.2f} seconds!")
126
- for book in books:
127
- book_key = book.get("key", "")
128
- if book_key:
129
- book_details = fetch_book_details(book_key)
130
- if book_details:
131
- st.subheader(book_details["Title"])
132
- st.write(f"**First Published Year:** {book_details['First Published Year']}")
133
- st.write(f"**Authors:** {book_details['Authors']}")
134
- st.write(f"**Description:** {book_details['Description']}")
135
- if book_details["Book Cover"] != "N/A":
136
- st.image(book_details["Book Cover"])
137
- else:
138
- st.warning("No books found.")
139
-
140
- if __name__ == "__main__":
141
- main()
 
1
  import streamlit as st
2
  import requests
 
 
 
3
 
4
+ # Open Library API base URL
5
+ OPEN_LIBRARY_API = "https://openlibrary.org/search.json"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
 
7
+ # List of subjects
8
+ subjects_list = [
9
+ "Classic Literature", "Modern Literature", "Postmodern Literature",
10
+ "Romanticism", "Realism", "Naturalism", "Existentialism", "Absurdism",
11
+ "Gothic Fiction", "Science Fiction", "Fantasy Literature", "Historical Fiction",
12
+ "Mystery and Detective Fiction", "Horror Literature", "Adventure Novels",
13
+ "Bildungsroman", "Satire", "Tragedy", "Comedy", "Dystopian Literature",
14
+ "Utopian Literature", "Magical Realism", "Stream of Consciousness",
15
+ "Metafiction", "Allegory", "Mythology", "Folklore", "Fairy Tales",
16
+ "Poetry", "Epic Poetry", "Lyric Poetry", "Sonnet", "Haiku", "Free Verse",
17
+ "Drama", "Tragicomedy", "Theater of the Absurd", "Shakespearean Plays",
18
+ "Greek Tragedy", "Modern Drama", "Surrealism in Literature", "Symbolism",
19
+ "Transcendentalism", "Stoicism", "Epicureanism", "Nihilism",
20
+ "Feminist Literature", "Postcolonial Literature", "Marxist Literary Criticism",
21
+ "Psychoanalytic Criticism", "Formalism", "New Criticism", "Cultural Studies",
22
+ "Comparative Literature", "World Literature", "African Literature",
23
+ "Asian Literature", "Latin American Literature", "European Literature",
24
+ "American Literature", "British Literature", "Russian Literature",
25
+ "French Literature", "German Literature", "Italian Literature",
26
+ "Spanish Literature", "Ancient Literature", "Medieval Literature",
27
+ "Renaissance Literature", "Enlightenment Literature", "Victorian Literature",
28
+ "Modernist Literature", "Postmodernist Literature", "Contemporary Literature"
29
+ ]
30
 
31
+ # Function to fetch books from Open Library API
32
+ def fetch_books(subjects, year_range):
33
+ query = " AND ".join([f"subject:{sub.replace(' ', '+')}" for sub in subjects])
34
+ year_query = f"first_publish_year:[{year_range[0]} TO {year_range[1]}]"
35
+
36
+ api_url = f"{OPEN_LIBRARY_API}?{query} AND {year_query}&limit=20"
37
+ response = requests.get(api_url)
38
+
39
  if response.status_code == 200:
40
+ data = response.json()
41
+ books = []
 
 
 
 
 
42
 
43
+ for doc in data.get("docs", []):
44
+ book = {
45
+ "Title": doc.get("title", "N/A"),
46
+ "Author": ", ".join(doc.get("author_name", ["N/A"])),
47
+ "First Published Year": doc.get("first_publish_year", "N/A"),
48
+ }
49
+ books.append(book)
50
 
51
+ return books
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  else:
53
+ st.error("Failed to fetch data from Open Library.")
54
+ return []
55
 
56
+ # Streamlit App UI
57
+ st.title("📚 Book Finder")
 
 
 
 
 
 
 
 
 
58
 
59
+ # Multi-select for subjects
60
+ selected_subjects = st.multiselect("Select Literary Subjects", subjects_list, default=["Classic Literature"])
61
+
62
+ # Year range slider
63
+ year_range = st.slider("Select Year Range", min_value=1800, max_value=2025, value=(1900, 2025))
64
+
65
+ # Button to search books
66
+ if st.button("🔍 Search Books"):
67
+ with st.spinner("Fetching books..."):
68
+ books = fetch_books(selected_subjects, year_range)
69
+
70
+ if books:
71
+ st.success(f"📖 Found {len(books)} books!")
72
+ st.table(books)
 
 
 
 
 
73
  else:
74
+ st.warning("No books found for the selected criteria.")