From 573a7809e46d1cd7f809285366d4419c1812f949 Mon Sep 17 00:00:00 2001 From: Svetlana Date: Fri, 21 Oct 2022 09:32:12 -0700 Subject: [PATCH 01/16] planets --- app/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/__init__.py b/app/__init__.py index 70b4cabfe..2a77b41b8 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,7 +1,9 @@ from flask import Flask -def create_app(test_config=None): +def create_app(): app = Flask(__name__) + from .routes import planets_bp + app.register_blueprint(planets_bp) return app From 4d70a4fae225d6c564ae5809d614fcb6062ce311 Mon Sep 17 00:00:00 2001 From: Svetlana Date: Fri, 21 Oct 2022 11:17:51 -0700 Subject: [PATCH 02/16] solar_system --- app/routes.py | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/app/routes.py b/app/routes.py index 8e9dfe684..a3d794594 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,2 +1,37 @@ -from flask import Blueprint +from flask import Blueprint,jsonify +class Planet: + def __init__(self,id,name,eq_diam,mass,moons,description): + self.id = id + self.name = name + self.eq_diam = eq_diam + self.mass = mass + self.moons = moons + self.description = description + + + +PLANETS =[ + + Planet(1, "Mercury",0.383,0.06,0,"the smallest planet in our solar system and closest to the Sun—is only slightly larger than Earth's Moon. Mercury is the fastest planet, zipping around the Sun every 88 Earth days"), + Planet(2, "Venus",0.949,0.81,0,"Venus spins slowly in the opposite direction from most planets. A thick atmosphere traps heat in a runaway greenhouse effect, making it the hottest planet in our solar system"), + Planet(3, "Earth",1.000,1.00,1,"our home planet—is the only place we know of so far that’s inhabited by living things. It's also the only planet in our solar system with liquid water on the surface" ) + ] +planets_bp = Blueprint('planets_bp', __name__, url_prefix='/planets') + +@planets_bp.route('',methods=['GET']) +def get_all_planets(): + planet_response = [] + for planet in PLANETS: + planet_response.append({ + 'id': planet.id, + 'name': planet.name, + 'eq_diam': planet.eq_diam, + 'mass': planet.mass, + 'moons': planet.moons, + 'deskriptions': planet.description + + }) + print(type(planet_response)) + print(type(jsonify(planet_response))) + return jsonify(planet_response) \ No newline at end of file From c1c503ade6788688d9a2ec45992de9a5be167e14 Mon Sep 17 00:00:00 2001 From: ashanti Date: Sat, 22 Oct 2022 13:22:28 -0400 Subject: [PATCH 03/16] defined planet class --- app/routes.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/routes.py b/app/routes.py index 8e9dfe684..94b2f84dd 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,2 +1,9 @@ -from flask import Blueprint +from flask import Blueprint, jsonify + +class Planet: + def __init__(self, id, name, description, moons): + self.id = id + self.name = name + self.description = description + self.moons = moons From 2db24fd92dda3035a29209cbe1b69de966965b0f Mon Sep 17 00:00:00 2001 From: ashanti Date: Sat, 22 Oct 2022 14:11:27 -0400 Subject: [PATCH 04/16] hardcoded planet instances --- app/routes.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/app/routes.py b/app/routes.py index 94b2f84dd..88b15830f 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,9 +1,22 @@ from flask import Blueprint, jsonify class Planet: - def __init__(self, id, name, description, moons): + def __init__(self, id, name, description, revolution_period): self.id = id self.name = name self.description = description - self.moons = moons + self.revolution_period = revolution_period + +PLANETS = [ + Planet(1, "Mercury", "terrestrial", "87.97 days"), + Planet(2, "Venus", "terrestrial", "224.7 days"), + Planet(3, "Earth", "terrestrial", "365.26 days"), + Planet(4, "Mars", "terrestrial", "1.88 years"), + Planet(5, "Jupiter", "gaseous", "11.86 years"), + Planet(6, "Saturn", "gaseous", "29.46 years"), + Planet(7, "Uranus", "gaseous", "84.01 years"), + Planet(8, "Neptune", "gaseous", "164.79 years"), + Planet(9, "Pluto", "icy, rocky", "248.59 years") +] + From 0df069d34ff566265ad316e2ef579cc3d9324852 Mon Sep 17 00:00:00 2001 From: ashanti Date: Sat, 22 Oct 2022 14:52:09 -0400 Subject: [PATCH 05/16] wave1 complete --- app/__init__.py | 3 +++ app/routes.py | 14 ++++++++++++++ 2 files changed, 17 insertions(+) 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 88b15830f..c418cb86c 100644 --- a/app/routes.py +++ b/app/routes.py @@ -20,3 +20,17 @@ def __init__(self, id, name, description, revolution_period): ] +planets_bp = Blueprint("planets_bp", __name__, url_prefix="/planets") + +@planets_bp.route("", methods=["GET"]) +def get_all_planets(): + planet_response = [] + for planet in PLANETS: + planet_response.append({ + "id" : planet.id, + "name" : planet.name, + "description" : planet.description, + "revolution_period" : planet.revolution_period + }) + + return jsonify(planet_response) \ No newline at end of file From 52a57bc8341b8e23a9686b7f26dab6ccfcd513a2 Mon Sep 17 00:00:00 2001 From: ashanti Date: Mon, 24 Oct 2022 11:20:15 -0400 Subject: [PATCH 06/16] refactored get_all_planets function --- app/routes.py | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/app/routes.py b/app/routes.py index c418cb86c..6138627b0 100644 --- a/app/routes.py +++ b/app/routes.py @@ -22,15 +22,22 @@ def __init__(self, id, name, description, revolution_period): planets_bp = Blueprint("planets_bp", __name__, url_prefix="/planets") +# @planets_bp.route("", methods=["GET"]) +# def get_all_planets(): +# planet_response = [] +# for planet in PLANETS: +# planet_response.append({ +# "id" : planet.id, +# "name" : planet.name, +# "description" : planet.description, +# "revolution_period" : planet.revolution_period +# }) + +# return jsonify(planet_response) + +# ------------------ Refactoring get_all_planets with vars and list comprehension -------------------- @planets_bp.route("", methods=["GET"]) + def get_all_planets(): - planet_response = [] - for planet in PLANETS: - planet_response.append({ - "id" : planet.id, - "name" : planet.name, - "description" : planet.description, - "revolution_period" : planet.revolution_period - }) - - return jsonify(planet_response) \ No newline at end of file + planet_response = [vars(planet) for planet in PLANETS] + return jsonify(planet_response) From a1d6014164703e172c262895ee11f9e3c2a9efee Mon Sep 17 00:00:00 2001 From: ashanti Date: Mon, 24 Oct 2022 11:54:42 -0400 Subject: [PATCH 07/16] refactor --- app/routes.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/routes.py b/app/routes.py index 6138627b0..c98c54f5a 100644 --- a/app/routes.py +++ b/app/routes.py @@ -41,3 +41,6 @@ def __init__(self, id, name, description, revolution_period): def get_all_planets(): planet_response = [vars(planet) for planet in PLANETS] return jsonify(planet_response) + +#GET one planet + From a3b6cc9ee78296cb65ab0f4ad83bee53996ba53b Mon Sep 17 00:00:00 2001 From: Svetlana Date: Mon, 24 Oct 2022 08:55:26 -0700 Subject: [PATCH 08/16] my_code --- app/routes.py | 48 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/app/routes.py b/app/routes.py index a3d794594..1f0fc8011 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,4 +1,6 @@ -from flask import Blueprint,jsonify +from crypt import methods +from os import abort +from flask import Blueprint,jsonify,abort,make_response class Planet: def __init__(self,id,name,eq_diam,mass,moons,description): @@ -21,17 +23,35 @@ def __init__(self,id,name,eq_diam,mass,moons,description): @planets_bp.route('',methods=['GET']) def get_all_planets(): - planet_response = [] - for planet in PLANETS: - planet_response.append({ - 'id': planet.id, - 'name': planet.name, - 'eq_diam': planet.eq_diam, - 'mass': planet.mass, - 'moons': planet.moons, - 'deskriptions': planet.description + planet_response = [vars(planet) for planet in PLANETS] + return jsonify(planet_response) + # for planet in PLANETS: + # planet_response.append({ + # 'id': planet.id, + # 'name': planet.name, + # 'eq_diam': planet.eq_diam, + # 'mass': planet.mass, + # 'moons': planet.moons, + # 'deskriptions': planet.description + + # }) - }) - print(type(planet_response)) - print(type(jsonify(planet_response))) - return jsonify(planet_response) \ No newline at end of file +@planets_bp.route('/',methods=['GET']) +def get_one_planet(id): + planet = validate_planet(id) + return planet + +def validate_planet(id): + try: + planet_id = int(id) + except ValueError: + return { + 'message': 'Invalid planer id' + },400 + for planet in PLANETS: + if planet.id == planet_id: + return vars(planet) + abort(make_response(jsonify(description = 'Resourse not found'),404)) + # print(type(planet_response)) + # print(type(jsonify(planet_response))) + \ No newline at end of file From 95086488c256c2f089eac1b003ebdb8a615cb158 Mon Sep 17 00:00:00 2001 From: ashanti Date: Mon, 24 Oct 2022 12:13:50 -0400 Subject: [PATCH 09/16] get one planet refactored and error handling --- app/routes.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/app/routes.py b/app/routes.py index e975b9f4d..8aefa246d 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, revolution_period): @@ -49,12 +49,16 @@ def validate_planet(id): planet_id = int(id) except ValueError: return { - 'message': 'Invalid planer id' + 'message': 'Invalid planet id' },400 for planet in PLANETS: if planet.id == planet_id: return vars(planet) - abort(make_response(jsonify(description = 'Resourse not found'),404)) + abort(make_response(jsonify(description = 'Planet not found'),404)) # print(type(planet_response)) # print(type(jsonify(planet_response))) - \ No newline at end of file + +@planets_bp.route('/',methods=['GET']) +def get_one_planet(id): + planet = validate_planet(id) + return planet From 2d8fb09463d9ffcbe53b2bd5143b32b1564770c2 Mon Sep 17 00:00:00 2001 From: ashanti Date: Tue, 1 Nov 2022 11:40:30 -0400 Subject: [PATCH 10/16] added solar system database --- app/__init__.py | 18 +++- app/models/__init__.py | 0 app/models/planet.py | 7 ++ app/routes/__init__.py | 0 app/{ => routes}/routes.py | 36 +++---- migrations/README | 1 + migrations/alembic.ini | 45 +++++++++ migrations/env.py | 96 +++++++++++++++++++ migrations/script.py.mako | 24 +++++ .../b57203d7c1ac_adds_planet_model.py | 34 +++++++ 10 files changed, 239 insertions(+), 22 deletions(-) create mode 100644 app/models/__init__.py create mode 100644 app/models/planet.py create mode 100644 app/routes/__init__.py rename app/{ => routes}/routes.py (61%) 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/b57203d7c1ac_adds_planet_model.py diff --git a/app/__init__.py b/app/__init__.py index 447d1c21e..32d033f72 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,12 +1,22 @@ from flask import Flask +from flask_sqlalchemy import SQLAlchemy +from flask_migrate import Migrate +db = SQLAlchemy() +migrate = Migrate() -def create_app(): +def create_app(test_config=None): app = Flask(__name__) - from .routes import planets_bp - app.register_blueprint(planets_bp) - from .routes import planets_bp + app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False + app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql+psycopg2://postgres:postgres@localhost:5432/solar_system_development' + + db.init_app(app) + migrate.init_app(app, db) + + from app.models.planet import Planet + + from .routes.routes import planets_bp app.register_blueprint(planets_bp) return app diff --git a/app/models/__init__.py b/app/models/__init__.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..5ee784dac --- /dev/null +++ b/app/models/planet.py @@ -0,0 +1,7 @@ +from app import db + +class Planet(db.Model): + id = db.Column(db.Integer, primary_key=True, autoincrement=True) + title = db.Column(db.String) + description = db.Column(db.String) + revolution_period = db.Column(db.String) \ No newline at end of file diff --git a/app/routes/__init__.py b/app/routes/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/app/routes.py b/app/routes/routes.py similarity index 61% rename from app/routes.py rename to app/routes/routes.py index 8aefa246d..cbc8170c8 100644 --- a/app/routes.py +++ b/app/routes/routes.py @@ -1,23 +1,23 @@ -from flask import Blueprint, jsonify, abort, make_response +from flask import Blueprint, jsonify, abort, make_response, request -class Planet: - def __init__(self, id, name, description, revolution_period): - self.id = id - self.name = name - self.description = description - self.revolution_period = revolution_period +# class Planet: +# def __init__(self, id, name, description, revolution_period): +# self.id = id +# self.name = name +# self.description = description +# self.revolution_period = revolution_period -PLANETS = [ - Planet(1, "Mercury", "terrestrial", "87.97 days"), - Planet(2, "Venus", "terrestrial", "224.7 days"), - Planet(3, "Earth", "terrestrial", "365.26 days"), - Planet(4, "Mars", "terrestrial", "1.88 years"), - Planet(5, "Jupiter", "gaseous", "11.86 years"), - Planet(6, "Saturn", "gaseous", "29.46 years"), - Planet(7, "Uranus", "gaseous", "84.01 years"), - Planet(8, "Neptune", "gaseous", "164.79 years"), - Planet(9, "Pluto", "icy, rocky", "248.59 years") -] +# PLANETS = [ +# Planet(1, "Mercury", "terrestrial", "87.97 days"), +# Planet(2, "Venus", "terrestrial", "224.7 days"), +# Planet(3, "Earth", "terrestrial", "365.26 days"), +# Planet(4, "Mars", "terrestrial", "1.88 years"), +# Planet(5, "Jupiter", "gaseous", "11.86 years"), +# Planet(6, "Saturn", "gaseous", "29.46 years"), +# Planet(7, "Uranus", "gaseous", "84.01 years"), +# Planet(8, "Neptune", "gaseous", "164.79 years"), +# Planet(9, "Pluto", "icy, rocky", "248.59 years") +# ] planets_bp = Blueprint("planets_bp", __name__, url_prefix="/planets") 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/b57203d7c1ac_adds_planet_model.py b/migrations/versions/b57203d7c1ac_adds_planet_model.py new file mode 100644 index 000000000..f53fcba4d --- /dev/null +++ b/migrations/versions/b57203d7c1ac_adds_planet_model.py @@ -0,0 +1,34 @@ +"""adds Planet model + +Revision ID: b57203d7c1ac +Revises: +Create Date: 2022-11-01 11:28:32.202651 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'b57203d7c1ac' +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('title', sa.String(), nullable=True), + sa.Column('description', sa.String(), nullable=True), + sa.Column('revolution_period', 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 98c25e08c3aede5cf288c996659a72f944dc8f33 Mon Sep 17 00:00:00 2001 From: ashanti Date: Tue, 1 Nov 2022 11:44:35 -0400 Subject: [PATCH 11/16] changed planet model title to name --- app/models/planet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/planet.py b/app/models/planet.py index 5ee784dac..a76e16946 100644 --- a/app/models/planet.py +++ b/app/models/planet.py @@ -2,6 +2,6 @@ class Planet(db.Model): id = db.Column(db.Integer, primary_key=True, autoincrement=True) - title = db.Column(db.String) + name = db.Column(db.String) description = db.Column(db.String) revolution_period = db.Column(db.String) \ No newline at end of file From 3aafe8604438ba8d4443435bd65e64cec3707c8f Mon Sep 17 00:00:00 2001 From: ashanti Date: Tue, 1 Nov 2022 12:24:06 -0400 Subject: [PATCH 12/16] added new migrations folder bc recreated db --- ..._planet_model.py => b9500ec88faa_adds_planet_model.py} | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) rename migrations/versions/{b57203d7c1ac_adds_planet_model.py => b9500ec88faa_adds_planet_model.py} (83%) diff --git a/migrations/versions/b57203d7c1ac_adds_planet_model.py b/migrations/versions/b9500ec88faa_adds_planet_model.py similarity index 83% rename from migrations/versions/b57203d7c1ac_adds_planet_model.py rename to migrations/versions/b9500ec88faa_adds_planet_model.py index f53fcba4d..ac4200212 100644 --- a/migrations/versions/b57203d7c1ac_adds_planet_model.py +++ b/migrations/versions/b9500ec88faa_adds_planet_model.py @@ -1,8 +1,8 @@ """adds Planet model -Revision ID: b57203d7c1ac +Revision ID: b9500ec88faa Revises: -Create Date: 2022-11-01 11:28:32.202651 +Create Date: 2022-11-01 12:18:40.670184 """ from alembic import op @@ -10,7 +10,7 @@ # revision identifiers, used by Alembic. -revision = 'b57203d7c1ac' +revision = 'b9500ec88faa' down_revision = None branch_labels = None depends_on = None @@ -20,7 +20,7 @@ def upgrade(): # ### commands auto generated by Alembic - please adjust! ### op.create_table('planet', sa.Column('id', sa.Integer(), autoincrement=True, nullable=False), - sa.Column('title', sa.String(), nullable=True), + sa.Column('name', sa.String(), nullable=True), sa.Column('description', sa.String(), nullable=True), sa.Column('revolution_period', sa.String(), nullable=True), sa.PrimaryKeyConstraint('id') From 9cff6fc3b9a5916adb92e92705af1be5f69772fa Mon Sep 17 00:00:00 2001 From: ashanti Date: Tue, 1 Nov 2022 12:34:26 -0400 Subject: [PATCH 13/16] added create planet endpoint --- app/routes/routes.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/app/routes/routes.py b/app/routes/routes.py index cbc8170c8..6f41d6fdd 100644 --- a/app/routes/routes.py +++ b/app/routes/routes.py @@ -1,5 +1,22 @@ +from app import db +from app.models.planet import Planet from flask import Blueprint, jsonify, abort, make_response, request +planets_bp = Blueprint("planets_bp", __name__, url_prefix="/planets") + +#Create a new Planet +@planets_bp.route("", methods=["POST"]) +def handle_planets(): + request_body = request.get_json() + new_planet = Planet(name=request_body["name"], + description=request_body["description"], + revolution_period=request_body["revolution_period"] + ) + + db.session.add(new_planet) + db.session.commit() + + return make_response(f"Book {new_planet.name} successfully created", 201) # class Planet: # def __init__(self, id, name, description, revolution_period): # self.id = id @@ -20,7 +37,6 @@ # ] -planets_bp = Blueprint("planets_bp", __name__, url_prefix="/planets") # @planets_bp.route("", methods=["GET"]) # def get_all_planets(): From e8deec31a816aba9848a4681408e4fcf4dc31ecf Mon Sep 17 00:00:00 2001 From: ashanti Date: Tue, 1 Nov 2022 13:35:16 -0400 Subject: [PATCH 14/16] added new migrations folder bc recreated db --- app/__init__.py | 4 +- app/routes/routes.py | 63 ++++++------------- ...l.py => 303fc3f68f6d_adds_planet_model.py} | 6 +- 3 files changed, 23 insertions(+), 50 deletions(-) rename migrations/versions/{b9500ec88faa_adds_planet_model.py => 303fc3f68f6d_adds_planet_model.py} (89%) diff --git a/app/__init__.py b/app/__init__.py index 32d033f72..0bc90e197 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -9,13 +9,13 @@ 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' + app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql+psycopg2://postgres:postgres@localhost:5432/solar_system_dev' db.init_app(app) migrate.init_app(app, db) from app.models.planet import Planet - + from .routes.routes import planets_bp app.register_blueprint(planets_bp) diff --git a/app/routes/routes.py b/app/routes/routes.py index 6f41d6fdd..e2545c14f 100644 --- a/app/routes/routes.py +++ b/app/routes/routes.py @@ -6,7 +6,7 @@ #Create a new Planet @planets_bp.route("", methods=["POST"]) -def handle_planets(): +def create_planet(): request_body = request.get_json() new_planet = Planet(name=request_body["name"], description=request_body["description"], @@ -16,7 +16,23 @@ def handle_planets(): db.session.add(new_planet) db.session.commit() - return make_response(f"Book {new_planet.name} successfully created", 201) + return make_response(f"Planet {new_planet.name} successfully created", 201) + +@planets_bp.route("", methods=["GET"]) +def read_all_planets(): + planets_response = [] + planets = Planet.query.all() + for planet in planets: + planets_response.append( + { + "id": planet.id, + "name": planet.name, + "description": planet.description, + "revolution_period": planet.revolution_period + } + ) + return jsonify(planets_response) + # class Planet: # def __init__(self, id, name, description, revolution_period): # self.id = id @@ -35,46 +51,3 @@ def handle_planets(): # Planet(8, "Neptune", "gaseous", "164.79 years"), # Planet(9, "Pluto", "icy, rocky", "248.59 years") # ] - - - -# @planets_bp.route("", methods=["GET"]) -# def get_all_planets(): -# planet_response = [] -# for planet in PLANETS: -# planet_response.append({ -# "id" : planet.id, -# "name" : planet.name, -# "description" : planet.description, -# "revolution_period" : planet.revolution_period -# }) - -# return jsonify(planet_response) - -# ------------------ Refactoring get_all_planets with vars and list comprehension -------------------- -@planets_bp.route("", methods=["GET"]) - -def get_all_planets(): - planet_response = [vars(planet) for planet in PLANETS] - return jsonify(planet_response) - -#GET one planet - -def validate_planet(id): - try: - planet_id = int(id) - except ValueError: - return { - 'message': 'Invalid planet id' - },400 - for planet in PLANETS: - if planet.id == planet_id: - return vars(planet) - abort(make_response(jsonify(description = 'Planet not found'),404)) - # print(type(planet_response)) - # print(type(jsonify(planet_response))) - -@planets_bp.route('/',methods=['GET']) -def get_one_planet(id): - planet = validate_planet(id) - return planet diff --git a/migrations/versions/b9500ec88faa_adds_planet_model.py b/migrations/versions/303fc3f68f6d_adds_planet_model.py similarity index 89% rename from migrations/versions/b9500ec88faa_adds_planet_model.py rename to migrations/versions/303fc3f68f6d_adds_planet_model.py index ac4200212..a38c10ff6 100644 --- a/migrations/versions/b9500ec88faa_adds_planet_model.py +++ b/migrations/versions/303fc3f68f6d_adds_planet_model.py @@ -1,8 +1,8 @@ """adds Planet model -Revision ID: b9500ec88faa +Revision ID: 303fc3f68f6d Revises: -Create Date: 2022-11-01 12:18:40.670184 +Create Date: 2022-11-01 13:25:16.340571 """ from alembic import op @@ -10,7 +10,7 @@ # revision identifiers, used by Alembic. -revision = 'b9500ec88faa' +revision = '303fc3f68f6d' down_revision = None branch_labels = None depends_on = None From 33813e2dad7f14601262bfa07e1b0f93d8d4f2c1 Mon Sep 17 00:00:00 2001 From: ashanti Date: Tue, 1 Nov 2022 13:59:15 -0400 Subject: [PATCH 15/16] added error handling for valid planets --- app/routes/routes.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/app/routes/routes.py b/app/routes/routes.py index e2545c14f..1de54bdf1 100644 --- a/app/routes/routes.py +++ b/app/routes/routes.py @@ -33,6 +33,32 @@ def read_all_planets(): ) return jsonify(planets_response) +#Error Handling an invalid planet or non-existing planet +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 + +#Get a Single(specific) planet endpoint +@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, + "revolution_period": planet.revolution_period + } + # class Planet: # def __init__(self, id, name, description, revolution_period): # self.id = id From d2fe0db3090938eccab928f13b34b904c379c18c Mon Sep 17 00:00:00 2001 From: ashanti Date: Wed, 2 Nov 2022 12:10:44 -0400 Subject: [PATCH 16/16] refactored read_all_planets to accept/stack queries --- app/routes/routes.py | 104 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 82 insertions(+), 22 deletions(-) diff --git a/app/routes/routes.py b/app/routes/routes.py index 1de54bdf1..08eff56a1 100644 --- a/app/routes/routes.py +++ b/app/routes/routes.py @@ -1,9 +1,24 @@ +from os import abort from app import db from app.models.planet import Planet from flask import Blueprint, jsonify, abort, make_response, request planets_bp = Blueprint("planets_bp", __name__, url_prefix="/planets") +#Error Handling an invalid planet or non-existing planet +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 + #Create a new Planet @planets_bp.route("", methods=["POST"]) def create_planet(): @@ -18,34 +33,53 @@ def create_planet(): return make_response(f"Planet {new_planet.name} successfully created", 201) + +# @planets_bp.route("", methods=["GET"]) +# def read_all_planets(): +# planets_response = [] +# planets = Planet.query.all() +# for planet in planets: +# planets_response.append( +# { +# "id": planet.id, +# "name": planet.name, +# "description": planet.description, +# "revolution_period": planet.revolution_period +# } +# ) +# return jsonify(planets_response) + + +# --------------------- Refactoring read_all query to take query params ---------------------------- @planets_bp.route("", methods=["GET"]) def read_all_planets(): - planets_response = [] - planets = Planet.query.all() - for planet in planets: - planets_response.append( - { - "id": planet.id, - "name": planet.name, - "description": planet.description, - "revolution_period": planet.revolution_period - } - ) - return jsonify(planets_response) + # this code replaces the previous (read_all_planets)query all code + # refactoring to stack queries -#Error Handling an invalid planet or non-existing planet -def validate_planet(planet_id): - try: - planet_id = int(planet_id) - except: - abort(make_response({"message":f"planet {planet_id} invalid"}, 400)) + planet_query = Planet.query #use variable to stack on queries - planet = planet.query.get(planet_id) + name_query = request.args.get("name") + if name_query: + planet_query = planet_query.filter(Planet.name.ilike(f"%{name_query}%")) + + description_query = request.args.get("description") + if description_query: + planet_query = planet_query.filter(Planet.description.ilike(f"%{description_query}%")) + + planets = planet_query.all() + - if not planet: - abort(make_response({"message":f"planet {planet_id} not found"}, 404)) + planets_response = [] + for planet in planets: + planets_response.append({ + "id": planet.id, + "name": planet.name, + "description": planet.description, + "revolution_period": planet.revolution_period + }) + + return jsonify(planets_response) - return planet #Get a Single(specific) planet endpoint @planets_bp.route("/", methods=["GET"]) @@ -59,6 +93,32 @@ def read_one_planet(planet_id): "revolution_period": planet.revolution_period } +#Updating a Planet (endpoint) +@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.revolution_period = request_body["revolution_period"] + + db.session.commit() + + return make_response(f"Planet #{planet.id} successfully updated") + +#Deleting a Planet (endpoint) +@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") + + # class Planet: # def __init__(self, id, name, description, revolution_period): # self.id = id