Bookmark! is a Flask + Socket.IO web app that helps students find the cheapest textbook listings. It converts a title to ISBN with Google Books, scrapes multiple retailers, and surfaces the best price with a clean UI.
Live app: https://bookmark-latest.onrender.com/
- Mehul Antony — mantony2@slu.edu
- Alexander Myers — amyersXX@slu.edu
- James Mueller — jmuellerXX@slu.edu
- Henry Wang — hwang59@slu.edu
- Revateesa Dammalapati — revateesa.dammalapati@slu.edu
- Search by title or ISBN with Google Books enrichment (cover, description, metadata)
- Aggregates prices via pluggable parsers (AbeBooks, TextbookX, Macmillan, VitalSource, etc.)
- Real-time search updates through Socket.IO; session-scoped results
- REST endpoints for programmatic access and a simple health check
- Docker support and a small unittest suite
- Python 3.11+ (tested with 3.11.5)
- pip
- Docker (optional for containerized runs)
- Clone the repo and enter it.`
- Install deps:
pip install -r requirements.txt - Run the server:
python .\src\flask_server.py - Open
http://localhost:3000in a browser.
Use the built-in unittest suite: python -m unittest discover -s tests
- Build:
docker build -t bookmark:latest . - Run:
docker run --rm -p 3000:3000 bookmark:latest
The repo also includes helper scripts in control_scripts/ for building and pushing images.
GET /api/health— service heartbeatPOST /api/search/book— body:{ "book_name": "Clean Code" }POST /api/search/isbn— body:{ "isbn": "9780134685991" }
Responses include title, isbn, price, link, and, when available, description and image.
Go_button_pushed— payload:{ search: "9780134685991", condition: "new", medium: "physical" }- Emits
search_started,search_results,redirect(to/results), orsearch_error. - AI recommendations: emit
get_ai_recommendationswith{ currentBook, history }; listen forai_recommendationsorai_error.
src/
flask_server.py # Flask app + Socket.IO events
book_finder.py # Aggregates parser outputs to pick cheapest book
parsers/ # Retailer-specific scrapers
google_books_api.py # Title -> ISBN + metadata
templates/, static/ # Jinja pages and client JS
control_scripts/ # Docker build/run helpers
tests/ # unittest-based checks
- Parsers live in
src/parsers/and are auto-imported bybook_finder; add aparse(isbn, condition, medium)function to integrate a new source. - Templates are loaded relative to project root; keep working directory at repo root when running tests or the server.
- Logging is set to INFO; adjust in
flask_server.pyif you need more verbosity.