This project is a full-stack trivia game where users can test their knowledge answering trivia questions. It is a TDD-based API with the following functionality:
-
Display questions:
- All questions or by category.
- Show the question, category, and difficulty.
- Show/hide the answer.
-
Delete questions.
-
Add new questions with mandatory question and answer texts.
-
Search for questions based on a keyword.
-
Play the quiz game, randomizing either all questions or within a specific category.
Tech stack includes:
- React.js and Sass for the website's frontend.
- Python3 and Flask as my server-side language and server-side framework.
- PostgreSQL as my database of choice.
- SQLAlchemy ORM to be my ORM library of choice.
Make sure to have PostgreSQL installed, if it is not, execute:
sudo apt-get -y install postgresql
First, start your PostgreSQL database server by running:
sudo service postgresql start
Then, create your project's database by running:
createdb trivia
Add your database connection string as an environment variable by executing:
export DATABASE_URL=<db_connection_string> # e.g. postgresql://username:password@localhost:5432/database
Make sure to be inside the /backend
directory. To import the database schema and initial data, run:
psql trivia < trivia.psql
Navigate to the /backend
directory and make sure that you have Python3 installed.
Run the following to create a virtual environment:
python3 -m venv env
Activate your newly created virtual environment by running:
source env/bin/activate
To install backend dependencies, simply run:
pip install -r requirements.txt
Prepare the development environment by executing:
export FLASK_APP=flaskr
export FLASK_ENV=development
To run the server at any time, use:
flask run
By default, the Flask server runs on http://localhost:5000.
Navigate to the /frontend
directory and make sure that you have Node.js and npm installed first.
To install backend dependencies, simply run:
npm install
To start the frontend server, run:
npm start
This will run the React frontend server at http://localhost:3000.
To run the tests, run
dropdb trivia_test
createdb trivia_test
psql trivia_test < trivia.psql
python3 test_flaskr.py
Omit the dropdb
command the first time you run tests.
-
Base URL:
- currently this application is only hosted locally.
- The backend is hosted at
http://127.0.0.1:5000/
.
-
Authentication: This version does not require authentication or API keys.
Errors are returned as JSON in the following format:
{
"error": 404,
"message": "resource not found",
"success": false
}
The API returns three types of errors:
- 400: bad request.
- 404: resource not found.
- 422: unprocessable.
-
General: returns a list of all categories.
-
Sample:
curl http://127.0.0.1:5000/categories
{
"categories": [
{
"1": "Science"
},
{
"2": "Art"
},
{
"3": "Geography"
},
{
"4": "History"
},
{
"5": "Entertainment"
},
{
"6": "Sports"
}
],
"success": true,
"total_categories": 6
}
-
General:
- Returns a list questions.
- Results are paginated in groups of 10.
- Also returns a list of categories and the total number of questions.
-
Sample:
curl http://127.0.0.1:5000/questions
{
"categories": [
{
"1": "Science"
},
{
"2": "Art"
},
{
"3": "Geography"
},
{
"4": "History"
},
{
"5": "Entertainment"
},
{
"6": "Sports"
}
],
"questions": [
{
"answer": "Apollo 13",
"category": 5,
"difficulty": 4,
"id": 2,
"question": "What movie earned Tom Hanks his third straight Oscar nomination, in 1996?"
},
{
"answer": "Tom Cruise",
"category": 5,
"difficulty": 4,
"id": 4,
"question": "What actor did author Anne Rice first denounce, then praise in the role of her beloved Lestat?"
},
{
"answer": "Maya Angelou",
"category": 4,
"difficulty": 2,
"id": 5,
"question": "Whose autobiography is entitled 'I Know Why the Caged Bird Sings'?"
},
{
"answer": "Edward Scissorhands",
"category": 5,
"difficulty": 3,
"id": 6,
"question": "What was the title of the 1990 fantasy directed by Tim Burton about a young man with multi-bladed appendages?"
},
{
"answer": "Muhammad Ali",
"category": 4,
"difficulty": 1,
"id": 9,
"question": "What boxer's original name is Cassius Clay?"
},
{
"answer": "Brazil",
"category": 6,
"difficulty": 3,
"id": 10,
"question": "Which is the only team to play in every soccer World Cup tournament?"
},
{
"answer": "Uruguay",
"category": 6,
"difficulty": 4,
"id": 11,
"question": "Which country won the first ever soccer World Cup in 1930?"
},
{
"answer": "George Washington Carver",
"category": 4,
"difficulty": 2,
"id": 12,
"question": "Who invented Peanut Butter?"
},
{
"answer": "Lake Victoria",
"category": 3,
"difficulty": 2,
"id": 13,
"question": "What is the largest lake in Africa?"
},
{
"answer": "The Palace of Versailles",
"category": 3,
"difficulty": 3,
"id": 14,
"question": "In which royal palace would you find the Hall of Mirrors?"
}
],
"success": true,
"total_questions": 20
}
-
General:
- Deletes a question by id, using url parameters.
- Returns the id of the deleted question upon success.
-
Sample:
curl http://127.0.0.1:5000/questions/6 -X DELETE
{
"deleted": 6,
"success": true
}
-
General:
- Creates a new question using JSON request parameters.
- Returns JSON object with the newly created question id, as well as paginated questions.
- Also returns the updated number of total questions.
-
Sample:
curl http://127.0.0.1:5000/questions -X POST -H "Content-Type: application/json" -d '{"question": "Which US state contains an area known as the Upper Penninsula?", "answer": "Michigan", "difficulty": 3, "category": "3"}'
{
"created": 26,
"questions": [
{
"answer": "Apollo 13",
"category": 5,
"difficulty": 4,
"id": 2,
"question": "What movie earned Tom Hanks his third straight Oscar nomination, in 1996?"
},
{
"answer": "Tom Cruise",
"category": 5,
"difficulty": 4,
"id": 4,
"question": "What actor did author Anne Rice first denounce, then praise in the role of her beloved Lestat?"
},
{
"answer": "Maya Angelou",
"category": 4,
"difficulty": 2,
"id": 5,
"question": "Whose autobiography is entitled 'I Know Why the Caged Bird Sings'?"
},
{
"answer": "Edward Scissorhands",
"category": 5,
"difficulty": 3,
"id": 6,
"question": "What was the title of the 1990 fantasy directed by Tim Burton about a young man with multi-bladed appendages?"
},
{
"answer": "Muhammad Ali",
"category": 4,
"difficulty": 1,
"id": 9,
"question": "What boxer's original name is Cassius Clay?"
},
{
"answer": "Brazil",
"category": 6,
"difficulty": 3,
"id": 10,
"question": "Which is the only team to play in every soccer World Cup tournament?"
},
{
"answer": "Uruguay",
"category": 6,
"difficulty": 4,
"id": 11,
"question": "Which country won the first ever soccer World Cup in 1930?"
},
{
"answer": "George Washington Carver",
"category": 4,
"difficulty": 2,
"id": 12,
"question": "Who invented Peanut Butter?"
},
{
"answer": "Lake Victoria",
"category": 3,
"difficulty": 2,
"id": 13,
"question": "What is the largest lake in Africa?"
},
{
"answer": "The Palace of Versailles",
"category": 3,
"difficulty": 3,
"id": 14,
"question": "In which royal palace would you find the Hall of Mirrors?"
}
],
"success": true,
"total_questions": 19
}
-
General:
- Searches for questions using search term in JSON request parameters.
- Returns JSON object with paginated matching questions.
- Also returns total number of matching questions.
-
Sample:
curl http://127.0.0.1:5000/questions/search -X POST -H "Content-Type: application/json" -d '{"search_term": "title"}'
{
"questions": [
{
"answer": "Maya Angelou",
"category": 4,
"difficulty": 2,
"id": 5,
"question": "Whose autobiography is entitled 'I Know Why the Caged Bird Sings'?"
},
{
"answer": "Edward Scissorhands",
"category": 5,
"difficulty": 3,
"id": 6,
"question": "What was the title of the 1990 fantasy directed by Tim Burton about a young man with multi-bladed appendages?"
}
],
"success": true,
"total_results": 2
}
-
General:
- Gets questions by category id, using url parameters.
- Returns JSON object with paginated matching questions.
- Also returns total number of the category's questions.
-
Sample:
curl http://127.0.0.1:5000/categories/1/questions
{
"current_category": 2,
"questions": [
{
"answer": "Escher",
"category": 2,
"difficulty": 1,
"id": 16,
"question": "Which Dutch graphic artist–initials M C was a creator of optical illusions?"
},
{
"answer": "Mona Lisa",
"category": 2,
"difficulty": 3,
"id": 17,
"question": "La Giaconda is better known as what?"
},
{
"answer": "One",
"category": 2,
"difficulty": 4,
"id": 18,
"question": "How many paintings did Van Gogh sell in his lifetime?"
}
],
"success": true,
"total_results": 3
}
-
General:
- Allows users to play a quiz game.
- Uses JSON request parameters of category and previous questions.
- Returns JSON object with a random question that is not among previous questions.
-
Sample:
curl http://127.0.0.1:5000/quiz -X POST -H "Content-Type: application/json" -d '{"previous_questions": [20, 21], "category": 1}'
{
"question": {
"answer": "Blood",
"category": 1,
"difficulty": 4,
"id": 22,
"question": "Hematology is a branch of medicine involving the study of what?"
},
"success": true
}
Ahmed Baligh authored the API (__init__.py
), test suite (test_flaskr.py
), and this README. Mohamed Agina along with Ahmed Baligh made major updates and improvement to all the files the (/frontend
) directory.
All other project files, including the models and structure of frontend, were created by Udacity as a project template for the Full Stack Web Developer Nanodegree.