From ebdc87b5607c0e55e383e6fc78457fb2ae2d090b Mon Sep 17 00:00:00 2001 From: Masha Date: Sat, 22 Oct 2022 16:03:03 -0700 Subject: [PATCH 01/28] Wave 1 --- app/__init__.py | 3 +++ app/routes.py | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 36 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..1e2382c72 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,2 +1,34 @@ -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, "Mercury", "the closest to the Sun", "orange"), + Planet(2, "Venus", "toxic atmosphere and yellowish clouds", "brown"), + Planet(3, "Earth", "ocean planet", "blue"), + Planet(4, "Mars", "small red, cold and dusty planet", "red"), + Planet(5, "Jupiter", "covered in cloudy stripes", "light blue with brown stripes"), + Planet(6, "Saturn", "has seven rings around its body", "beige"), + Planet(7, "Uranus", "made of water", "baby blue"), + Planet(8, "Neptune", "dark and very windy", "sky blue") + ] + +planets_bp = Blueprint("planets", __name__, url_prefix="/planets") + +@planets_bp.route("", methods=["Get"]) +def get_all_planets(): + result = [] + for planet in planets: + result.append({ + "id": planet.id, + "name": planet.name, + "description": planet.description, + "color": planet.color + }) + + return jsonify(result) \ No newline at end of file From 371313185806665d351435dc07266555be7608c2 Mon Sep 17 00:00:00 2001 From: Masha Date: Sat, 22 Oct 2022 16:55:55 -0700 Subject: [PATCH 02/28] Wave 2 --- app/routes.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/app/routes.py b/app/routes.py index 1e2382c72..861586b89 100644 --- a/app/routes.py +++ b/app/routes.py @@ -30,5 +30,26 @@ def get_all_planets(): "description": planet.description, "color": planet.color }) - - return jsonify(result) \ No newline at end of file + + return jsonify(result) + +@planets_bp.route("/", methods=["GET"]) +def get_one_planet(planet_id): + #planet_id = int(planet_id) + try: + planet_id = int(planet_id) + except: + return {"message":f"planet {planet_id} invalid"}, 400 + + for planet in planets: + if planet.id == planet_id: + + return { + "id": planet.id, + "name": planet.name, + "description": planet.description, + "color": planet.color + } + + return {"message":f"planet {planet_id} not found"}, 404 + From 46b4f125e876ea64376bd6ca25f774fe3e5bb665 Mon Sep 17 00:00:00 2001 From: Melley Gebretatios Date: Mon, 24 Oct 2022 14:47:17 -0400 Subject: [PATCH 03/28] Waves 1 and wave_2 done --- app/routes.py | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/app/routes.py b/app/routes.py index 861586b89..bd9fc0144 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,4 +1,4 @@ -from flask import Blueprint, jsonify +from flask import Blueprint, jsonify, abort, make_response class Planet(): def __init__(self, id, name, description, color): @@ -20,6 +20,8 @@ def __init__(self, id, name, description, color): planets_bp = Blueprint("planets", __name__, url_prefix="/planets") + + @planets_bp.route("", methods=["Get"]) def get_all_planets(): result = [] @@ -35,21 +37,23 @@ def get_all_planets(): @planets_bp.route("/", methods=["GET"]) def get_one_planet(planet_id): - #planet_id = int(planet_id) + planet = validate_planet(planet_id) + + return jsonify({ + "id": planet.id, + "name": planet.name, + "description": planet.description, + "color": planet.color + }), 200 + +def validate_planet(planet_id): try: planet_id = int(planet_id) except: - return {"message":f"planet {planet_id} invalid"}, 400 + abort(make_response({"message":f"planet {planet_id} invalid"}, 400)) for planet in planets: if planet.id == planet_id: + return planet - return { - "id": planet.id, - "name": planet.name, - "description": planet.description, - "color": planet.color - } - - return {"message":f"planet {planet_id} not found"}, 404 - + abort(make_response({"message":f"planet {planet_id} not found"}, 404)) \ No newline at end of file From ce5fffd59de5d80fe1076db6e1b31e50d73dd82f Mon Sep 17 00:00:00 2001 From: Melley Gebretatios Date: Fri, 28 Oct 2022 14:55:16 -0400 Subject: [PATCH 04/28] Refactored it but it is still not working. --- app/__init__.py | 16 ++++- app/models/__init__.py | 0 app/models/model.py | 0 app/models/planet.py | 15 +++++ app/routes.py | 146 ++++++++++++++++++++++++----------------- 5 files changed, 117 insertions(+), 60 deletions(-) create mode 100644 app/models/__init__.py create mode 100644 app/models/model.py create mode 100644 app/models/planet.py diff --git a/app/__init__.py b/app/__init__.py index ab9eee40e..141481073 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,10 +1,24 @@ from flask import Flask +from flask_sqlalchemy import SQLAlchemy +from flask_migrate import Migrate +db = SQLAlchemy() +migrate = Migrate() 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' + + # Import models here + from app.models.planet import Planet + + db.init_app(app) + migrate.init_app(app, db) + + # Register Blueprints here from .routes import planets_bp app.register_blueprint(planets_bp) - return app + return app \ No newline at end of file diff --git a/app/models/__init__.py b/app/models/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/app/models/model.py b/app/models/model.py new file mode 100644 index 000000000..e69de29bb diff --git a/app/models/planet.py b/app/models/planet.py new file mode 100644 index 000000000..5e0997afb --- /dev/null +++ b/app/models/planet.py @@ -0,0 +1,15 @@ +from app import db + +class Planet(db.Model): + id = db.Column(db.Integer, primary_key=True, autoincrement=True) + name = db.Column(db.String) + description = db.Column(db.String) + color = db.Column(db.String) + + + # class Planet(): + # def __init__(self, id, name, description, color): + # self.id = id + # self.name = name + # self.description = description + # self.color = color diff --git a/app/routes.py b/app/routes.py index bd9fc0144..73bdbf6f4 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,59 +1,87 @@ -from flask import Blueprint, jsonify, abort, make_response - -class Planet(): - def __init__(self, id, name, description, color): - self.id = id - self.name = name - self.description = description - self.color = color - -planets = [ - Planet(1, "Mercury", "the closest to the Sun", "orange"), - Planet(2, "Venus", "toxic atmosphere and yellowish clouds", "brown"), - Planet(3, "Earth", "ocean planet", "blue"), - Planet(4, "Mars", "small red, cold and dusty planet", "red"), - Planet(5, "Jupiter", "covered in cloudy stripes", "light blue with brown stripes"), - Planet(6, "Saturn", "has seven rings around its body", "beige"), - Planet(7, "Uranus", "made of water", "baby blue"), - Planet(8, "Neptune", "dark and very windy", "sky blue") - ] - -planets_bp = Blueprint("planets", __name__, url_prefix="/planets") - - - -@planets_bp.route("", methods=["Get"]) -def get_all_planets(): - result = [] - for planet in planets: - result.append({ - "id": planet.id, - "name": planet.name, - "description": planet.description, - "color": planet.color - }) - - return jsonify(result) - -@planets_bp.route("/", methods=["GET"]) -def get_one_planet(planet_id): - planet = validate_planet(planet_id) - - return jsonify({ - "id": planet.id, - "name": planet.name, - "description": planet.description, - "color": planet.color - }), 200 - -def validate_planet(planet_id): - try: - planet_id = int(planet_id) - except: - abort(make_response({"message":f"planet {planet_id} invalid"}, 400)) - - for planet in planets: - if planet.id == planet_id: - return planet - - abort(make_response({"message":f"planet {planet_id} not found"}, 404)) \ No newline at end of file +from os import abort +from app import db +from app.models.planet import Planet +from flask import Blueprint, jsonify, abort, make_response, request + + +# planets = [ +# Planet(1, "Mercury", "the closest to the Sun", "orange"), +# Planet(2, "Venus", "toxic atmosphere and yellowish clouds", "brown"), +# Planet(3, "Earth", "ocean planet", "blue"), +# Planet(4, "Mars", "small red, cold and dusty planet", "red"), +# Planet(5, "Jupiter", "covered in cloudy stripes", "light blue with brown stripes"), +# Planet(6, "Saturn", "has seven rings around its body", "beige"), +# Planet(7, "Uranus", "made of water", "baby blue"), +# Planet(8, "Neptune", "dark and very windy", "sky blue") +# ] + + +planets_bp = Blueprint("planets_bp", __name__, url_prefix="/planets") + +@planets_bp.route("", methods=["GET","POST"]) +#def handle_planets(): +def read_all_planets(): + #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) + +@planets_bp.route("", methods=["POST"]) +def create_planet(): + #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 = Blueprint("planets", __name__, url_prefix="/planets") +# @planets_bp.route("", methods=["Get"]) +# def get_all_planets(): +# result = [] +# for planet in planets: +# result.append({ +# "id": planet.id, +# "name": planet.name, +# "description": planet.description, +# "color": planet.color +# }) + +# return jsonify(result) + +# @planets_bp.route("/", methods=["GET"]) +# def get_one_planet(planet_id): +# planet = validate_planet(planet_id) + +# return jsonify({ +# "id": planet.id, +# "name": planet.name, +# "description": planet.description, +# "color": planet.color +# }), 200 + +# def validate_planet(planet_id): +# try: +# planet_id = int(planet_id) +# except: +# abort(make_response({"message":f"planet {planet_id} invalid"}, 400)) + +# for planet in planets: +# if planet.id == planet_id: +# return planet + +# abort(make_response({"message":f"planet {planet_id} not found"}, 404)) \ No newline at end of file From d4ea31553a2ee39733a17d4bf602c59d08435458 Mon Sep 17 00:00:00 2001 From: Melley Gebretatios Date: Sun, 30 Oct 2022 17:45:30 -0400 Subject: [PATCH 05/28] This is the part with the migration --- migrations/README | 1 + migrations/alembic.ini | 45 +++++++++ migrations/env.py | 96 +++++++++++++++++++ migrations/script.py.mako | 24 +++++ .../versions/02f11d17edc5_planet_model.py | 34 +++++++ 5 files changed, 200 insertions(+) create mode 100644 migrations/README create mode 100644 migrations/alembic.ini create mode 100644 migrations/env.py create mode 100644 migrations/script.py.mako create mode 100644 migrations/versions/02f11d17edc5_planet_model.py diff --git a/migrations/README b/migrations/README new file mode 100644 index 000000000..98e4f9c44 --- /dev/null +++ b/migrations/README @@ -0,0 +1 @@ +Generic single-database configuration. \ No newline at end of file diff --git a/migrations/alembic.ini b/migrations/alembic.ini new file mode 100644 index 000000000..f8ed4801f --- /dev/null +++ b/migrations/alembic.ini @@ -0,0 +1,45 @@ +# A generic, single database configuration. + +[alembic] +# template used to generate migration files +# file_template = %%(rev)s_%%(slug)s + +# set to 'true' to run the environment during +# the 'revision' command, regardless of autogenerate +# revision_environment = false + + +# Logging configuration +[loggers] +keys = root,sqlalchemy,alembic + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = WARN +handlers = console +qualname = + +[logger_sqlalchemy] +level = WARN +handlers = +qualname = sqlalchemy.engine + +[logger_alembic] +level = INFO +handlers = +qualname = alembic + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(levelname)-5.5s [%(name)s] %(message)s +datefmt = %H:%M:%S diff --git a/migrations/env.py b/migrations/env.py new file mode 100644 index 000000000..8b3fb3353 --- /dev/null +++ b/migrations/env.py @@ -0,0 +1,96 @@ +from __future__ import with_statement + +import logging +from logging.config import fileConfig + +from sqlalchemy import engine_from_config +from sqlalchemy import pool +from flask import current_app + +from alembic import context + +# this is the Alembic Config object, which provides +# access to the values within the .ini file in use. +config = context.config + +# Interpret the config file for Python logging. +# This line sets up loggers basically. +fileConfig(config.config_file_name) +logger = logging.getLogger('alembic.env') + +# add your model's MetaData object here +# for 'autogenerate' support +# from myapp import mymodel +# target_metadata = mymodel.Base.metadata +config.set_main_option( + 'sqlalchemy.url', + str(current_app.extensions['migrate'].db.engine.url).replace('%', '%%')) +target_metadata = current_app.extensions['migrate'].db.metadata + +# other values from the config, defined by the needs of env.py, +# can be acquired: +# my_important_option = config.get_main_option("my_important_option") +# ... etc. + + +def run_migrations_offline(): + """Run migrations in 'offline' mode. + + This configures the context with just a URL + and not an Engine, though an Engine is acceptable + here as well. By skipping the Engine creation + we don't even need a DBAPI to be available. + + Calls to context.execute() here emit the given string to the + script output. + + """ + url = config.get_main_option("sqlalchemy.url") + context.configure( + url=url, target_metadata=target_metadata, literal_binds=True + ) + + with context.begin_transaction(): + context.run_migrations() + + +def run_migrations_online(): + """Run migrations in 'online' mode. + + In this scenario we need to create an Engine + and associate a connection with the context. + + """ + + # this callback is used to prevent an auto-migration from being generated + # when there are no changes to the schema + # reference: http://alembic.zzzcomputing.com/en/latest/cookbook.html + def process_revision_directives(context, revision, directives): + if getattr(config.cmd_opts, 'autogenerate', False): + script = directives[0] + if script.upgrade_ops.is_empty(): + directives[:] = [] + logger.info('No changes in schema detected.') + + connectable = engine_from_config( + config.get_section(config.config_ini_section), + prefix='sqlalchemy.', + poolclass=pool.NullPool, + ) + + with connectable.connect() as connection: + context.configure( + connection=connection, + target_metadata=target_metadata, + process_revision_directives=process_revision_directives, + **current_app.extensions['migrate'].configure_args + ) + + with context.begin_transaction(): + context.run_migrations() + + +if context.is_offline_mode(): + run_migrations_offline() +else: + run_migrations_online() diff --git a/migrations/script.py.mako b/migrations/script.py.mako new file mode 100644 index 000000000..2c0156303 --- /dev/null +++ b/migrations/script.py.mako @@ -0,0 +1,24 @@ +"""${message} + +Revision ID: ${up_revision} +Revises: ${down_revision | comma,n} +Create Date: ${create_date} + +""" +from alembic import op +import sqlalchemy as sa +${imports if imports else ""} + +# revision identifiers, used by Alembic. +revision = ${repr(up_revision)} +down_revision = ${repr(down_revision)} +branch_labels = ${repr(branch_labels)} +depends_on = ${repr(depends_on)} + + +def upgrade(): + ${upgrades if upgrades else "pass"} + + +def downgrade(): + ${downgrades if downgrades else "pass"} diff --git a/migrations/versions/02f11d17edc5_planet_model.py b/migrations/versions/02f11d17edc5_planet_model.py new file mode 100644 index 000000000..abf0ef352 --- /dev/null +++ b/migrations/versions/02f11d17edc5_planet_model.py @@ -0,0 +1,34 @@ +"""planet model + +Revision ID: 02f11d17edc5 +Revises: +Create Date: 2022-10-30 17:42:31.089244 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '02f11d17edc5' +down_revision = None +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('planet', + sa.Column('id', sa.Integer(), autoincrement=True, nullable=False), + sa.Column('name', sa.String(), nullable=True), + sa.Column('description', sa.String(), nullable=True), + sa.Column('color', sa.String(), nullable=True), + sa.PrimaryKeyConstraint('id') + ) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table('planet') + # ### end Alembic commands ### From 68a434404c7ba63ab6a6c941f364c6142757b4d5 Mon Sep 17 00:00:00 2001 From: Masha Date: Mon, 31 Oct 2022 19:51:11 -0700 Subject: [PATCH 06/28] Fixed a couple of typos --- app/routes.py | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/app/routes.py b/app/routes.py index 73bdbf6f4..cd0fdd0d7 100644 --- a/app/routes.py +++ b/app/routes.py @@ -18,33 +18,33 @@ planets_bp = Blueprint("planets_bp", __name__, url_prefix="/planets") -@planets_bp.route("", methods=["GET","POST"]) -#def handle_planets(): +@planets_bp.route("", methods=["GET"]) +# def handle_planets(): def read_all_planets(): #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) + 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) @planets_bp.route("", methods=["POST"]) def create_planet(): #elif request.method == "POST": - request_body = request.get_json() - new_planet = Planet(name=request_body["name"], - description=request_body["description"], - color=request_body["color"]) + 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() + db.session.add(new_planet) + db.session.commit() - return make_response(f"planet {new_planet.name} successfully created", 201) + return make_response(f"planet {new_planet.name} successfully created", 201) From 74721d13d241d052bb28a5815a64131585dc0476 Mon Sep 17 00:00:00 2001 From: Melley Gebretatios Date: Tue, 1 Nov 2022 13:36:58 -0400 Subject: [PATCH 07/28] Changes from Sunday --- app/routes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/routes.py b/app/routes.py index 73bdbf6f4..16191cec6 100644 --- a/app/routes.py +++ b/app/routes.py @@ -18,7 +18,7 @@ planets_bp = Blueprint("planets_bp", __name__, url_prefix="/planets") -@planets_bp.route("", methods=["GET","POST"]) +@planets_bp.route("", methods=["GET"]) #def handle_planets(): def read_all_planets(): #if request.method == "GET": From 5d78ee6f23abb55bdf2017975c44968078e8b31f Mon Sep 17 00:00:00 2001 From: Masha Date: Tue, 1 Nov 2022 10:50:28 -0700 Subject: [PATCH 08/28] read one planet --- app/routes.py | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/app/routes.py b/app/routes.py index 758074476..90559986b 100644 --- a/app/routes.py +++ b/app/routes.py @@ -19,11 +19,35 @@ planets_bp = Blueprint("planets_bp", __name__, url_prefix="/planets") @planets_bp.route("", methods=["GET"]) -<<<<<<< HEAD -#def handle_planets(): -======= + # def handle_planets(): ->>>>>>> 68a434404c7ba63ab6a6c941f364c6142757b4d5 + +def validate_planet(planet_id): + try: + planet_id = int(planet_id) + except: + abort(make_response({"message":f"planet {planet_id} invalid"}, 400)) + + planet = planet.query.get(planet_id) + + if not planet: + abort(make_response({"message":f"planet {planet_id} not found"}, 404)) + + return planet + +@planets_bp.route("/", methods=["GET"]) +def read_one_planet(planet_id): + planet = validate_planet(planet_id) + return { + "id": planet.id, + "name": planet.name, + "description": planet.description, + "color": planet.color + } + + + + def read_all_planets(): #if request.method == "GET": planets = Planet.query.all() From 55a8b4a81cfc4c815dbe861942a30d3ca3c7c345 Mon Sep 17 00:00:00 2001 From: Masha Date: Tue, 1 Nov 2022 11:02:36 -0700 Subject: [PATCH 09/28] fixed planet into Planet, wave 4 now working --- app/routes.py | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/app/routes.py b/app/routes.py index 90559986b..0ff992e1f 100644 --- a/app/routes.py +++ b/app/routes.py @@ -18,7 +18,7 @@ planets_bp = Blueprint("planets_bp", __name__, url_prefix="/planets") -@planets_bp.route("", methods=["GET"]) + # def handle_planets(): @@ -28,26 +28,14 @@ def validate_planet(planet_id): except: abort(make_response({"message":f"planet {planet_id} invalid"}, 400)) - planet = planet.query.get(planet_id) + planet = Planet.query.get(planet_id) if not planet: abort(make_response({"message":f"planet {planet_id} not found"}, 404)) return planet -@planets_bp.route("/", methods=["GET"]) -def read_one_planet(planet_id): - planet = validate_planet(planet_id) - return { - "id": planet.id, - "name": planet.name, - "description": planet.description, - "color": planet.color - } - - - - +@planets_bp.route("", methods=["GET"]) def read_all_planets(): #if request.method == "GET": planets = Planet.query.all() @@ -74,6 +62,20 @@ def create_planet(): return make_response(f"planet {new_planet.name} successfully created", 201) +@planets_bp.route("/", methods=["GET"]) +def read_one_planet(planet_id): + planet = validate_planet(planet_id) + return { + "id": planet.id, + "name": planet.name, + "description": planet.description, + "color": planet.color + } + + + + + From 22881bb1e39bc97b00874fe0e05e43dc33efee82 Mon Sep 17 00:00:00 2001 From: Melley Gebretatios Date: Tue, 1 Nov 2022 14:36:24 -0400 Subject: [PATCH 10/28] Updated planet --- app/routes.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/routes.py b/app/routes.py index 0ff992e1f..01e3aab16 100644 --- a/app/routes.py +++ b/app/routes.py @@ -73,7 +73,19 @@ def read_one_planet(planet_id): } +@planets_bp.route("/", methods=["PUT"]) +def update_planet(planet_id): + planet = validate_planet(planet_id) + + request_body = request.get_json() + + planet.name = request_body["name"] + planet.description = request_body["description"] + planet.color = request_body["color"] + + db.session.commit() + return make_response(f"Planet #{planet.id} successfully updated") From cae75397e4d196fca02ac17a9b06cc9eb566b64d Mon Sep 17 00:00:00 2001 From: Melley Gebretatios Date: Tue, 1 Nov 2022 14:42:37 -0400 Subject: [PATCH 11/28] Delete planet --- app/routes.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/routes.py b/app/routes.py index 01e3aab16..e09377842 100644 --- a/app/routes.py +++ b/app/routes.py @@ -89,6 +89,14 @@ def update_planet(planet_id): +@planets_bp.route("/", methods=["DELETE"]) +def delete_planet(planet_id): + planet = validate_planet(planet_id) + + db.session.delete(planet) + db.session.commit() + + return make_response(f"Planet #{planet.id} successfully deleted") # planets_bp = Blueprint("planets", __name__, url_prefix="/planets") From 3b550aa8bdbb8f1e3eb8f8d726c18db659d82ca8 Mon Sep 17 00:00:00 2001 From: Melley Gebretatios Date: Wed, 2 Nov 2022 17:19:54 -0400 Subject: [PATCH 12/28] Refactored version. --- app/models/planet.py | 40 ++++++++++++++++++++++++++++------ app/routes.py | 51 +++++++++++++++++++++----------------------- 2 files changed, 58 insertions(+), 33 deletions(-) diff --git a/app/models/planet.py b/app/models/planet.py index 5e0997afb..0579831bb 100644 --- a/app/models/planet.py +++ b/app/models/planet.py @@ -7,9 +7,37 @@ class Planet(db.Model): color = db.Column(db.String) - # class Planet(): - # def __init__(self, id, name, description, color): - # self.id = id - # self.name = name - # self.description = description - # self.color = color +def to_dict(self): + + return { + "name": self.name, + "color": self.color, + "description": self.description, + "id": self.id + } +@classmethod +def from_json(cls, req_body): + return cls( + name= req_body["name"], + color= req_body["color"], + description= req_body["description"] + ) + +def update(self, req_body): + self.name= req_body["name"], + self.color= req_body["color"], + self.description= req_body["description"] + + + + + + + + + # planet_as_dict = {} + # planet_as_dict["id"] = self.id + # planet_as_dict["title"] = self.title + # planet_as_dict["description"] = self.description + + # return planet_as_dict \ No newline at end of file diff --git a/app/routes.py b/app/routes.py index e09377842..c168f7a64 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,4 +1,5 @@ from os import abort +from turtle import title from app import db from app.models.planet import Planet from flask import Blueprint, jsonify, abort, make_response, request @@ -22,41 +23,41 @@ # def handle_planets(): -def validate_planet(planet_id): +def validate_planet(class_obj, planet_id): try: planet_id = int(planet_id) except: - abort(make_response({"message":f"planet {planet_id} invalid"}, 400)) + abort(make_response({"message":f"planet {class_obj} {planet_id} is an invalid planet_id"}, 400)) - planet = Planet.query.get(planet_id) + query_result = class_obj.query.get(planet_id) - if not planet: - abort(make_response({"message":f"planet {planet_id} not found"}, 404)) + if not query_result: + abort(make_response({"message":f"{class_obj} {planet_id} not found"}, 404)) - return planet + return query_result @planets_bp.route("", methods=["GET"]) def read_all_planets(): - #if request.method == "GET": - planets = Planet.query.all() + color_param =request.args.get("color") + name_param = request.args.get("name") + + if color_param: + planets = Planet.query.filter_by(color=color_param) + elif name_param: + planets = Planet.query.filter_by(name= name_param) + else: + 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) + planets_response.append(planet.to_dict()) + + return jsonify(planets_response), 200 @planets_bp.route("", methods=["POST"]) def create_planet(): - #elif request.method == "POST": request_body = request.get_json() - new_planet = Planet(name=request_body["name"], - description=request_body["description"], - color=request_body["color"]) - + new_planet = Planet.from_json(request_body) db.session.add(new_planet) db.session.commit() @@ -65,19 +66,15 @@ def create_planet(): @planets_bp.route("/", methods=["GET"]) def read_one_planet(planet_id): planet = validate_planet(planet_id) - return { - "id": planet.id, - "name": planet.name, - "description": planet.description, - "color": planet.color - } + return jsonify(planet.to_dict()), 200 @planets_bp.route("/", methods=["PUT"]) def update_planet(planet_id): planet = validate_planet(planet_id) - request_body = request.get_json() + + planet.update(request_body) planet.name = request_body["name"] planet.description = request_body["description"] From 685e48b02956482720e7cea44557d72e46c40730 Mon Sep 17 00:00:00 2001 From: Melley Gebretatios Date: Wed, 2 Nov 2022 18:23:14 -0400 Subject: [PATCH 13/28] Code and postman working. --- app/models/planet.py | 38 +++++++++++++++++++------------------- app/routes.py | 4 ++-- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/app/models/planet.py b/app/models/planet.py index 0579831bb..ff7f79eca 100644 --- a/app/models/planet.py +++ b/app/models/planet.py @@ -7,26 +7,26 @@ class Planet(db.Model): color = db.Column(db.String) -def to_dict(self): + def to_dict(self): - return { - "name": self.name, - "color": self.color, - "description": self.description, - "id": self.id - } -@classmethod -def from_json(cls, req_body): - return cls( - name= req_body["name"], - color= req_body["color"], - description= req_body["description"] - ) - -def update(self, req_body): - self.name= req_body["name"], - self.color= req_body["color"], - self.description= req_body["description"] + return { + "name": self.name, + "color": self.color, + "description": self.description, + "id": self.id + } + @classmethod + def from_json(cls, req_body): + return cls( + name= req_body["name"], + color= req_body["color"], + description= req_body["description"] + ) + + def update(self, req_body): + self.name= req_body["name"], + self.color= req_body["color"], + self.description= req_body["description"] diff --git a/app/routes.py b/app/routes.py index c168f7a64..aa2007ff3 100644 --- a/app/routes.py +++ b/app/routes.py @@ -44,7 +44,7 @@ def read_all_planets(): if color_param: planets = Planet.query.filter_by(color=color_param) elif name_param: - planets = Planet.query.filter_by(name= name_param) + planets = Planet.query.filter_by(name=name_param) else: planets = Planet.query.all() planets_response = [] @@ -65,7 +65,7 @@ def create_planet(): @planets_bp.route("/", methods=["GET"]) def read_one_planet(planet_id): - planet = validate_planet(planet_id) + planet = validate_planet(Planet, planet_id) return jsonify(planet.to_dict()), 200 From 5df92b3bceba7c70cd3c49ad9c43555725ccbf04 Mon Sep 17 00:00:00 2001 From: Melley Gebretatios Date: Thu, 3 Nov 2022 15:34:54 -0400 Subject: [PATCH 14/28] First part of testing done. --- app/__init__.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/app/__init__.py b/app/__init__.py index 141481073..8d85f0a6c 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,16 +1,25 @@ 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() 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' - + if not test_config: + app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get( + "SQLALCHEMY_DATABASE_URI") + else: + app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get( + "SQLALCHEMY_TEST_DATABASE_URI") + # Import models here from app.models.planet import Planet From 55193746f498c4cfdc6a470878e92509e344800d Mon Sep 17 00:00:00 2001 From: Masha Date: Thu, 3 Nov 2022 13:45:03 -0700 Subject: [PATCH 15/28] testing if push is working at all with a reame line --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index f9d17f77c..eb646e344 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Solar System API +test line in readme + ## Goal From 048235436929702a75a49aab68e4e3abe9c168fb Mon Sep 17 00:00:00 2001 From: Masha Date: Thu, 3 Nov 2022 14:10:51 -0700 Subject: [PATCH 16/28] I'm not sure but here's our .env file which was ignored before --- .env | 2 ++ .gitignore | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 .env diff --git a/.env b/.env new file mode 100644 index 000000000..b0ee7bf75 --- /dev/null +++ b/.env @@ -0,0 +1,2 @@ +SQLALCHEMY_DATABASE_URI=postgresql+psycopg2://postgres:postgres@localhost:5432/planet +SQLALCHEMY_TEST_DATABASE_URI=postgresql+psycopg2://postgres:postgres@localhost:5432/planet_test \ No newline at end of file diff --git a/.gitignore b/.gitignore index 4e9b18359..15197b612 100644 --- a/.gitignore +++ b/.gitignore @@ -108,7 +108,7 @@ celerybeat.pid *.sage.py # Environments -.env +#.env .venv env/ venv/ From f3c3a7342cf1beeab3373a20326434dce0291f05 Mon Sep 17 00:00:00 2001 From: Masha Date: Thu, 3 Nov 2022 15:05:52 -0700 Subject: [PATCH 17/28] Wave 6 second attempt --- .env | 4 ++-- app/__init__.py | 7 +++++-- tests/__init__.py | 0 tests/conftest.py | 42 ++++++++++++++++++++++++++++++++++++++++++ tests/test_routes.py | 23 +++++++++++++++++++++++ 5 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 tests/__init__.py create mode 100644 tests/conftest.py create mode 100644 tests/test_routes.py diff --git a/.env b/.env index b0ee7bf75..0473e465d 100644 --- a/.env +++ b/.env @@ -1,2 +1,2 @@ -SQLALCHEMY_DATABASE_URI=postgresql+psycopg2://postgres:postgres@localhost:5432/planet -SQLALCHEMY_TEST_DATABASE_URI=postgresql+psycopg2://postgres:postgres@localhost:5432/planet_test \ No newline at end of file +SQLALCHEMY_DATABASE_URI=postgresql+psycopg2://postgres:postgres@localhost:5432/solar_system +SQLALCHEMY_TEST_DATABASE_URI=postgresql+psycopg2://postgres:postgres@localhost:5432/solar_system_test \ No newline at end of file diff --git a/app/__init__.py b/app/__init__.py index 8d85f0a6c..8b678db06 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -12,12 +12,14 @@ def create_app(test_config=None): app = Flask(__name__) - app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False if not test_config: + app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get( "SQLALCHEMY_DATABASE_URI") else: - app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get( + app.config["TESTING"] = True + app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False + app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get( "SQLALCHEMY_TEST_DATABASE_URI") # Import models here @@ -30,4 +32,5 @@ def create_app(test_config=None): from .routes import planets_bp app.register_blueprint(planets_bp) + return app \ No newline at end of file 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..984f936fa --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,42 @@ +import pytest +from app import create_app +from app import db +from flask.signals import request_finished +from app.models.planet import Planet + + +@pytest.fixture +def app(): + app = create_app({"TESTING": True}) + + @request_finished.connect_via(app) + def expire_session(sender, response, **extra): + db.session.remove() + + 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() + +@pytest.fixture +def two_saved_planets(app): + # Arrange + planet_number_one = Planet(name="Planet number one", + description="watr 4evr", + color = "color") + test_planet = Planet(name="Test planet", + description="i luv 2 climb rocks", + color = "color") + + db.session.add_all([planet_number_one, test_planet]) + # Alternatively, we could do + # db.session.add(planet_number_one) + # db.session.add(test_planet) + db.session.commit() \ No newline at end of file diff --git a/tests/test_routes.py b/tests/test_routes.py new file mode 100644 index 000000000..9039ec8f2 --- /dev/null +++ b/tests/test_routes.py @@ -0,0 +1,23 @@ +def test_get_all_planets_with_no_records(client): + # Act + response = client.get("/planets") + response_body = response.get_json() + + # Assert + assert response.status_code == 200 + assert response_body == [] + +def test_get_one_planet(client, two_saved_planets): + # Act + response = client.get("/planets/1") + response_body = response.get_json() + + # Assert + assert response.status_code == 200 + assert response_body == { + "id": 1, + "name": "Planet number one", + "description": "watr 4evr", + "color": "color" + } + From 71dacfd72ec5e779a6d019baff9e0cfface06d7e Mon Sep 17 00:00:00 2001 From: Melley Gebretatios Date: Thu, 3 Nov 2022 19:00:21 -0400 Subject: [PATCH 18/28] I have added new content in routes and test. --- app/routes.py | 4 ++-- tests/test_routes.py | 13 +++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/app/routes.py b/app/routes.py index aa2007ff3..542dcd1ed 100644 --- a/app/routes.py +++ b/app/routes.py @@ -60,8 +60,8 @@ def create_planet(): new_planet = Planet.from_json(request_body) db.session.add(new_planet) db.session.commit() - - return make_response(f"planet {new_planet.name} successfully created", 201) +# I have changed this retun statement and run the test. My terminal is acting up. Plaease try to run the test. + return make_response(jsonify(f"planet {new_planet.name} successfully created", 201)) @planets_bp.route("/", methods=["GET"]) def read_one_planet(planet_id): diff --git a/tests/test_routes.py b/tests/test_routes.py index 9039ec8f2..253797e2b 100644 --- a/tests/test_routes.py +++ b/tests/test_routes.py @@ -20,4 +20,17 @@ def test_get_one_planet(client, two_saved_planets): "description": "watr 4evr", "color": "color" } +# I have added this create function +def test_create_one_planet(client): + # Act + response = client.post("/planets", json={ + "name": "MelMash Planet", + "description": "The Best!", + "color": "Green" + }) + response_body = response.get_json() + # Assert + assert response.status_code == 201 + assert response_body == "Book New Book successfully created" + From b1b5c13a692c1f1650eb9082c83894462fa23c2a Mon Sep 17 00:00:00 2001 From: Masha Date: Thu, 3 Nov 2022 20:19:20 -0700 Subject: [PATCH 19/28] wave 6 last test not working --- app/routes.py | 3 +++ tests/conftest.py | 21 +++++++++++-------- tests/test_routes.py | 49 ++++++++++++++++++++++++++++++++------------ 3 files changed, 51 insertions(+), 22 deletions(-) diff --git a/app/routes.py b/app/routes.py index 542dcd1ed..0a0bc7070 100644 --- a/app/routes.py +++ b/app/routes.py @@ -68,6 +68,9 @@ def read_one_planet(planet_id): planet = validate_planet(Planet, planet_id) return jsonify(planet.to_dict()), 200 +# We should also make this change to jsonify our response body +# in the PUT /books/ and DELETE /books/ routes. +# This adds predictability to our RESTful routes. @planets_bp.route("/", methods=["PUT"]) def update_planet(planet_id): diff --git a/tests/conftest.py b/tests/conftest.py index 984f936fa..7391a6920 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,6 +1,5 @@ import pytest -from app import create_app -from app import db +from app import create_app, db from flask.signals import request_finished from app.models.planet import Planet @@ -26,17 +25,21 @@ def client(app): return app.test_client() @pytest.fixture -def two_saved_planets(app): +def one_planet(app): # Arrange - planet_number_one = Planet(name="Planet number one", + test_planet = Planet(name="Planet number one", description="watr 4evr", color = "color") - test_planet = Planet(name="Test planet", - description="i luv 2 climb rocks", - color = "color") - db.session.add_all([planet_number_one, test_planet]) + # test_planet = Planet(name="Test planet", + # description="i luv 2 climb rocks", + # color = "color") + + db.session.add(test_planet) # Alternatively, we could do # db.session.add(planet_number_one) # db.session.add(test_planet) - db.session.commit() \ No newline at end of file + db.session.commit() + db.session.refresh(test_planet, ["id"]) + + return test_planet \ No newline at end of file diff --git a/tests/test_routes.py b/tests/test_routes.py index 253797e2b..c720fa9f7 100644 --- a/tests/test_routes.py +++ b/tests/test_routes.py @@ -1,3 +1,5 @@ +from app.models.planet import Planet + def test_get_all_planets_with_no_records(client): # Act response = client.get("/planets") @@ -7,9 +9,9 @@ def test_get_all_planets_with_no_records(client): assert response.status_code == 200 assert response_body == [] -def test_get_one_planet(client, two_saved_planets): +def test_get_one_planet(client, one_planet): # Act - response = client.get("/planets/1") + response = client.get(f"/planets/{one_planet.id}") response_body = response.get_json() # Assert @@ -20,17 +22,38 @@ def test_get_one_planet(client, two_saved_planets): "description": "watr 4evr", "color": "color" } -# I have added this create function -def test_create_one_planet(client): - # Act - response = client.post("/planets", json={ - "name": "MelMash Planet", - "description": "The Best!", - "color": "Green" - }) - response_body = response.get_json() - # Assert + +def test_create_planet_can_create_planet_in_empty_db(client): + #arrange + EXPECTED_PLANET = { + "name": "Created Planet", + "description": "New watr 4evr", + "color": "New color" + } + + EXPECTED_ID = 1 + + #act + response = client.post("/planets", json = EXPECTED_PLANET) + response_body = response.get_data(as_text=True) + + #actual_planet = Planet.query.get(EXPECTED_ID) + assert response.status_code == 201 - assert response_body == "Book New Book successfully created" + assert response_body == f"planet {EXPECTED_PLANET['name']} successfully created" + + +# def test_create_one_planet(client): +# # Act +# response = client.post("/planets", json={ +# "name": "MelMash Planet", +# "description": "The Best!", +# "color": "Green" +# }) +# response_body = response.get_json() + +# # Assert +# assert response.status_code == 201 +# assert response_body == "planet MelMash Planet successfully created" From f5f9904fd04bf77681c18d3f855c7136352fe7d4 Mon Sep 17 00:00:00 2001 From: Masha Date: Thu, 3 Nov 2022 21:23:23 -0700 Subject: [PATCH 20/28] Wave 6 last test fixed --- app/routes.py | 3 ++- tests/test_routes.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/routes.py b/app/routes.py index 0a0bc7070..b742634e5 100644 --- a/app/routes.py +++ b/app/routes.py @@ -61,7 +61,8 @@ def create_planet(): db.session.add(new_planet) db.session.commit() # I have changed this retun statement and run the test. My terminal is acting up. Plaease try to run the test. - return make_response(jsonify(f"planet {new_planet.name} successfully created", 201)) + #return make_response(jsonify(f"planet {new_planet.name} successfully created")), 201 + return make_response(f"planet {new_planet.name} successfully created"), 201 @planets_bp.route("/", methods=["GET"]) def read_one_planet(planet_id): diff --git a/tests/test_routes.py b/tests/test_routes.py index c720fa9f7..84b836793 100644 --- a/tests/test_routes.py +++ b/tests/test_routes.py @@ -32,7 +32,7 @@ def test_create_planet_can_create_planet_in_empty_db(client): "color": "New color" } - EXPECTED_ID = 1 + #EXPECTED_ID = 1 #act response = client.post("/planets", json = EXPECTED_PLANET) From aa53137c17e883513f2ca232ffa91a7b944f6457 Mon Sep 17 00:00:00 2001 From: Masha Date: Fri, 4 Nov 2022 01:44:20 -0700 Subject: [PATCH 21/28] Wave 6 more tests --- tests/conftest.py | 36 ++++++++++++++++++++++++++++- tests/test_routes.py | 55 +++++++++++++++++++++++++++++++++++--------- 2 files changed, 79 insertions(+), 12 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 7391a6920..b66f39092 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -42,4 +42,38 @@ def one_planet(app): db.session.commit() db.session.refresh(test_planet, ["id"]) - return test_planet \ No newline at end of file + return test_planet + +@pytest.fixture +def many_planets(app): + # Arrange + + # ocean_book = Book(title="Ocean Book", + # description="watr 4evr") + # mountain_book = Book(title="Mountain Book", + # description="i luv 2 climb rocks") + + + apes_planet = Planet(name="Planet of apes", + description="Only apes live there", + color = "Grey") + crocodile_planet = Planet(name="Planet crocodiles", + description="Only crocodiles live there", + color = "Green") + butterfly_planet = Planet(name="Planet of butterflies", + description="Butterflies and unicorns live there", + color = "Rainbow") + orange_planet = Planet(name="Planet of oranges", + description="It's full of oranges", + color = "Orange") + + db.session.add_all([apes_planet, crocodile_planet, butterfly_planet, orange_planet]) + + #db.session.add(several_test_planets) + # Alternatively, we could do + # db.session.add(planet_number_one) + # db.session.add(test_planet) + db.session.commit() + + #db.session.refresh(test_planet, ["id"]) + \ No newline at end of file diff --git a/tests/test_routes.py b/tests/test_routes.py index 84b836793..5a6992cd5 100644 --- a/tests/test_routes.py +++ b/tests/test_routes.py @@ -9,6 +9,26 @@ def test_get_all_planets_with_no_records(client): assert response.status_code == 200 assert response_body == [] +def test_get_all_planets_with_fixture_records(client, many_planets): + # Act + response = client.get("/planets") + response_body = response.get_json() + + # Assert + assert response.status_code == 200 + assert len(response_body) == 4 + #assert + + +def test_get_one_planet_no_fixture(client): + # Act + response = client.get("/books/1") + response_body = response.get_json() + + # Assert + assert response.status_code == 404 + assert response_body is None + def test_get_one_planet(client, one_planet): # Act response = client.get(f"/planets/{one_planet.id}") @@ -44,16 +64,29 @@ def test_create_planet_can_create_planet_in_empty_db(client): assert response_body == f"planet {EXPECTED_PLANET['name']} successfully created" -# def test_create_one_planet(client): -# # Act -# response = client.post("/planets", json={ -# "name": "MelMash Planet", -# "description": "The Best!", -# "color": "Green" -# }) -# response_body = response.get_json() +def test_create_one_planet_if_there_are_planets_in_db(client, many_planets): + #arrange + EXPECTED_PLANET = { + "name": "Created Planet", + "description": "New watr 4evr", + "color": "New color" + } + + EXPECTED_ID = 5 -# # Assert -# assert response.status_code == 201 -# assert response_body == "planet MelMash Planet successfully created" + #act + response = client.post("/planets", json = EXPECTED_PLANET) + response_body = response.get_data(as_text=True) + + all_planets = Planet.query.all() + planets_response = [] + + for planet in all_planets: + planets_response.append(planet.to_dict()) + + # Assert + assert response.status_code == 201 + assert response_body == "planet Created Planet successfully created" + assert len(all_planets) == 5 + assert EXPECTED_PLANET["name"] == planets_response[4]["name"] \ No newline at end of file From 1e91d0aef783bf3eec2ca445afec187b4ee01fa5 Mon Sep 17 00:00:00 2001 From: Masha Date: Fri, 4 Nov 2022 02:23:36 -0700 Subject: [PATCH 22/28] Wave 6 even more tests --- app/routes.py | 5 +++-- tests/test_routes.py | 47 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/app/routes.py b/app/routes.py index b742634e5..a7f65d069 100644 --- a/app/routes.py +++ b/app/routes.py @@ -27,12 +27,13 @@ def validate_planet(class_obj, planet_id): try: planet_id = int(planet_id) except: - abort(make_response({"message":f"planet {class_obj} {planet_id} is an invalid planet_id"}, 400)) + abort(make_response({"message": f"planet {planet_id} has an invalid planet_id"}, 400)) query_result = class_obj.query.get(planet_id) if not query_result: - abort(make_response({"message":f"{class_obj} {planet_id} not found"}, 404)) + abort(make_response({"message": f"planet {planet_id} not found"}, 404)) + return query_result diff --git a/tests/test_routes.py b/tests/test_routes.py index 5a6992cd5..72027aa01 100644 --- a/tests/test_routes.py +++ b/tests/test_routes.py @@ -43,6 +43,53 @@ def test_get_one_planet(client, one_planet): "color": "color" } +def test_get_one_planet_from_many_planets_valid_id(client, many_planets): + #Arrange + EXPECTED_ID = 3 + + # Act + response = client.get(f"/planets/{EXPECTED_ID}") + response_body = response.get_json() + + # Assert + assert response.status_code == 200 + assert response_body == { + "id": 3, + "name": "Planet of butterflies", + "description": "Butterflies and unicorns live there", + "color": "Rainbow" + } + +def test_get_one_planet_from_many_planets_non_existing_id_returns_404(client, many_planets): + #Arrange + NON_EXISTING_ID = 7 + + # Act + response = client.get(f"/planets/{NON_EXISTING_ID}") + response_body = response.get_data(as_text=True) + + # Assert + assert response.status_code == 404 + + # ??????????? big question here how to make pretty message + assert response_body == "{\"message\":\"planet 7 not found\"}\n" + +def test_get_one_planet_from_many_planets_invalid_id_returns_400(client, many_planets): + #Arrange + INVALID_ID = "ABC" + + # Act + response = client.get(f"/planets/{INVALID_ID}") + response_body = response.get_data(as_text=True) + + # Assert + assert response.status_code == 400 + + # ??????????? big question here how to make pretty message + # assert response_body == f"Message: Planet {INVALID_ID} has an invalid planet_id" + assert response_body == "{\"message\":\"planet ABC has an invalid planet_id\"}\n" + #abort(make_response({"message":f"planet {class_obj} {planet_id} is an invalid planet_id"}, 400)) + def test_create_planet_can_create_planet_in_empty_db(client): #arrange From 732339318e7beab9c7eb652872f172b324109591 Mon Sep 17 00:00:00 2001 From: Melley Gebretatios Date: Fri, 4 Nov 2022 11:44:28 -0400 Subject: [PATCH 23/28] Last time before submitting it. --- app/routes.py | 5 ++--- tests/test_routes.py | 10 +++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/app/routes.py b/app/routes.py index a7f65d069..cf5fa92c1 100644 --- a/app/routes.py +++ b/app/routes.py @@ -61,8 +61,7 @@ def create_planet(): new_planet = Planet.from_json(request_body) db.session.add(new_planet) db.session.commit() -# I have changed this retun statement and run the test. My terminal is acting up. Plaease try to run the test. - #return make_response(jsonify(f"planet {new_planet.name} successfully created")), 201 + return make_response(f"planet {new_planet.name} successfully created"), 201 @planets_bp.route("/", methods=["GET"]) @@ -87,7 +86,7 @@ def update_planet(planet_id): db.session.commit() - return make_response(f"Planet #{planet.id} successfully updated") + return make_response (f"Planet #{planet.id} successfully updated") diff --git a/tests/test_routes.py b/tests/test_routes.py index 72027aa01..466a9d9a8 100644 --- a/tests/test_routes.py +++ b/tests/test_routes.py @@ -70,9 +70,10 @@ def test_get_one_planet_from_many_planets_non_existing_id_returns_404(client, ma # Assert assert response.status_code == 404 - - # ??????????? big question here how to make pretty message assert response_body == "{\"message\":\"planet 7 not found\"}\n" + # alternative + #assert response_body == f"Message: Planet {NON_EXISTING_ID} not found" + def test_get_one_planet_from_many_planets_invalid_id_returns_400(client, many_planets): #Arrange @@ -84,12 +85,11 @@ def test_get_one_planet_from_many_planets_invalid_id_returns_400(client, many_pl # Assert assert response.status_code == 400 - - # ??????????? big question here how to make pretty message # assert response_body == f"Message: Planet {INVALID_ID} has an invalid planet_id" assert response_body == "{\"message\":\"planet ABC has an invalid planet_id\"}\n" #abort(make_response({"message":f"planet {class_obj} {planet_id} is an invalid planet_id"}, 400)) - + # alternative + #assert response_body == f"Message: Planet {INVALID_ID} has an invalid planet_id" def test_create_planet_can_create_planet_in_empty_db(client): #arrange From f3f06b953e53546385679a86c38a7688247985f4 Mon Sep 17 00:00:00 2001 From: Masha Date: Fri, 4 Nov 2022 09:18:16 -0700 Subject: [PATCH 24/28] Clean up --- .gitignore | 2 +- app/models/planet.py | 16 +----------- app/routes.py | 62 -------------------------------------------- tests/conftest.py | 24 +---------------- tests/test_routes.py | 13 ---------- 5 files changed, 3 insertions(+), 114 deletions(-) diff --git a/.gitignore b/.gitignore index 15197b612..4e9b18359 100644 --- a/.gitignore +++ b/.gitignore @@ -108,7 +108,7 @@ celerybeat.pid *.sage.py # Environments -#.env +.env .venv env/ venv/ diff --git a/app/models/planet.py b/app/models/planet.py index ff7f79eca..e8a7ac106 100644 --- a/app/models/planet.py +++ b/app/models/planet.py @@ -26,18 +26,4 @@ def from_json(cls, req_body): def update(self, req_body): self.name= req_body["name"], self.color= req_body["color"], - self.description= req_body["description"] - - - - - - - - - # planet_as_dict = {} - # planet_as_dict["id"] = self.id - # planet_as_dict["title"] = self.title - # planet_as_dict["description"] = self.description - - # return planet_as_dict \ No newline at end of file + self.description= req_body["description"] \ No newline at end of file diff --git a/app/routes.py b/app/routes.py index cf5fa92c1..3f17ae340 100644 --- a/app/routes.py +++ b/app/routes.py @@ -4,25 +4,8 @@ from app.models.planet import Planet from flask import Blueprint, jsonify, abort, make_response, request - -# planets = [ -# Planet(1, "Mercury", "the closest to the Sun", "orange"), -# Planet(2, "Venus", "toxic atmosphere and yellowish clouds", "brown"), -# Planet(3, "Earth", "ocean planet", "blue"), -# Planet(4, "Mars", "small red, cold and dusty planet", "red"), -# Planet(5, "Jupiter", "covered in cloudy stripes", "light blue with brown stripes"), -# Planet(6, "Saturn", "has seven rings around its body", "beige"), -# Planet(7, "Uranus", "made of water", "baby blue"), -# Planet(8, "Neptune", "dark and very windy", "sky blue") -# ] - - planets_bp = Blueprint("planets_bp", __name__, url_prefix="/planets") - - -# def handle_planets(): - def validate_planet(class_obj, planet_id): try: planet_id = int(planet_id) @@ -34,7 +17,6 @@ def validate_planet(class_obj, planet_id): if not query_result: abort(make_response({"message": f"planet {planet_id} not found"}, 404)) - return query_result @planets_bp.route("", methods=["GET"]) @@ -69,10 +51,6 @@ def read_one_planet(planet_id): planet = validate_planet(Planet, planet_id) return jsonify(planet.to_dict()), 200 -# We should also make this change to jsonify our response body -# in the PUT /books/ and DELETE /books/ routes. -# This adds predictability to our RESTful routes. - @planets_bp.route("/", methods=["PUT"]) def update_planet(planet_id): planet = validate_planet(planet_id) @@ -88,8 +66,6 @@ def update_planet(planet_id): return make_response (f"Planet #{planet.id} successfully updated") - - @planets_bp.route("/", methods=["DELETE"]) def delete_planet(planet_id): planet = validate_planet(planet_id) @@ -98,41 +74,3 @@ def delete_planet(planet_id): db.session.commit() return make_response(f"Planet #{planet.id} successfully deleted") - - -# planets_bp = Blueprint("planets", __name__, url_prefix="/planets") -# @planets_bp.route("", methods=["Get"]) -# def get_all_planets(): -# result = [] -# for planet in planets: -# result.append({ -# "id": planet.id, -# "name": planet.name, -# "description": planet.description, -# "color": planet.color -# }) - -# return jsonify(result) - -# @planets_bp.route("/", methods=["GET"]) -# def get_one_planet(planet_id): -# planet = validate_planet(planet_id) - -# return jsonify({ -# "id": planet.id, -# "name": planet.name, -# "description": planet.description, -# "color": planet.color -# }), 200 - -# def validate_planet(planet_id): -# try: -# planet_id = int(planet_id) -# except: -# abort(make_response({"message":f"planet {planet_id} invalid"}, 400)) - -# for planet in planets: -# if planet.id == planet_id: -# return planet - -# abort(make_response({"message":f"planet {planet_id} not found"}, 404)) \ No newline at end of file diff --git a/tests/conftest.py b/tests/conftest.py index b66f39092..20c2d2fd9 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -26,19 +26,12 @@ def client(app): @pytest.fixture def one_planet(app): - # Arrange test_planet = Planet(name="Planet number one", description="watr 4evr", color = "color") - # test_planet = Planet(name="Test planet", - # description="i luv 2 climb rocks", - # color = "color") db.session.add(test_planet) - # Alternatively, we could do - # db.session.add(planet_number_one) - # db.session.add(test_planet) db.session.commit() db.session.refresh(test_planet, ["id"]) @@ -46,14 +39,6 @@ def one_planet(app): @pytest.fixture def many_planets(app): - # Arrange - - # ocean_book = Book(title="Ocean Book", - # description="watr 4evr") - # mountain_book = Book(title="Mountain Book", - # description="i luv 2 climb rocks") - - apes_planet = Planet(name="Planet of apes", description="Only apes live there", color = "Grey") @@ -69,11 +54,4 @@ def many_planets(app): db.session.add_all([apes_planet, crocodile_planet, butterfly_planet, orange_planet]) - #db.session.add(several_test_planets) - # Alternatively, we could do - # db.session.add(planet_number_one) - # db.session.add(test_planet) - db.session.commit() - - #db.session.refresh(test_planet, ["id"]) - \ No newline at end of file + db.session.commit() \ No newline at end of file diff --git a/tests/test_routes.py b/tests/test_routes.py index 466a9d9a8..dfaa222cd 100644 --- a/tests/test_routes.py +++ b/tests/test_routes.py @@ -71,9 +71,6 @@ def test_get_one_planet_from_many_planets_non_existing_id_returns_404(client, ma # Assert assert response.status_code == 404 assert response_body == "{\"message\":\"planet 7 not found\"}\n" - # alternative - #assert response_body == f"Message: Planet {NON_EXISTING_ID} not found" - def test_get_one_planet_from_many_planets_invalid_id_returns_400(client, many_planets): #Arrange @@ -85,11 +82,7 @@ def test_get_one_planet_from_many_planets_invalid_id_returns_400(client, many_pl # Assert assert response.status_code == 400 - # assert response_body == f"Message: Planet {INVALID_ID} has an invalid planet_id" assert response_body == "{\"message\":\"planet ABC has an invalid planet_id\"}\n" - #abort(make_response({"message":f"planet {class_obj} {planet_id} is an invalid planet_id"}, 400)) - # alternative - #assert response_body == f"Message: Planet {INVALID_ID} has an invalid planet_id" def test_create_planet_can_create_planet_in_empty_db(client): #arrange @@ -99,14 +92,10 @@ def test_create_planet_can_create_planet_in_empty_db(client): "color": "New color" } - #EXPECTED_ID = 1 - #act response = client.post("/planets", json = EXPECTED_PLANET) response_body = response.get_data(as_text=True) - #actual_planet = Planet.query.get(EXPECTED_ID) - assert response.status_code == 201 assert response_body == f"planet {EXPECTED_PLANET['name']} successfully created" @@ -119,8 +108,6 @@ def test_create_one_planet_if_there_are_planets_in_db(client, many_planets): "color": "New color" } - EXPECTED_ID = 5 - #act response = client.post("/planets", json = EXPECTED_PLANET) response_body = response.get_data(as_text=True) From 7b164aeae8d5de16a1e9de7946c622e4c86dec61 Mon Sep 17 00:00:00 2001 From: Melley Gebretatios Date: Mon, 7 Nov 2022 14:40:45 -0500 Subject: [PATCH 25/28] This is the commit with Procfile. --- Procfile | 1 + 1 file changed, 1 insertion(+) 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 From 529c5c87e9557fc2376f949912b4e79dacf790f9 Mon Sep 17 00:00:00 2001 From: Melley Gebretatios Date: Mon, 7 Nov 2022 19:50:53 -0500 Subject: [PATCH 26/28] Requirements fixed. --- app/routes.py | 1 - 1 file changed, 1 deletion(-) diff --git a/app/routes.py b/app/routes.py index 3f17ae340..7c30ccf71 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,5 +1,4 @@ from os import abort -from turtle import title from app import db from app.models.planet import Planet from flask import Blueprint, jsonify, abort, make_response, request From 0a9597e4f47fbb19e0fa6e6297da823bf4c275d8 Mon Sep 17 00:00:00 2001 From: Melley Gebretatios Date: Mon, 7 Nov 2022 20:00:56 -0500 Subject: [PATCH 27/28] Procfile updated. --- Procfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Procfile b/Procfile index 62e430aca..7cfc90917 100644 --- a/Procfile +++ b/Procfile @@ -1 +1 @@ -web: gunicorn 'app:create_app()' \ No newline at end of file +web: gunicorn --log-level=DEBUG 'app:create_app()' From 1f4d2ed8cff001a219a3bf80aa7c219887a621c4 Mon Sep 17 00:00:00 2001 From: Melley Gebretatios Date: Mon, 7 Nov 2022 20:06:07 -0500 Subject: [PATCH 28/28] Requirements fixed. --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index fba2b3e38..83515424a 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 idna==2.10 itsdangerous==1.1.0 Jinja2==2.11.3