From e12e945e173a33b7c19dfafd2952ce9ec1d74112 Mon Sep 17 00:00:00 2001 From: Reid Maute Date: Fri, 15 Oct 2021 11:01:37 -0700 Subject: [PATCH 01/13] First part done --- app/__init__.py | 3 +++ app/routes.py | 28 +++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/app/__init__.py b/app/__init__.py index 70b4cabfe..ab9eee40e 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -4,4 +4,7 @@ def create_app(test_config=None): app = Flask(__name__) + from .routes import planets_bp + app.register_blueprint(planets_bp) + return app diff --git a/app/routes.py b/app/routes.py index 8e9dfe684..34dc38af7 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,2 +1,28 @@ -from flask import Blueprint +from flask import Blueprint, jsonify +class Planet: + def __init__(self, id, name, description, color): + self.id = id + self.name = name + self.description = description + self.color = color + +planets = [ + Planet(1, "Venus", "A planet that spins in the opposite direction", "orange"), + Planet(2, "Mars", "Dusty, Cold, Desered", "red"), + Planet(3, "Mercury", "The smallest planet", "many colors"), +] + +planets_bp = Blueprint("planets", __name__, url_prefix="/planets") + +@planets_bp.route("", methods=["GET"]) +def handle_planets(): + planets_response = [] + for planet in planets: + planets_response.append({ + "id": planet.id, + "name": planet.name, + "description": planet.description, + "color": planet.color + }) + return jsonify(planets_response) \ No newline at end of file From 4fad73f936e4282a511c783a890eb69cc90b240a Mon Sep 17 00:00:00 2001 From: Reid Maute Date: Fri, 15 Oct 2021 11:07:24 -0700 Subject: [PATCH 02/13] second part done- able to get single planet now --- app/routes.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/app/routes.py b/app/routes.py index 34dc38af7..759c80e1d 100644 --- a/app/routes.py +++ b/app/routes.py @@ -25,4 +25,17 @@ def handle_planets(): "description": planet.description, "color": planet.color }) - return jsonify(planets_response) \ No newline at end of file + return jsonify(planets_response) + + +@planets_bp.route("/", methods=["GET"]) +def handle_planet(planet_id): + planet_id = int(planet_id) + for planet in planets: + if planet.id == planet_id: + return { + "id": planet.id, + "name": planet.name, + "description": planet.description, + "color": planet.color + } \ No newline at end of file From 824ca4aec0c8204f977e8eb3475db6d3e159e431 Mon Sep 17 00:00:00 2001 From: Asha Paul Date: Fri, 15 Oct 2021 21:38:25 -0400 Subject: [PATCH 03/13] edit on line 12 in routes.py --- app/routes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/routes.py b/app/routes.py index 759c80e1d..14a98b04b 100644 --- a/app/routes.py +++ b/app/routes.py @@ -9,7 +9,7 @@ def __init__(self, id, name, description, color): planets = [ Planet(1, "Venus", "A planet that spins in the opposite direction", "orange"), - Planet(2, "Mars", "Dusty, Cold, Desered", "red"), + Planet(2, "Mars", "Dusty, Cold, Deserted", "red"), Planet(3, "Mercury", "The smallest planet", "many colors"), ] From f4a89948717fe529e75dfc1ef9ef474cf2bc1b31 Mon Sep 17 00:00:00 2001 From: Reid Maute Date: Mon, 18 Oct 2021 14:05:07 -0700 Subject: [PATCH 04/13] Added call to external API, need to format JSON response to only print planet names --- app/routes.py | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/app/routes.py b/app/routes.py index 759c80e1d..c062a0971 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,4 +1,9 @@ from flask import Blueprint, jsonify +import requests +import time + +path = "https://api.le-systeme-solaire.net/rest.php/bodies" + class Planet: def __init__(self, id, name, description, color): @@ -38,4 +43,25 @@ def handle_planet(planet_id): "name": planet.name, "description": planet.description, "color": planet.color - } \ No newline at end of file + } + +def get_bodies(): + query_params = { + "filter[]": "isPlanet,neq,false" + } + + response = requests.get(path, params=query_params) + return response.json() + + +print(get_bodies()) + + +""" +Hey API +Give me everything where isPlanet is True + + +We want that to be returned and displayed + +""" \ No newline at end of file From c5bbfee15d4f30e2d1a2b7fa9366b7310ced2819 Mon Sep 17 00:00:00 2001 From: Asha Paul Date: Mon, 18 Oct 2021 17:51:38 -0400 Subject: [PATCH 05/13] add blueprint object to point to /bodies --- app/routes.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/app/routes.py b/app/routes.py index 874068d2e..f74aaae35 100644 --- a/app/routes.py +++ b/app/routes.py @@ -47,21 +47,21 @@ def handle_planet(planet_id): def get_bodies(): query_params = { - "filter[]": "isPlanet,neq,false" + "filter[]": "isPlanet,neq,false", + "data": "englishName" } response = requests.get(path, params=query_params) return response.json() -print(get_bodies()) +# print(get_bodies()) - -""" -Hey API -Give me everything where isPlanet is True - - -We want that to be returned and displayed - -""" \ No newline at end of file +@planets_bp.route("/bodies", methods=["GET"]) +def handle_all_planets(): + all_planets = get_bodies() + planet_names = [] + for planet in all_planets["bodies"]: + print(planet["englishName"]) + planet_names.append(planet["englishName"]) + return jsonify(planet_names) \ No newline at end of file From 3704d8946b146f35852d596d56c8500dcd3f0212 Mon Sep 17 00:00:00 2001 From: Reid Maute Date: Fri, 22 Oct 2021 12:05:52 -0700 Subject: [PATCH 06/13] changes --- app/routes.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/app/routes.py b/app/routes.py index 874068d2e..0338b7b17 100644 --- a/app/routes.py +++ b/app/routes.py @@ -55,13 +55,3 @@ def get_bodies(): print(get_bodies()) - - -""" -Hey API -Give me everything where isPlanet is True - - -We want that to be returned and displayed - -""" \ No newline at end of file From 4f8ae8866b3a838b8521afc381acbcfafa266498 Mon Sep 17 00:00:00 2001 From: Asha Paul Date: Mon, 25 Oct 2021 17:09:09 -0400 Subject: [PATCH 07/13] get all planets and get one planet --- app/routes.py | 54 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/app/routes.py b/app/routes.py index 8a594b7f9..b805ef9f4 100644 --- a/app/routes.py +++ b/app/routes.py @@ -2,23 +2,53 @@ from app.models.planet import Planet from flask import Blueprint, jsonify, make_response, request -path = "https://api.le-systeme-solaire.net/rest.php/bodies" +# path = "https://api.le-systeme-solaire.net/rest.php/bodies" planets_bp = Blueprint("planets", __name__, url_prefix="/planets") -@planets_bp.route("", methods=["POST"]) + +@planets_bp.route("", methods=["GET", "POST"]) def handle_planets(): - request_body = request.get_json() - new_planet = Planet(name=request_body["name"], - description=request_body["description"], - color=request_body["color"] - ) - - db.session.add(new_planet) - db.session.commit() + if request.method == "GET": + planets = Planet.query.all() + planets_response = [] + for planet in planets: + planets_response.append( + { + "id": planet.id, + "name": planet.name, + "description": planet.description, + "color": planet.color + } + ) + return jsonify(planets_response) + + elif request.method == "POST": + request_body = request.get_json() + new_planet = Planet(name=request_body["name"], + description=request_body["description"], + color=request_body["color"] + ) + + db.session.add(new_planet) + db.session.commit() + + return make_response(f"Planet {new_planet.name} successfully created", 201) + + +@planets_bp.route("/", methods=["GET"]) +def handle_planet(planet_id): + planet = Planet.query.get(planet_id) # we're assigning this query to the variable 'planet' + if planet is None: + return make_response(f"Planet {planet.id} not found", 404) + return { # we're returning a json object using the planet that we found + "id": planet.id, + "name": planet.name, + "description": planet.description, + "color": planet.color +} - return make_response(f"Planet {new_planet.name} successfully created", 201) """ @planets_bp.route("/", methods=["GET"]) @@ -45,4 +75,4 @@ def get_bodies(): print(get_bodies()) -""" \ No newline at end of file +""" From f5d1804ae95e416ed00c92388c719f51fbe2715f Mon Sep 17 00:00:00 2001 From: Reid Maute Date: Mon, 25 Oct 2021 14:30:08 -0700 Subject: [PATCH 08/13] Added the Update and Delete features --- app/routes.py | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/app/routes.py b/app/routes.py index b805ef9f4..6d799bbde 100644 --- a/app/routes.py +++ b/app/routes.py @@ -37,17 +37,38 @@ def handle_planets(): return make_response(f"Planet {new_planet.name} successfully created", 201) -@planets_bp.route("/", methods=["GET"]) +@planets_bp.route("/", methods=["GET", "PUT", "DELETE"]) def handle_planet(planet_id): - planet = Planet.query.get(planet_id) # we're assigning this query to the variable 'planet' + + planet = Planet.query.get(planet_id) + #this is where we tell it which id to grab + if planet is None: - return make_response(f"Planet {planet.id} not found", 404) - return { # we're returning a json object using the planet that we found - "id": planet.id, - "name": planet.name, - "description": planet.description, - "color": planet.color -} + return make_response(f"Planet {planet.id} not found", 404) + + if request.method == "GET": + return { # we're returning a json object using the planet that we found + "id": planet.id, + "name": planet.name, + "description": planet.description, + "color": planet.color + } + elif request.method == "PUT": + request_body = request.get_json() + + planet.name = request_body["name"] + planet.description = request_body["description"] + planet.color = request_body["color"] + + db.session.commit() + + return jsonify(f"Planet #{planet.id} successfully updated"), 200 + + elif request.method == "DELETE": + db.session.delete(planet) + db.session.commit() + return jsonify(f"Planet #{planet.id} successfully deleted"), 200 + """ From 294ec5df61361b6905932ff424c9383243523e7e Mon Sep 17 00:00:00 2001 From: Asha Paul Date: Tue, 26 Oct 2021 13:55:39 -0400 Subject: [PATCH 09/13] modify our endpoint code to filter the results when a name query param is supplied --- app/routes.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/routes.py b/app/routes.py index 6d799bbde..7a3586e57 100644 --- a/app/routes.py +++ b/app/routes.py @@ -11,7 +11,11 @@ @planets_bp.route("", methods=["GET", "POST"]) def handle_planets(): if request.method == "GET": - planets = Planet.query.all() + name = request.args.get("name") + if name: + planets = Planet.query.filter_by(name=name) + else: + planets = Planet.query.all() planets_response = [] for planet in planets: planets_response.append( From f99c8d14819162f639f5db3b91ac7aa467b2268a Mon Sep 17 00:00:00 2001 From: Reid Maute Date: Wed, 27 Oct 2021 11:14:33 -0700 Subject: [PATCH 10/13] set up initial test and .env file --- app/__init__.py | 16 ++++++++++++++-- app/routes.py | 2 +- requirements.txt | 7 +++++++ tests/__init__.py | 0 tests/conftest.py | 21 +++++++++++++++++++++ tests/test_routes.py | 6 ++++++ 6 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 tests/__init__.py create mode 100644 tests/conftest.py create mode 100644 tests/test_routes.py diff --git a/app/__init__.py b/app/__init__.py index a08eaaa5c..b12a63824 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,16 +1,28 @@ from flask import Flask from flask_sqlalchemy import SQLAlchemy from flask_migrate import Migrate +from dotenv import load_dotenv +import os db = SQLAlchemy() migrate = Migrate() +load_dotenv() #need this to point to our .env file which connects to the dbs def create_app(test_config=None): app = Flask(__name__) - app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False - app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql+psycopg2://postgres:postgres@localhost:5432/solar_system_development' + if not test_config: + app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False + app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get( + "SQLALCHEMY_DATABASE_URI") + else: + app.config["TESTING"] = True + app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False + app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get( + "SQLALCHEMY_TEST_DATABASE_URI") + + db.init_app(app) migrate.init_app(app, db) diff --git a/app/routes.py b/app/routes.py index 7a3586e57..bebc3336d 100644 --- a/app/routes.py +++ b/app/routes.py @@ -26,7 +26,7 @@ def handle_planets(): "color": planet.color } ) - return jsonify(planets_response) + return jsonify(planets_response), 200 elif request.method == "POST": request_body = request.get_json() diff --git a/requirements.txt b/requirements.txt index fd90fffa8..6ee946d37 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ alembic==1.5.4 +attrs==21.2.0 autopep8==1.5.5 certifi==2020.12.5 chardet==4.0.0 @@ -7,12 +8,18 @@ Flask==1.1.2 Flask-Migrate==2.6.0 Flask-SQLAlchemy==2.4.4 idna==2.10 +iniconfig==1.1.1 itsdangerous==1.1.0 Jinja2==2.11.3 Mako==1.1.4 MarkupSafe==1.1.1 +packaging==21.0 +pluggy==1.0.0 psycopg2-binary==2.8.6 +py==1.10.0 pycodestyle==2.6.0 +pyparsing==3.0.2 +pytest==6.2.5 python-dateutil==2.8.1 python-dotenv==0.15.0 python-editor==1.0.4 diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 000000000..4716ab8ee --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,21 @@ +import pytest +from app import create_app +from app import db +from app.models.planet import Planet #bc we are making an instance of Book in the 3rd function + + +@pytest.fixture +def app(): + app = create_app({"TESTING": True}) + + with app.app_context(): + db.create_all() + yield app + + with app.app_context(): + db.drop_all() + + +@pytest.fixture +def client(app): + return app.test_client() \ No newline at end of file diff --git a/tests/test_routes.py b/tests/test_routes.py new file mode 100644 index 000000000..ce2210060 --- /dev/null +++ b/tests/test_routes.py @@ -0,0 +1,6 @@ +def test_get_all_planets_with_no_records(client): + response = client.get("/planets") + response_body = response.get_json() + + assert response.status_code == 200 + assert response_body == [] \ No newline at end of file From 604618126b7d948abb837f83bbb8b1bc82c7257f Mon Sep 17 00:00:00 2001 From: Reid Maute Date: Wed, 27 Oct 2021 11:54:22 -0700 Subject: [PATCH 11/13] finished writing all tests --- app/routes.py | 8 +++++--- tests/conftest.py | 11 ++++++++++- tests/test_routes.py | 45 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 59 insertions(+), 5 deletions(-) diff --git a/app/routes.py b/app/routes.py index bebc3336d..9123bfb33 100644 --- a/app/routes.py +++ b/app/routes.py @@ -38,7 +38,9 @@ def handle_planets(): db.session.add(new_planet) db.session.commit() - return make_response(f"Planet {new_planet.name} successfully created", 201) + new_planet_response = {"id" : 1, "name" : "Post", "description" :"Posty", "color" : "Postingggg"} + + return jsonify(new_planet_response), 201 @planets_bp.route("/", methods=["GET", "PUT", "DELETE"]) @@ -48,7 +50,7 @@ def handle_planet(planet_id): #this is where we tell it which id to grab if planet is None: - return make_response(f"Planet {planet.id} not found", 404) + return jsonify(f"Planet {planet_id} not found"), 404 if request.method == "GET": return { # we're returning a json object using the planet that we found @@ -56,7 +58,7 @@ def handle_planet(planet_id): "name": planet.name, "description": planet.description, "color": planet.color - } + }, 200 #testing this elif request.method == "PUT": request_body = request.get_json() diff --git a/tests/conftest.py b/tests/conftest.py index 4716ab8ee..f559343e4 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -18,4 +18,13 @@ def app(): @pytest.fixture def client(app): - return app.test_client() \ No newline at end of file + return app.test_client() + +@pytest.fixture +def three_saved_planets(app): + mars_planet = Planet(name="Mars", description="Hot and dusty", color="red") + earth_planet = Planet(name="Earth", description="Nice", color="blue marble") + saturn_planet = Planet(name="Saturn", description="Has some rings", color="yellow-brown") + + db.session.add_all([mars_planet, earth_planet, saturn_planet]) + db.session.commit() \ No newline at end of file diff --git a/tests/test_routes.py b/tests/test_routes.py index ce2210060..56506a217 100644 --- a/tests/test_routes.py +++ b/tests/test_routes.py @@ -3,4 +3,47 @@ def test_get_all_planets_with_no_records(client): response_body = response.get_json() assert response.status_code == 200 - assert response_body == [] \ No newline at end of file + assert response_body == [] + +def test_get_one_book(client, three_saved_planets): + response = client.get("/planets/1") + response_body = response.get_json() + + assert response.status_code == 200 + assert response_body == { + "id" : 1, + "name" : "Mars", + "description" : "Hot and dusty", + "color" : "red" + } + + +def test_get_one_book_but_is_empty_returns_error(client): + response = client.get("/planets/1") + response_body = response.get_json() + + assert response.status_code == 404 + assert response_body == f"Planet 1 not found" + +def test_get_all_planets(client, three_saved_planets): + planet1 = dict(id=1, name="Mars", description="Hot and dusty", color="red") + planet2 = dict(id=2, name="Earth", description="Nice", color="blue marble") + planet3 = dict(id=3, name="Saturn", description="Has some rings", color="yellow-brown") + + response = client.get("/planets") + response_body = response.get_json() + + assert response.status_code == 200 + assert len(response_body) == 3 + assert planet1 in response_body + assert planet2 in response_body + assert planet3 in response_body + +def test_posts_one_planet_successfully(client): + post_planet = dict(name="Post", description="Posty", color="Postingggg") + + response = client.post("/planets", json={"name" : "Post", "description" :"Posty", "color" : "Postingggg"}) + response_body = response.get_json() + + assert response.status_code == 201 + assert response_body == {"id" : 1, "name" : "Post", "description" :"Posty", "color" : "Postingggg"} From a7fb8c7a1e483c0e834d196a5e3b5904d1341a47 Mon Sep 17 00:00:00 2001 From: Asha Paul Date: Tue, 2 Nov 2021 11:08:53 -0400 Subject: [PATCH 12/13] add Procfile --- Procfile | 1 + requirements.txt | 1 + 2 files changed, 2 insertions(+) create mode 100644 Procfile diff --git a/Procfile b/Procfile new file mode 100644 index 000000000..62e430aca --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +web: gunicorn 'app:create_app()' \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 6ee946d37..09438102a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,6 +7,7 @@ click==7.1.2 Flask==1.1.2 Flask-Migrate==2.6.0 Flask-SQLAlchemy==2.4.4 +gunicorn==20.1.0 idna==2.10 iniconfig==1.1.1 itsdangerous==1.1.0 From 7280bb18c890f64044b3aacb04dd6165752a61b8 Mon Sep 17 00:00:00 2001 From: Asha Paul Date: Tue, 2 Nov 2021 11:47:15 -0400 Subject: [PATCH 13/13] edit new_planet_response for /planets endpoint --- app/routes.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/routes.py b/app/routes.py index 9123bfb33..234473b40 100644 --- a/app/routes.py +++ b/app/routes.py @@ -38,7 +38,12 @@ def handle_planets(): db.session.add(new_planet) db.session.commit() - new_planet_response = {"id" : 1, "name" : "Post", "description" :"Posty", "color" : "Postingggg"} + new_planet_response = { + "id": new_planet.id, + "name": new_planet.name, + "description": new_planet.description, + "color": new_planet.color + } return jsonify(new_planet_response), 201