Project 1: Books



In this project, you’ll build a book review website. Users will be able to register for your website and then log in using their username and password. Once they log in, they will be able to search for books, leave reviews for individual books, and see the reviews made by other people. You’ll also use the a third-party API by Goodreads, another book review website, to pull in ratings from a broader audience. Finally, users will be able to query for book details and book reviews programmatically via your website’s API.

Getting Started


For this project, you’ll need to set up a PostgreSQL database to use with our application. It’s possible to set up PostgreSQL locally on your own computer, but for this project, we’ll use a database hosted by Heroku, an online web hosting service.

  1. Navigate to, and create an account if you don’t already have one.
  2. On Heroku’s Dashboard, click “New” and choose “Create new app.”
  3. Give your app a name, and click “Create app.”
  4. On your app’s “Overview” page, click the “Configure Add-ons” button.
  5. In the “Add-ons” section of the page, type in and select “Heroku Postgres.”
  6. Choose the “Hobby Dev - Free” plan, which will give you access to a free PostgreSQL database that will support up to 10,000 rows of data. Click “Provision.”
  7. Now, click the “Heroku Postgres :: Database” link.
  8. You should now be on your database’s overview page. Click on “Settings”, and then “View Credentials.” This is the information you’ll need to log into your database. You can access the database via Adminer, filling in the server (the “Host” in the credentials list), your username (the “User”), your password, and the name of the database, all of which you can find on the Heroku credentials page.

Alternatively, if you install PostgreSQL on your own computer, you should be able to run psql URI on the command line, where the URI is the link provided in the Heroku credentials list.

Python and Flask

  1. First, make sure you install a copy of Python. For this course, you should be using Python version 3.6 or higher.
  2. You’ll also need to install pip. If you downloaded Python from Python’s website, you likely already have pip installed (you can check by running pip in a terminal window). If you don’t have it installed, be sure to install it before moving on!

To try running your first Flask application:

  1. Download the project1 distribution directory from and unzip it.
  2. In a terminal window, navigate into your project1 directory.
  3. Run pip3 install -r requirements.txt in your terminal window to make sure that all of the necessary Python packages (Flask and SQLAlchemy, for instance) are installed.
  4. Set the environment variable FLASK_APP to be On a Mac or on Linux, the command to do this is export On Windows, the command is instead set You may optionally want to set the environment variable FLASK_DEBUG to 1, which will activate Flask’s debugger and will automatically reload your web application whenever you save a change to a file.
  5. Set the environment variable DATABASE_URL to be the URI of your database, which you should be able to see from the credentials page on Heroku.
  6. Run flask run to start up your Flask application.
  7. If you navigate to the URL provided by flask, you should see the text "Project 1: TODO"!

Goodreads API

Goodreads is a popular book review website, and we’ll be using their API in this project to get access to their review data for individual books.

  1. Go to and sign up for a Goodreads account if you don’t already have one.
  2. Navigate to and apply for an API key. For “Application name” and “Company name” feel free to just write “project1,” and no need to include an application URL, callback URL, or support URL.
  3. You should then see your API key. (For this project, we’ll care only about the “key”, not the “secret”.)
  4. You can now use that API key to make requests to the Goodreads API, documented here. In particular, Python code like the below
import requests
res = requests.get("", params={"key": "KEY", "isbns": "9781632168146"})

where KEY is your API key, will give you the review and rating data for the book with the provided ISBN number. In particular, you might see something like this dictionary:

{'books': [{
                'id': 29207858,
                'isbn': '1632168146',
                'isbn13': '9781632168146',
                'ratings_count': 0,
                'reviews_count': 1,
                'text_reviews_count': 0,
                'work_ratings_count': 26,
                'work_reviews_count': 113,
                'work_text_reviews_count': 10,
                'average_rating': '4.04'

Note that work_ratings_count here is the number of ratings that this particular book has received, and average_rating is the book’s average score out of 5.


Alright, it’s time to actually build your web application! Here are the requirements:

    "title": "Memory",
    "author": "Doug Lloyd",
    "year": 2015,
    "isbn": "1632168146",
    "review_count": 28,
    "average_score": 5.0

If the requested ISBN number isn’t in your database, your website should return a 404 error.

Beyond these requirements, the design, look, and feel of the website are up to you! You’re also welcome to add additional features to your website, so long as you meet the requirements laid out in the above specification!



For the API, do the JSON keys need to be in order?

Any order is fine!

AttributeError: 'NoneType' object has no attribute '_instantiate_plugins'

Make sure that you’ve set your DATABASE_URL environment variable before running flask run!

How to Submit

IMPORTANT: On 1 July 2020, CS50W will update to a new version and this version of this project will no longer be accepted for credit. If you haven’t completed the entire course by that date, that’s okay! If you ultimately receive a passing grade on this project, we will consider it equivalent in scope and content to Project 2 in the new version of the course, and within two weeks after 1 July 2020 your gradebook at will update to reflect that you have received credit for having completed Project 2.

  1. If you haven’t already done so, visit this link, log in with your GitHub account, and click Authorize cs50. Then, check the box indicating that you’d like to grant course staff access to your submissions, and click Join course.
  2. If you’ve installed submit50, execute
    submit50 web50/projects/2020/x/1

    Otherwise, using Git, push your work to, where USERNAME is your GitHub username, on a branch called web50/projects/2020/x/1.

  3. Record a 1- to 5-minute screencast in which you demonstrate your app’s functionality and/or walk viewers through your code. Upload that video to YouTube (as unlisted or public, but not private) or somewhere else. To aid in the staff’s review, in your video’s description on YouTube, you should timestamp where, minimally, each of the following occurs. This is not optional; failure to do this will result in your submission being rejected:
    • Search (showing multiple results for a query)
    • Individual book page showing leaving a review
    • API page
  4. Submit this form.

You can then go to to view your progress!