diff --git a/README.md b/README.md index 17fcdda27..13d6f11e0 100644 --- a/README.md +++ b/README.md @@ -1,49 +1,170 @@ -# API Development and Documentation Final Project +# Trivia API Documentation + +This documentation provides detailed information about the available API endpoints in the Trivia application. Each endpoint is described with its URL, request parameters, and expected response body. + +## API Endpoints + +### 1. GET `/categories` +**Description**: Fetches all categories. + +**Request Parameters**: None + +**Response Body**: +```json +{ + "success": true, + "categories": { + "1": "Science", + "2": "Art" + // other categories + } +} +``` +### 2. GET `/questions` +**Description**: Fetches all questions with pagination. + +**Request Parameters**: page (optional): Page number for pagination (default: 1) + +**Response Body**: +```json +{ + "success": true, + "questions": [ + { + "id": 1, + "question": "What is the capital of France?", + "answer": "Paris", + "category": "1", + "difficulty": 1 + } + // other questions + ], + "total_questions": 50 +} +``` +### 3. DELETE /questions/question_id +**Description**: Deletes a specific question. + +**Request Parameters**: None + +**Response Body**: +```json +{ + "success": true, + "deleted": 1 +} +``` +### 4. POST /questions +**Description**: Adds a new question. + +**Request Parameters**: None + +**Request Body**: +```json +{ + "question": "What is the largest planet?", + "answer": "Jupiter", + "category": "1", + "difficulty": 3 +} +``` + +**Response Body**: +```json +{ + "success": true +} +``` +### 5. POST /questions/search +**Description**: Adds a new question. + +**Request Parameters**: None + +**Request Body**: +```json +{ + "searchTerm": "planet" +} +``` +**Response Body**: +```json +{ + "success": true, + "questions": [ + { + "id": 1, + "question": "What is the largest planet?", + "answer": "Jupiter", + "category": "1", + "difficulty": 3 + } + // other matching questions + ], + "total_questions": 1 +} +``` +### 6. GET /categories/category_id/questions +**Description**: Fetches questions for a specific category. + +**Request Parameters**: None + +**Response Body**: +```json +{ + "success": true, + "questions": [ + { + "id": 1, + "question": "What is the capital of France?", + "answer": "Paris", + "category": "1", + "difficulty": 1 + } + // other questions in the category + ], + "total_questions": 10, + "current_category": 1 +} +``` +### 7. POST /quizzes +**Description**: Fetches the next question for a quiz. + +**Request Parameters**: None + +**Request Body**: +```json +{ + "previous_questions": [1, 2], + "quiz_category": { + "id": "1", + "type": "Science" + } +} +``` +**Response Body**: +```json +{ + "success": true, + "question": { + "id": 3, + "question": "What is the boiling point of water?", + "answer": "100°C", + "category": "1", + "difficulty": 1 + } +} +``` +### 8. ERROR HANDLING +**The API returns error responses in the following format**: +```json +{ + "success": false, + "error": 404, + "message": "Resource not found" +} +``` +**Error Codes**: +- 400: Bad request +- 404: Resource not found +- 422: Unprocessable entity -## Trivia App - -Udacity is invested in creating bonding experiences for its employees and students. A bunch of team members got the idea to hold trivia on a regular basis and created a webpage to manage the trivia app and play the game, but their API experience is limited and still needs to be built out. - -That's where you come in! Help them finish the trivia app so they can start holding trivia and seeing who's the most knowledgeable of the bunch. The application must: - -1. Display questions - both all questions and by category. Questions should show the question, category and difficulty rating by default and can show/hide the answer. -2. Delete questions. -3. Add questions and require that they include question and answer text. -4. Search for questions based on a text query string. -5. Play the quiz game, randomizing either all questions or within a specific category. - -Completing this trivia app will give you the ability to structure plan, implement, and test an API - skills essential for enabling your future applications to communicate with others. - -## Starting and Submitting the Project - -[Fork](https://help.github.com/en/articles/fork-a-repo) the project repository and [clone](https://help.github.com/en/articles/cloning-a-repository) your forked repository to your machine. Work on the project locally and make sure to push all your changes to the remote repository before submitting the link to your repository in the Classroom. - -## About the Stack - -We started the full stack application for you. It is designed with some key functional areas: - -### Backend - -The [backend](./backend/README.md) directory contains a partially completed Flask and SQLAlchemy server. You will work primarily in `__init__.py` to define your endpoints and can reference models.py for DB and SQLAlchemy setup. These are the files you'd want to edit in the backend: - -1. `backend/flaskr/__init__.py` -2. `backend/test_flaskr.py` - -> View the [Backend README](./backend/README.md) for more details. - -### Frontend - -The [frontend](./frontend/README.md) directory contains a complete React frontend to consume the data from the Flask server. If you have prior experience building a frontend application, you should feel free to edit the endpoints as you see fit for the backend you design. If you do not have prior experience building a frontend application, you should read through the frontend code before starting and make notes regarding: - -1. What are the end points and HTTP methods the frontend is expecting to consume? -2. How are the requests from the frontend formatted? Are they expecting certain parameters or payloads? - -Pay special attention to what data the frontend is expecting from each API response to help guide how you format your API. The places where you may change the frontend behavior, and where you should be looking for the above information, are marked with `TODO`. These are the files you'd want to edit in the frontend: - -1. `frontend/src/components/QuestionView.js` -2. `frontend/src/components/FormView.js` -3. `frontend/src/components/QuizView.js` - -By making notes ahead of time, you will practice the core skill of being able to read and understand code and will have a simple plan to follow to build out the endpoints of your backend API. - -> View the [Frontend README](./frontend/README.md) for more details. diff --git a/backend/flaskr/__init__.py b/backend/flaskr/__init__.py index d991c6bd5..95490e9cd 100644 --- a/backend/flaskr/__init__.py +++ b/backend/flaskr/__init__.py @@ -1,107 +1,182 @@ from flask import Flask, request, abort, jsonify from flask_cors import CORS import random - from models import setup_db, Question, Category, db QUESTIONS_PER_PAGE = 10 + +def paginate_questions(request, questions): + page = request.args.get("page", 1, type=int) + start = (page - 1) * QUESTIONS_PER_PAGE + end = start + QUESTIONS_PER_PAGE + + formatted_questions = [question.format() for question in questions] + return formatted_questions[start:end] + + def create_app(test_config=None): - # create and configure the app app = Flask(__name__) if test_config is None: setup_db(app) else: - database_path = test_config.get('SQLALCHEMY_DATABASE_URI') + database_path = test_config.get("SQLALCHEMY_DATABASE_URI") setup_db(app, database_path=database_path) - """ - @TODO: Set up CORS. Allow '*' for origins. Delete the sample route after completing the TODOs - """ - with app.app_context(): - db.create_all() - - """ - @TODO: Use the after_request decorator to set Access-Control-Allow - """ - - """ - @TODO: - Create an endpoint to handle GET requests - for all available categories. - """ - - - """ - @TODO: - 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. - - TEST: At this point, when you start the application - you should see questions and categories generated, - ten questions per page and pagination at the bottom of the screen for three pages. - Clicking on the page numbers should update the questions. - """ - - """ - @TODO: - Create an endpoint to DELETE question using a question ID. - - TEST: When you click the trash icon next to a question, the question will be removed. - This removal will persist in the database and when you refresh the page. - """ - - """ - @TODO: - Create an endpoint to POST a new question, - which will require the question and answer text, - category, and difficulty score. - - TEST: When you submit a question on the "Add" tab, - the form will clear and the question will appear at the end of the last page - of the questions list in the "List" tab. - """ - - """ - @TODO: - 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. - - TEST: Search by any phrase. The questions list will update to include - only question that include that string within their question. - Try using the word "title" to start. - """ - - """ - @TODO: - Create a GET endpoint to get questions based on category. - - TEST: In the "List" tab / main screen, clicking on one of the - categories in the left column will cause only questions of that - category to be shown. - """ - - """ - @TODO: - 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. - - TEST: In the "Play" tab, after a user selects "All" or a category, - one question at a time is displayed, the user is allowed to answer - and shown whether they were correct or not. - """ - - """ - @TODO: - Create error handlers for all expected errors - including 404 and 422. - """ + CORS(app) + + @app.after_request + def after_request(response): + response.headers.add( + "Access-Control-Allow-Headers", "Content-Type, Authorization" + ) + response.headers.add( + "Access-Control-Allow-Methods", "GET, POST, PATCH, DELETE, OPTIONS" + ) + return response + + @app.route("/categories", methods=["GET"]) + def get_categories(): + categories = Category.query.all() + if not categories: + abort(404) + return jsonify( + { + "success": True, + "categories": {category.id: category.type for category in categories}, + } + ) + + @app.route("/questions", methods=["GET"]) + def get_questions(): + questions = Question.query.all() + categories = Category.query.all() + current_questions = paginate_questions(request, questions) + if not current_questions: + abort(404) + + return jsonify( + { + "success": True, + "questions": current_questions, + "total_questions": len(questions), + } + ) + + @app.route("/questions/", methods=["DELETE"]) + def delete_question(question_id): + question = Question.query.get(question_id) + if not question: + abort(404) + try: + question.delete() + db.session.commit() + return jsonify({"success": True, "deleted": question_id}) + except: + db.session.rollback() + abort(422) + finally: + db.session.close() + + @app.route("/questions", methods=["POST"]) + def add_question(): + data = request.get_json() + question_text = data.get("question") + answer = data.get("answer") + category = data.get("category") + difficulty = data.get("difficulty") + + if not (question_text and answer and category and difficulty): + abort(400) + + try: + new_question = Question( + question=question_text, + answer=answer, + category=category, + difficulty=difficulty, + ) + new_question.insert() + return jsonify({"success": True}) + except: + abort(422) + + @app.route("/questions/search", methods=["POST"]) + def search_questions(): + data = request.get_json() + search_term = data.get("searchTerm", "") + + questions = Question.query.filter( + Question.question.ilike(f"%{search_term}%") + ).all() + if not questions: + abort(404) + + return jsonify( + { + "success": True, + "questions": [question.format() for question in questions], + "total_questions": len(questions), + } + ) + + @app.route("/categories//questions", methods=["GET"]) + def get_questions_by_category(category_id): + questions = Question.query.filter_by(category=str(category_id)).all() + if not questions: + abort(404) + + return jsonify( + { + "success": True, + "questions": [question.format() for question in questions], + "total_questions": len(questions), + "current_category": category_id, + } + ) + + @app.route("/quizzes", methods=["POST"]) + def play_quiz(): + data = request.get_json() + previous_questions = data.get("previous_questions", []) + quiz_category = data.get("quiz_category", {}) + + if quiz_category.get("id"): + questions = ( + Question.query.filter_by(category=str(quiz_category["id"])) + .filter(Question.id.notin_(previous_questions)) + .all() + ) + else: + questions = Question.query.filter( + Question.id.notin_(previous_questions) + ).all() + + if not questions: + return jsonify({"success": True, "question": None}) + + next_question = random.choice(questions).format() + return jsonify({"success": True, "question": next_question}) + + @app.errorhandler(404) + def not_found(error): + return ( + jsonify({"success": False, "error": 404, "message": "Resource not found"}), + 404, + ) + + @app.errorhandler(422) + def unprocessable(error): + return ( + jsonify( + {"success": False, "error": 422, "message": "Unprocessable entity"} + ), + 422, + ) + + @app.errorhandler(400) + def bad_request(error): + return jsonify({"success": False, "error": 400, "message": "Bad request"}), 400 return app - diff --git a/backend/models.py b/backend/models.py index 7647a6fbf..65cb70da3 100644 --- a/backend/models.py +++ b/backend/models.py @@ -1,10 +1,13 @@ from sqlalchemy import Column, String, Integer from flask_sqlalchemy import SQLAlchemy -database_name = 'trivia' -database_user = 'postgres' -database_password = 'password' -database_host = 'localhost:5432' -database_path = f'postgresql://{database_user}:{database_password}@{database_host}/{database_name}' + +database_name = "trivia" +database_user = "gurpreetatwal" +database_password = "abc" +database_host = "localhost:5432" +database_path = ( + f"postgresql://{database_user}:{database_password}@{database_host}/{database_name}" +) db = SQLAlchemy() @@ -12,16 +15,21 @@ setup_db(app) binds a flask application and a SQLAlchemy service """ + + def setup_db(app, database_path=database_path): - app.config['SQLALCHEMY_DATABASE_URI'] = database_path - app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False + app.config["SQLALCHEMY_DATABASE_URI"] = database_path + app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False db.init_app(app) + """ Question """ + + class Question(db.Model): - __tablename__ = 'questions' + __tablename__ = "questions" id = Column(Integer, primary_key=True) question = Column(String, nullable=False) @@ -48,18 +56,21 @@ def delete(self): def format(self): return { - 'id': self.id, - 'question': self.question, - 'answer': self.answer, - 'category': self.category, - 'difficulty': self.difficulty + "id": self.id, + "question": self.question, + "answer": self.answer, + "category": self.category, + "difficulty": self.difficulty, } + """ Category """ + + class Category(db.Model): - __tablename__ = 'categories' + __tablename__ = "categories" id = Column(Integer, primary_key=True) type = Column(String, nullable=False) @@ -68,7 +79,4 @@ def __init__(self, type): self.type = type def format(self): - return { - 'id': self.id, - 'type': self.type - } + return {"id": self.id, "type": self.type} diff --git a/backend/test_flaskr.py b/backend/test_flaskr.py index 20a355b90..d965dab78 100644 --- a/backend/test_flaskr.py +++ b/backend/test_flaskr.py @@ -1,8 +1,10 @@ +from sqlalchemy import inspect, text import os import unittest - +import json from flaskr import create_app from models import db, Question, Category +import subprocess class TriviaTestCase(unittest.TestCase): @@ -11,33 +13,225 @@ class TriviaTestCase(unittest.TestCase): def setUp(self): """Define test variables and initialize app.""" self.database_name = "trivia_test" - self.database_user = "postgres" - self.database_password = "password" + self.database_user = "gurpreetatwal" + self.database_password = "abc" self.database_host = "localhost:5432" self.database_path = f"postgresql://{self.database_user}:{self.database_password}@{self.database_host}/{self.database_name}" + # Path to the trivia.psql file + base_dir = os.path.dirname( + os.path.abspath(__file__) + ) # Directory of this script + psql_file_path = os.path.join(base_dir, "trivia.psql") + + # load test db with data + try: + # Load the initial test data + with open(psql_file_path, "r") as psql_file: + subprocess.run( + ["psql", self.database_name], + stdin=psql_file, + check=True, + ) + except subprocess.CalledProcessError as e: + print(f"Error setting up the test database: {e}") + raise + # Create app with the test configuration - self.app = create_app({ - "SQLALCHEMY_DATABASE_URI": self.database_path, - "SQLALCHEMY_TRACK_MODIFICATIONS": False, - "TESTING": True - }) + self.app = create_app( + { + "SQLALCHEMY_DATABASE_URI": self.database_path, + "SQLALCHEMY_TRACK_MODIFICATIONS": False, + "TESTING": True, + } + ) self.client = self.app.test_client() # Bind the app to the current context and create all tables with self.app.app_context(): db.create_all() + from sqlalchemy import inspect, text + def tearDown(self): - """Executed after each test""" + """ + Executed after each test. + Drop all relations. + """ + with self.app.app_context(): + db.session.remove() # Clear the session + + # Use raw SQL to drop tables + with db.engine.connect() as connection: + transaction = connection.begin() # Begin a transaction + try: + # Reflect the database and drop each table with CASCADE + inspector = inspect(db.engine) + for table_name in inspector.get_table_names(): + print(f"Dropping table: {table_name}") + connection.execute( + text(f"DROP TABLE IF EXISTS {table_name} CASCADE") + ) + + transaction.commit() # Commit the transaction + print("All tables dropped successfully.") + except Exception as e: + transaction.rollback() # Rollback in case of an error + print(f"Error dropping tables: {e}") + + def test_get_categories_success(self): + """Test retrieving all categories.""" + response = self.client.get("/categories") + data = json.loads(response.data) + print(f"The response JSON is: {data}") + self.assertEqual(response.status_code, 200) + self.assertTrue(data["success"]) + self.assertTrue(data["categories"]) + + def test_get_categories_failure(self): + """Test 404 error when no categories exist.""" + with self.app.app_context(): + db.session.query(Category).delete() + db.session.commit() + + response = self.client.get("/categories") + data = json.loads(response.data) + print(f"The response JSON is: {data}") + print(f"The status code is: {response.status_code}") + self.assertEqual(response.status_code, 404) + self.assertFalse(data["success"]) + + def test_get_questions_success(self): + """Test retrieving paginated questions.""" + response = self.client.get("/questions?page=1") + data = json.loads(response.data) + print(f"The response JSON is: {data}") + self.assertEqual(response.status_code, 200) + self.assertTrue(data["success"]) + self.assertTrue(data["questions"]) + self.assertTrue(data["total_questions"]) + + def test_get_questions_failure(self): + """Test 404 error when no questions are available.""" with self.app.app_context(): - db.session.remove() - db.drop_all() + db.session.query(Question).delete() + db.session.commit() + + response = self.client.get("/questions") + data = json.loads(response.data) + print(f"The response JSON is: {data}") + self.assertEqual(response.status_code, 404) + self.assertFalse(data["success"]) + + def test_delete_question_success(self): + """Test deleting an existing question.""" + with self.app.app_context(): + question = db.session.query(Question).first() + question_id = question.id if question else None + + if question_id: + response = self.client.delete(f"/questions/{question_id}") + data = json.loads(response.data) + print(f"The response JSON is: {data}") + self.assertEqual(response.status_code, 200) + self.assertTrue(data["success"]) + self.assertEqual(data["deleted"], question_id) + + def test_delete_question_failure(self): + """Test 404 error when deleting a non-existent question.""" + response = self.client.delete("/questions/9999") + data = json.loads(response.data) + print(f"The response JSON is: {data}") + self.assertEqual(response.status_code, 404) + self.assertFalse(data["success"]) + + def test_add_question_success(self): + """Test adding a new question.""" + new_question = { + "question": "What is the capital of France?", + "answer": "Paris", + "category": "1", + "difficulty": 2, + } + response = self.client.post("/questions", json=new_question) + data = json.loads(response.data) + print(f"The response JSON is: {data}") + self.assertEqual(response.status_code, 200) + self.assertTrue(data["success"]) + + def test_add_question_failure(self): + """Test 400 error when adding a question with incomplete data.""" + incomplete_question = { + "question": "What is the capital of France?", + "answer": "Paris", + } + response = self.client.post("/questions", json=incomplete_question) + data = json.loads(response.data) + print(f"The response JSON is: {data}") + self.assertEqual(response.status_code, 400) + self.assertFalse(data["success"]) + + def test_search_questions_success(self): + """Test searching for questions.""" + search_data = {"searchTerm": "autobiography"} + response = self.client.post("/questions/search", json=search_data) + data = json.loads(response.data) + print(f"The response JSON is: {data}") + self.assertEqual(response.status_code, 200) + self.assertTrue(data["success"]) + self.assertTrue(data["questions"]) + + def test_search_questions_failure(self): + """Test 404 error when searching for a non-existent term.""" + search_data = {"searchTerm": "xyz"} + response = self.client.post("/questions/search", json=search_data) + data = json.loads(response.data) + print(f"The response JSON is: {data}") + self.assertEqual(response.status_code, 404) + self.assertFalse(data["success"]) + + def test_get_questions_by_category_success(self): + """Test retrieving questions by category.""" + response = self.client.get("/categories/1/questions") + data = json.loads(response.data) + print(f"The response JSON is: {data}") + self.assertEqual(response.status_code, 200) + self.assertTrue(data["success"]) + self.assertTrue(data["questions"]) + + def test_get_questions_by_category_failure(self): + """Test 404 error when category has no questions.""" + response = self.client.get("/categories/999/questions") + data = json.loads(response.data) + print(f"The response JSON is: {data}") + self.assertEqual(response.status_code, 404) + self.assertFalse(data["success"]) + + def test_play_quiz_success(self): + """Test playing quiz with available questions.""" + quiz_data = { + "previous_questions": [], + "quiz_category": {"id": "1"}, + } + response = self.client.post("/quizzes", json=quiz_data) + data = json.loads(response.data) + print(f"The response JSON is: {data}") + self.assertEqual(response.status_code, 200) + self.assertTrue(data["success"]) + self.assertIsNotNone(data["question"]) - """ - TODO - Write at least one test for each test for successful operation and for expected errors. - """ + def test_play_quiz_failure(self): + """Test playing quiz with no available questions.""" + quiz_data = { + "previous_questions": [1], + "quiz_category": {"id": "999"}, + } + response = self.client.post("/quizzes", json=quiz_data) + data = json.loads(response.data) + print(f"The response JSON is: {data}") + self.assertEqual(response.status_code, 200) + self.assertTrue(data["success"]) + self.assertIsNone(data["question"]) # Make the tests conveniently executable diff --git a/backend/trivia.psql b/backend/trivia.psql index 1549d3d63..a2f90969a 100644 --- a/backend/trivia.psql +++ b/backend/trivia.psql @@ -21,7 +21,7 @@ SET default_tablespace = ''; SET default_with_oids = false; -- --- Name: categories; Type: TABLE; Schema: public; Owner: student +-- Name: categories; Type: TABLE; Schema: public; Owner: gurpreetatwal -- CREATE TABLE public.categories ( @@ -30,10 +30,10 @@ CREATE TABLE public.categories ( ); -ALTER TABLE public.categories OWNER TO student; +ALTER TABLE public.categories OWNER TO gurpreetatwal; -- --- Name: categories_id_seq; Type: SEQUENCE; Schema: public; Owner: student +-- Name: categories_id_seq; Type: SEQUENCE; Schema: public; Owner: gurpreetatwal -- CREATE SEQUENCE public.categories_id_seq @@ -45,17 +45,17 @@ CREATE SEQUENCE public.categories_id_seq CACHE 1; -ALTER TABLE public.categories_id_seq OWNER TO student; +ALTER TABLE public.categories_id_seq OWNER TO gurpreetatwal; -- --- Name: categories_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: student +-- Name: categories_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: gurpreetatwal -- ALTER SEQUENCE public.categories_id_seq OWNED BY public.categories.id; -- --- Name: questions; Type: TABLE; Schema: public; Owner: student +-- Name: questions; Type: TABLE; Schema: public; Owner: gurpreetatwal -- CREATE TABLE public.questions ( @@ -67,10 +67,10 @@ CREATE TABLE public.questions ( ); -ALTER TABLE public.questions OWNER TO student; +ALTER TABLE public.questions OWNER TO gurpreetatwal; -- --- Name: questions_id_seq; Type: SEQUENCE; Schema: public; Owner: student +-- Name: questions_id_seq; Type: SEQUENCE; Schema: public; Owner: gurpreetatwal -- CREATE SEQUENCE public.questions_id_seq @@ -82,31 +82,31 @@ CREATE SEQUENCE public.questions_id_seq CACHE 1; -ALTER TABLE public.questions_id_seq OWNER TO student; +ALTER TABLE public.questions_id_seq OWNER TO gurpreetatwal; -- --- Name: questions_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: student +-- Name: questions_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: gurpreetatwal -- ALTER SEQUENCE public.questions_id_seq OWNED BY public.questions.id; -- --- Name: categories id; Type: DEFAULT; Schema: public; Owner: student +-- Name: categories id; Type: DEFAULT; Schema: public; Owner: gurpreetatwal -- ALTER TABLE ONLY public.categories ALTER COLUMN id SET DEFAULT nextval('public.categories_id_seq'::regclass); -- --- Name: questions id; Type: DEFAULT; Schema: public; Owner: student +-- Name: questions id; Type: DEFAULT; Schema: public; Owner: gurpreetatwal -- ALTER TABLE ONLY public.questions ALTER COLUMN id SET DEFAULT nextval('public.questions_id_seq'::regclass); -- --- Data for Name: categories; Type: TABLE DATA; Schema: public; Owner: student +-- Data for Name: categories; Type: TABLE DATA; Schema: public; Owner: gurpreetatwal -- COPY public.categories (id, type) FROM stdin; @@ -120,7 +120,7 @@ COPY public.categories (id, type) FROM stdin; -- --- Data for Name: questions; Type: TABLE DATA; Schema: public; Owner: student +-- Data for Name: questions; Type: TABLE DATA; Schema: public; Owner: gurpreetatwal -- COPY public.questions (id, question, answer, difficulty, category) FROM stdin; @@ -147,21 +147,21 @@ COPY public.questions (id, question, answer, difficulty, category) FROM stdin; -- --- Name: categories_id_seq; Type: SEQUENCE SET; Schema: public; Owner: student +-- Name: categories_id_seq; Type: SEQUENCE SET; Schema: public; Owner: gurpreetatwal -- SELECT pg_catalog.setval('public.categories_id_seq', 6, true); -- --- Name: questions_id_seq; Type: SEQUENCE SET; Schema: public; Owner: student +-- Name: questions_id_seq; Type: SEQUENCE SET; Schema: public; Owner: gurpreetatwal -- SELECT pg_catalog.setval('public.questions_id_seq', 23, true); -- --- Name: categories categories_pkey; Type: CONSTRAINT; Schema: public; Owner: student +-- Name: categories categories_pkey; Type: CONSTRAINT; Schema: public; Owner: gurpreetatwal -- ALTER TABLE ONLY public.categories @@ -169,7 +169,7 @@ ALTER TABLE ONLY public.categories -- --- Name: questions questions_pkey; Type: CONSTRAINT; Schema: public; Owner: student +-- Name: questions questions_pkey; Type: CONSTRAINT; Schema: public; Owner: gurpreetatwal -- ALTER TABLE ONLY public.questions @@ -177,7 +177,7 @@ ALTER TABLE ONLY public.questions -- --- Name: questions category; Type: FK CONSTRAINT; Schema: public; Owner: student +-- Name: questions category; Type: FK CONSTRAINT; Schema: public; Owner: gurpreetatwal -- ALTER TABLE ONLY public.questions diff --git a/notes.txt b/notes.txt new file mode 100644 index 000000000..116542218 --- /dev/null +++ b/notes.txt @@ -0,0 +1,30 @@ +####################################################### + +start and stop the postgre server +pg_ctl -D /opt/homebrew/var/postgres start +pg_ctl -D /opt/homebrew/var/postgres stop + +####################################################### + +Create and populate the db + +createdb trivia +psql trivia < trivia.psql (from the backend folder) + +Note: for test file, db name is "trivia_test" + +createdb trivia_test +psql trivia_test < trivia.psql (from the backend folder) + +####################################################### + +Run the commands fron backend folder: + +export FLASK_APP=flaskr +export FLASK_ENV=development +or +export FLASK_DEBUG=1 (one of them works - the debug = 1) +flask run --port=5001 + +####################################################### +