From fd13777b275e326f88a8a159050c9f5365ae6c58 Mon Sep 17 00:00:00 2001 From: Tirhas Gebreyohannes Date: Mon, 18 Oct 2021 13:59:36 -0700 Subject: [PATCH 01/12] Initial setup --- app/__init__.py | 2 ++ app/routes.py | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/app/__init__.py b/app/__init__.py index 70b4cabfe..24188be49 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -3,5 +3,7 @@ def create_app(test_config=None): app = Flask(__name__) + from .routes import solarsystem_bp + app.register_blueprint(solarsystem_bp) return app diff --git a/app/routes.py b/app/routes.py index 8e9dfe684..1b3f5d8c4 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,2 +1,23 @@ from flask import Blueprint +solarsystem_bp = Blueprint("solarsystem", __name__, url_prefix="/solarsystem") + +class SolarSysten: + def __init__(self, name,description): + self.name = name + self.has_ring = True + self.description = description + + @solarsystem_bp.route("solarsystem", methods=["GET"]) + + planets = [ + SolarSystem() + ] +def handle_solarsystem(): + solarsystem_response = [] + for planet in solarsystem: + solarsystem_response.append({ + + }) + return jsonify(solarsystem_response) + \ No newline at end of file From 1659cc705771c0c130893d71bfad611d38e66bc0 Mon Sep 17 00:00:00 2001 From: Ainur Dzhaianbaeva Date: Mon, 18 Oct 2021 15:28:52 -0700 Subject: [PATCH 02/12] add Get routes --- app/routes.py | 69 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 57 insertions(+), 12 deletions(-) diff --git a/app/routes.py b/app/routes.py index 1b3f5d8c4..96660ccfe 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,23 +1,68 @@ -from flask import Blueprint +from flask import Blueprint, jsonify solarsystem_bp = Blueprint("solarsystem", __name__, url_prefix="/solarsystem") -class SolarSysten: - def __init__(self, name,description): +class SolarSystem: + def __init__(self, name, surface_area, orbital_period, distance_from_sun, radius): self.name = name - self.has_ring = True - self.description = description - - @solarsystem_bp.route("solarsystem", methods=["GET"]) + # self.has_ring = True + self.surface_area = surface_area + self.orbital_period = orbital_period + self.distance_from_sun = distance_from_sun + self.radius = radius + - planets = [ - SolarSystem() +planets = [ + SolarSystem("Mercury", "28.88 million mi²", "88 days", 57900000, "1,516 mi"), + SolarSystem("Venus", "177.7 million mi²", "225 days", 108200000, "3,760.4 mi"), + SolarSystem("Earth", "196.9 million mi²", "365 days", 149600000, "3,958.8 mi"), + SolarSystem("Mars", "55.91 million mi²", "687 days", 227900000, "2,106.1 mi"), + SolarSystem("Jupiter", "23.71 billion mi²", "12 years", 778600000, "43,441 mi"), + SolarSystem("Saturn", "36,184 mi", "29 years", 1433500000, "36,184 mi"), + SolarSystem("Uranus", "3.121 billion mi²", "84 years", 2872500000, "15,759 mi"), + SolarSystem("Neptune", "2.941 billion mi²", "165 years", 4495100000, "15,299 mi") ] + + +@solarsystem_bp.route("", methods=["GET"]) def handle_solarsystem(): solarsystem_response = [] - for planet in solarsystem: + for planet in planets: solarsystem_response.append({ - + "name": planet.name, + "surface_area": planet.surface_area, + "orbital_period": planet.orbital_period, + "distance_from_sun": planet.distance_from_sun, + "radius": planet.radius }) - return jsonify(solarsystem_response) + return jsonify(solarsystem_response) + + +@solarsystem_bp.route("/", methods=["GET"]) +def handle_planet(name): + for planet in planets: + if planet.name == name: + return { + "name": planet.name, + "surface_area": planet.surface_area, + "orbital_period": planet.orbital_period, + "distance_from_sun": planet.distance_from_sun, + "radius": planet.radius + } + + +@solarsystem_bp.route("/", methods=["GET"]) +def handle_planet(name): + + for planet in planets: + max_distance = max(planet.distance_from_sun) + # farest_planet = None + if planet.distance_from_sun == max_distance: + return { + "name": planet.name, + "surface_area": planet.surface_area, + "orbital_period": planet.orbital_period, + "distance_from_sun": planet.distance_from_sun, + "radius": planet.radius + } \ No newline at end of file From b2831cff18c650fad64761a0172f6d42aa7506d7 Mon Sep 17 00:00:00 2001 From: Tirhas Gebreyohannes Date: Mon, 18 Oct 2021 15:34:15 -0700 Subject: [PATCH 03/12] add get method --- app/routes.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/app/routes.py b/app/routes.py index 1b3f5d8c4..e7d07cb30 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,21 +1,22 @@ -from flask import Blueprint +from flask import Blueprint,jsonify solarsystem_bp = Blueprint("solarsystem", __name__, url_prefix="/solarsystem") class SolarSysten: - def __init__(self, name,description): + def __init__(self, name,distance): self.name = name self.has_ring = True - self.description = description + self.distance = distance @solarsystem_bp.route("solarsystem", methods=["GET"]) planets = [ - SolarSystem() + SolarSysten("Mercury",False,0.39) + ] def handle_solarsystem(): solarsystem_response = [] - for planet in solarsystem: + for planet in SolarSysten: solarsystem_response.append({ }) From ca8b6f3eef8026ada7c04527c8c746883c2280ca Mon Sep 17 00:00:00 2001 From: Tirhas Gebreyohannes Date: Tue, 19 Oct 2021 14:15:26 -0700 Subject: [PATCH 04/12] make changes on farest function and finalize --- app/routes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/routes.py b/app/routes.py index 5567b431f..ee1125ae7 100644 --- a/app/routes.py +++ b/app/routes.py @@ -39,7 +39,7 @@ def handle_planet(name): return "please enter a valid planet", 404 -@solarsystem_bp.route("/distance_from_sun", methods=["GET"]) +@solarsystem_bp.route("/max/distance_from_sun", methods=["GET"]) def farest_planet(): distances = [planet.distance_from_sun for planet in planets] for planet in planets: From 9a4f0352017da92656cabc6a5e3701fc3f72ac9e Mon Sep 17 00:00:00 2001 From: Tirhas Gebreyohannes Date: Mon, 25 Oct 2021 15:08:55 -0700 Subject: [PATCH 05/12] creates planet model, connects to DataBase and creates POST and GET routes --- app/__init__.py | 13 +++ app/models/__init__.py | 0 app/models/planet.py | 13 +++ app/routes.py | 71 +++++++------- migrations/README | 1 + migrations/alembic.ini | 45 +++++++++ migrations/env.py | 96 +++++++++++++++++++ migrations/script.py.mako | 24 +++++ .../96feded2ee65_adds_planet_model.py | 36 +++++++ 9 files changed, 260 insertions(+), 39 deletions(-) create mode 100644 app/models/__init__.py create mode 100644 app/models/planet.py 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/96feded2ee65_adds_planet_model.py diff --git a/app/__init__.py b/app/__init__.py index 24188be49..d598743ac 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,9 +1,22 @@ 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/solarsystem_db' + + from app.models.planet import Planet + from .routes import solarsystem_bp app.register_blueprint(solarsystem_bp) + + db.init_app(app) + migrate.init_app(app,db) 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..a4880b57e --- /dev/null +++ b/app/models/planet.py @@ -0,0 +1,13 @@ +from app import db + +class Planet(db.Model): + id = db.Column(db.Integer, primary_key= True, autoincrement=True) + name = db.Column(db.String(64)) + surface_area= db.Column(db.Integer) + orbital_period = db.Column(db.Integer) + distance_from_sun = db.Column(db.Integer) + radius = db.Column(db.Integer) + + + + \ No newline at end of file diff --git a/app/routes.py b/app/routes.py index ee1125ae7..c29d2a3ae 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,49 +1,42 @@ -from flask import Blueprint, jsonify +from app import db +from flask import Blueprint, jsonify, request,make_response +from app.models.planet import Planet solarsystem_bp = Blueprint("solarsystem", __name__, url_prefix="/solarsystem") -class SolarSystem: - def __init__(self, name, surface_area, orbital_period, distance_from_sun, radius): - self.name = name - self.surface_area = surface_area - self.orbital_period = orbital_period - self.distance_from_sun = distance_from_sun - self.radius = radius - -planets = [ - SolarSystem("Mercury", "28.88 million mi²", "88 days", 57900000, "1,516 mi"), - SolarSystem("Venus", "177.7 million mi²", "225 days", 108200000, "3,760.4 mi"), - SolarSystem("Earth", "196.9 million mi²", "365 days", 149600000, "3,958.8 mi"), - SolarSystem("Mars", "55.91 million mi²", "687 days", 227900000, "2,106.1 mi"), - SolarSystem("Jupiter", "23.71 billion mi²", "12 years", 778600000, "43,441 mi"), - SolarSystem("Saturn", "36,184 mi", "29 years", 1433500000, "36,184 mi"), - SolarSystem("Uranus", "3.121 billion mi²", "84 years", 2872500000, "15,759 mi"), - SolarSystem("Neptune", "2.941 billion mi²", "165 years", 4495100000, "15,299 mi") -] - @solarsystem_bp.route("", methods=["GET"]) def handle_solarsystem(): - solarsystem_response =[vars(planet) for planet in planets] - return jsonify(solarsystem_response) - - -@solarsystem_bp.route("/", methods=["GET"]) -def handle_planet(name): - name=name.capitalize() - print(name) + planets = Planet.query.all() + # solarsystem_response =[vars(planet) for planet in planets] + solarsystem_response = [] for planet in planets: - if planet.name == name: - return vars(planet) - else: - return "please enter a valid planet", 404 + solarsystem_response.append({ + 'id':planet.id, + 'name':planet.name, + 'surface_area':planet.surface_area, + 'orbital_period':planet.orbital_period, + 'distance_from_sun':planet.distance_from_sun, + 'radius':planet.radius + }) + return jsonify(solarsystem_response) + +@solarsystem_bp.route("", methods=["POST"]) +def create_solarsystem(): + request_date = request.get_json() + if 'name' not in request_date or 'surface_area' not in request_date or 'orbital_period' not in request_date \ + or 'distance_from_sun' not in request_date or 'radius' not in request_date: + return jsonify({'message': "missing data"}),400 + new_planet = Planet( + name= request_date['name'], + surface_area = request_date['surface_area'], + orbital_period = request_date['orbital_period'], + distance_from_sun = request_date['distance_from_sun'], + radius = request_date['radius'] + ) + db.session.add(new_planet) + db.session.commit() + return f" Planet {new_planet.name} created", 201 -@solarsystem_bp.route("/max/distance_from_sun", methods=["GET"]) -def farest_planet(): - distances = [planet.distance_from_sun for planet in planets] - for planet in planets: - max_distance = max(distances) - if planet.distance_from_sun == max_distance: - return vars(planet) \ No newline at end of file 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/96feded2ee65_adds_planet_model.py b/migrations/versions/96feded2ee65_adds_planet_model.py new file mode 100644 index 000000000..14bf18fa2 --- /dev/null +++ b/migrations/versions/96feded2ee65_adds_planet_model.py @@ -0,0 +1,36 @@ +"""adds planet model + +Revision ID: 96feded2ee65 +Revises: +Create Date: 2021-10-25 14:02:44.108898 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '96feded2ee65' +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(length=64), nullable=True), + sa.Column('surface_area', sa.Integer(), nullable=True), + sa.Column('orbital_period', sa.Integer(), nullable=True), + sa.Column('distance_from_sun', sa.Integer(), nullable=True), + sa.Column('radius', sa.Integer(), 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 dab93936eaaf4b044187ad85934699f6435d7134 Mon Sep 17 00:00:00 2001 From: Ainur Dzhaianbaeva Date: Tue, 26 Oct 2021 11:36:45 -0700 Subject: [PATCH 06/12] adds PUT route --- app/models/planet.py | 12 ++++++++++++ app/routes.py | 20 +++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/app/models/planet.py b/app/models/planet.py index a4880b57e..224c7fa5f 100644 --- a/app/models/planet.py +++ b/app/models/planet.py @@ -7,6 +7,18 @@ class Planet(db.Model): orbital_period = db.Column(db.Integer) distance_from_sun = db.Column(db.Integer) radius = db.Column(db.Integer) + + def to_dict(self): + return { + 'id':self.id, + 'name':self.name, + 'surface_area':self.surface_area, + 'orbital_period':self.orbital_period, + 'distance_from_sun':self.distance_from_sun, + 'radius':self.radius + } + + diff --git a/app/routes.py b/app/routes.py index c29d2a3ae..cfdbd6911 100644 --- a/app/routes.py +++ b/app/routes.py @@ -39,4 +39,22 @@ def create_solarsystem(): return f" Planet {new_planet.name} created", 201 - \ No newline at end of file +@solarsystem_bp.route("/", methods=["GET", "PUT"]) +def get_planet(planet_id): + planet = Planet.query.get(planet_id) + if not planet: + return {"Error": f"PLanet {planet_id} was not found"}, 404 + if request.method == "GET": + return jsonify(planet.to_dict()), 200 + elif request.method == "PUT": + form_data = request.get_json() + planet.name = form_data["name"], + planet.surface_area = form_data["surface_area"] + planet.orbital_period = form_data["orbital_period"] + planet.distance_from_sun = form_data["distance_from_sun"] + planet.radius = form_data["radius"] + + db.session.commit() + + return jsonify(planet.to_dict()), 200 + From 943372eab102bd84d364f078fef4f67fa750b118 Mon Sep 17 00:00:00 2001 From: Ainur Dzhaianbaeva Date: Tue, 26 Oct 2021 11:56:04 -0700 Subject: [PATCH 07/12] adds DELETE route --- app/routes.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/app/routes.py b/app/routes.py index cfdbd6911..19b0c8edd 100644 --- a/app/routes.py +++ b/app/routes.py @@ -58,3 +58,19 @@ def get_planet(planet_id): return jsonify(planet.to_dict()), 200 + + +@solarsystem_bp.route("/", methods=["DELETE"]) +def delete_planet(planet_id): + try: + planet_id = int(planet_id) + except ValueError: + return {"Error": "Id must be numeric"}, 400 + planet = Planet.query.get(planet_id) + if planet: + db.session.delete(planet) + db.session.commit() + return {"Message": f"Planet with id number {planet_id} deleted."}, 200 + + else: + return {"Message": f"Planet with id number {planet_id} not found"}, 404 From 2eb176390a2b58955a8bece8be8a96135b92de8b Mon Sep 17 00:00:00 2001 From: Tirhas Gebreyohannes Date: Wed, 27 Oct 2021 20:33:22 -0700 Subject: [PATCH 08/12] adds filter queries --- app/routes.py | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/app/routes.py b/app/routes.py index 19b0c8edd..e0ecd1eac 100644 --- a/app/routes.py +++ b/app/routes.py @@ -7,18 +7,25 @@ @solarsystem_bp.route("", methods=["GET"]) def handle_solarsystem(): - planets = Planet.query.all() - # solarsystem_response =[vars(planet) for planet in planets] + requested_name = request.args.get('name') + shorter_orbital_period=request.args.get("shorter_orbital_period") + if requested_name: + requested_name = requested_name.capitalize() + planets=Planet.query.filter_by(name=requested_name) + elif shorter_orbital_period: + try: + shorter_orbital_period = int(shorter_orbital_period) + except ValueError: + return {"Error": "Orbital period must be numeric"}, 400 + planets=Planet.query.filter(Planet.orbital_period < request.args.get("shorter/orbital_period")) + elif request.args.get("order_by") == "name": + planets = Planet.query.order_by(Planet.name.desc()) + else: + planets = Planet.query.all() solarsystem_response = [] for planet in planets: - solarsystem_response.append({ - 'id':planet.id, - 'name':planet.name, - 'surface_area':planet.surface_area, - 'orbital_period':planet.orbital_period, - 'distance_from_sun':planet.distance_from_sun, - 'radius':planet.radius - }) + solarsystem_response.append(planet.to_dict()) + return jsonify(solarsystem_response) @solarsystem_bp.route("", methods=["POST"]) @@ -41,6 +48,10 @@ def create_solarsystem(): @solarsystem_bp.route("/", methods=["GET", "PUT"]) def get_planet(planet_id): + try: + planet_id = int(planet_id) + except ValueError: + return {"Error": "Id must be numeric"}, 400 planet = Planet.query.get(planet_id) if not planet: return {"Error": f"PLanet {planet_id} was not found"}, 404 @@ -48,6 +59,11 @@ def get_planet(planet_id): return jsonify(planet.to_dict()), 200 elif request.method == "PUT": form_data = request.get_json() + + if 'name' not in form_data or 'surface_area' not in form_data or 'orbital_period' not in form_data \ + or 'distance_from_sun' not in form_data or 'radius' not in form_data: + return jsonify({'message': "missing data"}),400 + planet.name = form_data["name"], planet.surface_area = form_data["surface_area"] planet.orbital_period = form_data["orbital_period"] From 6b8367713fb171f44b7ec31e6b5788739840fffc Mon Sep 17 00:00:00 2001 From: Ainur Dzhaianbaeva Date: Thu, 28 Oct 2021 11:50:35 -0700 Subject: [PATCH 09/12] seperates GET and PUT routes logic --- app/routes.py | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/app/routes.py b/app/routes.py index e0ecd1eac..38ea2ead3 100644 --- a/app/routes.py +++ b/app/routes.py @@ -46,7 +46,7 @@ def create_solarsystem(): return f" Planet {new_planet.name} created", 201 -@solarsystem_bp.route("/", methods=["GET", "PUT"]) +@solarsystem_bp.route("/", methods=["GET"]) def get_planet(planet_id): try: planet_id = int(planet_id) @@ -54,25 +54,35 @@ def get_planet(planet_id): return {"Error": "Id must be numeric"}, 400 planet = Planet.query.get(planet_id) if not planet: - return {"Error": f"PLanet {planet_id} was not found"}, 404 + return {"Error": f"Planet with id number {planet_id} was not found"}, 404 if request.method == "GET": return jsonify(planet.to_dict()), 200 - elif request.method == "PUT": - form_data = request.get_json() - - if 'name' not in form_data or 'surface_area' not in form_data or 'orbital_period' not in form_data \ - or 'distance_from_sun' not in form_data or 'radius' not in form_data: - return jsonify({'message': "missing data"}),400 - - planet.name = form_data["name"], - planet.surface_area = form_data["surface_area"] - planet.orbital_period = form_data["orbital_period"] - planet.distance_from_sun = form_data["distance_from_sun"] - planet.radius = form_data["radius"] - db.session.commit() +@solarsystem_bp.route("/", methods=["PUT"]) +def update_planet(planet_id): + try: + planet_id = int(planet_id) + except ValueError: + return {"Error": "Id must be numeric"}, 400 + planet = Planet.query.get(planet_id) + + form_data = request.get_json() + + if 'name' not in form_data or 'surface_area' not in form_data or 'orbital_period' not in form_data \ + or 'distance_from_sun' not in form_data or 'radius' not in form_data: + return jsonify({'message': "missing data"}),400 + + planet.name = form_data["name"], + planet.surface_area = form_data["surface_area"] + planet.orbital_period = form_data["orbital_period"] + planet.distance_from_sun = form_data["distance_from_sun"] + planet.radius = form_data["radius"] + + db.session.commit() + + return jsonify(planet.to_dict()), 200 + - return jsonify(planet.to_dict()), 200 From d437ce3cd39e459445a562341f21edc38ab219f5 Mon Sep 17 00:00:00 2001 From: Tirhas Gebreyohannes Date: Thu, 28 Oct 2021 16:13:37 -0700 Subject: [PATCH 10/12] handles TypeErrors --- app/routes.py | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/app/routes.py b/app/routes.py index 38ea2ead3..7f350fe80 100644 --- a/app/routes.py +++ b/app/routes.py @@ -30,16 +30,23 @@ def handle_solarsystem(): @solarsystem_bp.route("", methods=["POST"]) def create_solarsystem(): - request_date = request.get_json() - if 'name' not in request_date or 'surface_area' not in request_date or 'orbital_period' not in request_date \ - or 'distance_from_sun' not in request_date or 'radius' not in request_date: + request_data = request.get_json() + if 'name' not in request_data or 'surface_area' not in request_data or 'orbital_period' not in request_data \ + or 'distance_from_sun' not in request_data or 'radius' not in request_data: return jsonify({'message': "missing data"}),400 + if type(request_data['name']) != str or type(request_data['surface_area']) != int or\ + type(request_data['orbital_period']) != int or type(request_data['distance_from_sun']) != int\ + or type(request_data['radius']) != int : + return jsonify({'message': "Unsupported data type"}),400 + + + new_planet = Planet( - name= request_date['name'], - surface_area = request_date['surface_area'], - orbital_period = request_date['orbital_period'], - distance_from_sun = request_date['distance_from_sun'], - radius = request_date['radius'] + name= request_data['name'], + surface_area = request_data['surface_area'], + orbital_period = request_data['orbital_period'], + distance_from_sun = request_data['distance_from_sun'], + radius = request_data['radius'] ) db.session.add(new_planet) db.session.commit() @@ -72,6 +79,11 @@ def update_planet(planet_id): or 'distance_from_sun' not in form_data or 'radius' not in form_data: return jsonify({'message': "missing data"}),400 + if type(form_data['name']) != str or type(form_data['surface_area']) != int or\ + type(form_data['orbital_period']) != int or type(form_data['distance_from_sun']) != int\ + or type(form_data['radius']) != int : + return jsonify({'message': "Unsupported data type"}),400 + planet.name = form_data["name"], planet.surface_area = form_data["surface_area"] planet.orbital_period = form_data["orbital_period"] @@ -82,10 +94,6 @@ def update_planet(planet_id): return jsonify(planet.to_dict()), 200 - - - - @solarsystem_bp.route("/", methods=["DELETE"]) def delete_planet(planet_id): try: @@ -100,3 +108,7 @@ def delete_planet(planet_id): else: return {"Message": f"Planet with id number {planet_id} not found"}, 404 + + + + \ No newline at end of file From 25d753e5a5e596a2732d51dbae44f2276216a194 Mon Sep 17 00:00:00 2001 From: Tirhas Gebreyohannes Date: Wed, 3 Nov 2021 11:47:41 -0700 Subject: [PATCH 11/12] adds .env file --- Procfile | 1 + app/__init__.py | 4 +++- app/routes.py | 4 ++-- requirements.txt | 1 + 4 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 Procfile diff --git a/Procfile b/Procfile new file mode 100644 index 000000000..62e430aca --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +web: gunicorn 'app:create_app()' \ No newline at end of file diff --git a/app/__init__.py b/app/__init__.py index d598743ac..c376aa4fa 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,6 +1,8 @@ from flask import Flask from flask_sqlalchemy import SQLAlchemy from flask_migrate import Migrate +import os +from dotenv import load_dotenv db = SQLAlchemy() migrate = Migrate() @@ -9,7 +11,7 @@ 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/solarsystem_db' + app.config['SQLALCHEMY_DATABASE_URI'] =os.enviro.get("SQLALCHEMY_DATABASE_URI") from app.models.planet import Planet diff --git a/app/routes.py b/app/routes.py index 7f350fe80..fe3d21421 100644 --- a/app/routes.py +++ b/app/routes.py @@ -62,8 +62,8 @@ def get_planet(planet_id): planet = Planet.query.get(planet_id) if not planet: return {"Error": f"Planet with id number {planet_id} was not found"}, 404 - if request.method == "GET": - return jsonify(planet.to_dict()), 200 + + return jsonify(planet.to_dict()), 200 @solarsystem_bp.route("/", methods=["PUT"]) def update_planet(planet_id): diff --git a/requirements.txt b/requirements.txt index fd90fffa8..d2f045e58 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,6 +6,7 @@ click==7.1.2 Flask==1.1.2 Flask-Migrate==2.6.0 Flask-SQLAlchemy==2.4.4 +gunicorn==20.1.0 idna==2.10 itsdangerous==1.1.0 Jinja2==2.11.3 From 852db5808726402b3772243f0735a2284cb7afca Mon Sep 17 00:00:00 2001 From: Tirhas Gebreyohannes Date: Wed, 3 Nov 2021 12:15:32 -0700 Subject: [PATCH 12/12] edited init.py --- app/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/__init__.py b/app/__init__.py index c376aa4fa..7bb63acf9 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -6,12 +6,12 @@ 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'] =os.enviro.get("SQLALCHEMY_DATABASE_URI") + app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get("SQLALCHEMY_DATABASE_URI") from app.models.planet import Planet