Follow instructions to install the latest version of python for your platform in the python docs
We recommend working within a virtual environment whenever using Python for projects. This keeps your dependencies for each project separate and organaized. Instructions for setting up a virual enviornment for your platform can be found in the python docs
Once you have your virtual environment setup and running, install dependencies by naviging to the /backend
directory and running:
pip install -r requirements.txt
This will install all of the required packages we selected within the requirements.txt
file.
-
Flask is a lightweight backend microservices framework. Flask is required to handle requests and responses.
-
SQLAlchemy is the Python SQL toolkit and ORM we'll use handle the lightweight sqlite database. You'll primarily work in app.py and can reference models.py.
-
Flask-CORS is the extension we'll use to handle cross origin requests from our frontend server.
With Postgres running, restore a database using the trivia.psql file provided. From the backend folder in terminal run:
psql trivia < trivia.psql
From within the backend
directory first ensure you are working using your created virtual environment.
To run the server, execute:
export FLASK_APP=flaskr
export FLASK_ENV=development
flask run
Setting the FLASK_ENV
variable to development
will detect file changes and restart the server automatically.
Setting the FLASK_APP
variable to flaskr
directs flask to use the flaskr
directory and the __init__.py
file to find the application.
One note before you delve into your tasks: for each endpoint you are expected to define the endpoint and response data. The frontend will be a plentiful resource because it is set up to expect certain endpoints and response data formats already. You should feel free to specify endpoints in your own way; if you do so, make sure to update the frontend or you will get some unexpected behavior.
- Use Flask-CORS to enable cross-domain requests and set response headers.
- Create an endpoint to handle GET requests for questions, including pagination (every 10 questions). This endpoint should return a list of questions, number of total questions, current category, categories.
- Create an endpoint to handle GET requests for all available categories.
- Create an endpoint to DELETE question using a question ID.
- Create an endpoint to POST a new question, which will require the question and answer text, category, and difficulty score.
- Create a POST endpoint to get questions based on category.
- Create a POST endpoint to get questions based on a search term. It should return any questions for whom the search term is a substring of the question.
- Create a POST endpoint to get questions to play the quiz. This endpoint should take category and previous question parameters and return a random questions within the given category, if provided, and that is not one of the previous questions.
- Create error handlers for all expected errors including 400, 404, 422 and 500.
REVIEW_COMMENT
Endpoints GET '/categories' GET ... POST ... DELETE ...
GET '/categories'
- Fetches a dictionary of categories in which the keys are the ids and the value is the corresponding string of the category
- Request Arguments: None
- Returns: An object with a single key, categories, that contains a object of id: category_string key:value pairs.
{'1' : "Science",
'2' : "Art",
'3' : "Geography",
'4' : "History",
'5' : "Entertainment",
'6' : "Sports"}
GET '/questions?page={number}'
- Fetches a dictionary showing all categories , all paginated questions defaulting to page 1 and total number of questions. Optional - number is the page number
- Request Arguments: None
- Response: An object with keys - categories,questions, current_category and total_questions.
{
"categories": [
{
"id": 1,
"type": "Science"
},
{
"id": 2,
"type": "Art"
},
{
"id": 3,
"type": "Geography"
},
{
"id": 4,
"type": "History"
},
{
"id": 5,
"type": "Entertainment"
},
{
"id": 6,
"type": "Sports"
}
],
"current_category": null,
"questions": [
{
"answer": "Maya Angelou",
"category": 4,
"difficulty": 2,
"id": 5,
"question": "Whose autobiography is entitled 'I Know Why the Caged Bird Sings'?"
},
{
"answer": "Muhammad Ali",
"category": 4,
"difficulty": 1,
"id": 9,
"question": "What boxer's original name is Cassius Clay?"
},
{
"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": "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": "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?"
}
],
"total_questions": 19
}
GET '/categories/{id}/questions'
- Fetches a dictionary showing current selected category name , all questions from the selected category and total number of questions from selected category.
- Request Arguments: Category id
- Response: An object with keys - current_category,questions and total_questions.
{
"currentCategory": "Geography",
"questions": [
{
"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?"
},
{
"answer": "Agra",
"category": 3,
"difficulty": 2,
"id": 15,
"question": "The Taj Mahal is located in which Indian city?"
},
{
"answer": "Paris",
"category": 3,
"difficulty": 1,
"id": 32,
"question": "Where is the Eiffel Tower?"
}
],
"totalQuestions": 4
}
GET '/add'
- Fetches a dictionary showing all categories to allow for selecting question category for creation of new question
- Request Arguments: None
- Response: An object with key categories
GET '/play'
- Fetches a dictionary showing all categories to allow for selecting question category for playing quiz
- Request Arguments: None
- Response: An object with key categories
{
"categories": [
{
"id": 1,
"type": "Science"
},
{
"id": 2,
"type": "Art"
},
{
"id": 3,
"type": "Geography"
},
{
"id": 4,
"type": "History"
},
{
"id": 5,
"type": "Entertainment"
},
{
"id": 6,
"type": "Sports"
}
]
}
POST '/add'
- Add a new question to the database. Each question must contain a question, answer, valid category and valid difficulty value.
- Request Arguments: question , answer , difficulty, category
- Response: An object with keys - message and success
{
"message": "Question added successfully",
"success": true
}
POST '/search'
- Search questions containing the search term.
- Request Arguments: searchTerm
- Response: An object with keys - questions, total_questions, current_category and success
{
"currentCategory": null,
"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,
"totalQuestions": 2
}
POST '/quizzes'
- Get a random question from selected category passed as a request argument.
- Request Arguments: previous_questions and quiz_category
{
"previous_questions" : [],
"quiz_category": {
"type" : {
"id" : 5,
"type" : "Entertainment"
},
"id" : 4
}
}
- Response: An object with key - question
{
"question": {
"answer": "Apollo 13",
"category": 5,
"difficulty": 4,
"id": 2,
"question": "What movie earned Tom Hanks his third straight Oscar nomination, in 1996?"
}
}
DELETE '/questions/delete/{id}'
- Delete question with id passed to query string.
- Request Arguments: None
- Response: An object with keys - deleted and success
{
"deleted": 9,
"success": true
}
Errors
- 400 -- Bad request
- 404 -- Not found
- 422 -- Not processable
- 500 -- Internal Server Error
Sample response
{
"error": 422,
"message": "Not processable",
"success": false
}
To run the tests, run
dropdb trivia_test
createdb trivia_test
psql trivia_test < trivia.psql
python test_flaskr.py