forked from AdaGold/solar-system-api
-
Notifications
You must be signed in to change notification settings - Fork 11
Ocelots - Soumya S and Kelly T #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
kellytate
wants to merge
39
commits into
ada-ac2:main
Choose a base branch
from
kellytate:main
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
39 commits
Select commit
Hold shift + click to select a range
e5d719c
Created Planets
kellytate fe92aad
Added /planets endpoint
kellytate 6e1b787
added get planet by id, and add validation
smysh 4759c30
Added a to_dict() method to convert data to dictionary.
smysh 15c8865
Made planet module and added attribute
kellytate 209d092
Moved planet.py, imported in routes.py, added additional planets.
smysh 349bdca
changes to create the planet model. make sure to separately CREATE DA…
smysh 1d2d1dc
added POST and GET routes to planets blueprint to create_planet_data(…
smysh 798befb
Added endpoints to create and get all planets.
kellytate 12087c9
Merged changes 12/21 in routes .py
smysh 842e96d
Added Read, Update, and Delete endpoints
kellytate eb94c73
add query params to sort planets by name and display results in ascen…
smysh e06912c
refactor code for query params by name and sort asc or desc
smysh 8729275
Added seed file
kellytate 8a4bdd8
added reading SQL configuration from .env file. jsonified make_respon…
smysh 0604d42
configure tests in conftest.py, added tests to read and create planet…
smysh c7de599
fix pytest warning
smysh bb771ec
Added tests for update and delete
kellytate 4cb75a0
Added tests for edge cases for update and delete
kellytate 672c773
Refactors and adds tests for to_dict() helper
kellytate f75313f
Adds tests for from_dict
kellytate abde75a
Refactors validate_planet to validate_model
kellytate 706d123
Corrects typo in create_planet
kellytate 5dce2e3
adds moon.py and moon_bp blueprint. Also adds routes to create and re…
smysh b9e8761
adds moon model migration change.
smysh 653abf4
remove references to foreign key. tests pass and routes are working a…
smysh e99dba2
Updates planet and moon models for FK relationship
kellytate b622107
Migrations to add/update Moon and Planet models
kellytate 6856cda
Removes old migration files
kellytate b0a271d
adds additional details to moon model.
smysh a6eb19c
Moved nested routes to planet_routes
kellytate 4cf54b5
added Procfile. installed gunicorn and added it to requirements.
smysh 0e2278c
added web: gunicorn to Procfile.
smysh c4eb47a
Minor correction to test name
kellytate dd97502
Adds Procfile
kellytate 591ce8f
Removes commented-out code in moon_routes
kellytate 9e83bbe
Merge branch 'main' of https://github.com/kellytate/solar-system-api
smysh 23a31a7
Updates moon creation and deletion routes
kellytate 789cd28
Merge branch 'main' of https://github.com/kellytate/solar-system-api
kellytate File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| web: gunicorn 'app:create_app()' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,36 @@ | ||
| 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__) | ||
|
|
||
| if not test_config: | ||
| app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('SQLALCHEMY_DATABASE_URI') | ||
| else: | ||
| app.config["TESTING"] = True | ||
| app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('SQLALCHEMY_TEST_DATABASE_URI') | ||
|
|
||
| app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False | ||
| app.config['JSON_SORT_KEYS'] = False | ||
| app.url_map.strict_slashes = False | ||
|
|
||
| db.init_app(app) | ||
| migrate.init_app(app, db) | ||
|
|
||
| from app.models.planet import Planet | ||
| from app.models.moon import Moon | ||
|
|
||
| from .planet_routes import planets_bp | ||
| app.register_blueprint(planets_bp) | ||
|
|
||
| from .moon_routes import moon_bp | ||
| app.register_blueprint(moon_bp) | ||
|
|
||
| return app |
Empty file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| from app import db | ||
| class Moon(db.Model): | ||
| id = db.Column(db.Integer,primary_key=True, autoincrement=True) | ||
| name = db.Column(db.String()) | ||
| size = db.Column(db.Integer()) | ||
| description = db.Column(db.String()) | ||
| distance_from_planet = db.Column(db.Integer()) | ||
| planet_id = db.Column(db.Integer(), db.ForeignKey('planet.id')) | ||
| planet = db.relationship("Planet", back_populates="moons") | ||
|
|
||
| def to_dict(self): | ||
| moon_as_dict = {} | ||
| moon_as_dict["id"] = self.id | ||
| moon_as_dict["name"] = self.name | ||
| moon_as_dict["size"] = self.size | ||
| moon_as_dict["description"] = self.description | ||
| moon_as_dict["distance_from_planet"] = self.distance_from_planet | ||
| moon_as_dict["planet_id"] = self.planet_id | ||
|
|
||
| return moon_as_dict | ||
|
|
||
| @classmethod | ||
| def from_dict(cls, moon_data): | ||
| new_moon = Moon( | ||
| name=moon_data["name"], | ||
| description=moon_data["description"], | ||
| size=moon_data["size"], | ||
| distance_from_planet=moon_data["distance_from_planet"], | ||
| planet_id=moon_data["planet_id"] | ||
| ) | ||
| return new_moon |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| 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()) | ||
| orbit_days = db.Column(db.Integer()) | ||
| num_moons = db.Column(db.Integer()) | ||
| moons = db.relationship("Moon", back_populates="planet") | ||
|
|
||
| def to_dict(self): | ||
| planet_as_dict = {} | ||
| planet_as_dict["id"] = self.id | ||
| planet_as_dict["name"] = self.name | ||
| planet_as_dict["description"] = self.description | ||
| planet_as_dict["orbit_days"] = self.orbit_days | ||
| planet_as_dict["num_moons"] = self.num_moons | ||
| moons_list = [] | ||
| for moon in self.moons: | ||
| moons_list.append(moon.to_dict()) | ||
| planet_as_dict["moons"] = moons_list | ||
|
|
||
| return planet_as_dict | ||
|
|
||
| @classmethod | ||
| def from_dict(cls, planet_data): | ||
| new_planet = Planet( | ||
| name=planet_data["name"], | ||
| description=planet_data["description"], | ||
| orbit_days=planet_data["orbit_days"], | ||
| num_moons=planet_data["num_moons"], | ||
|
|
||
| ) | ||
| return new_planet |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| from app import db | ||
| from app.models.moon import Moon | ||
| from app.models.planet import Planet | ||
| from app.planet_routes import validate_model | ||
| from flask import Blueprint, jsonify, abort, make_response, request | ||
|
|
||
| moon_bp = Blueprint("moon_bp", __name__, url_prefix="/moons") | ||
|
|
||
| @moon_bp.route("", methods=["POST"]) | ||
| def create_one_moon(): | ||
| request_body = request.get_json() | ||
| new_moon = Moon.from_dict(request_body) | ||
|
|
||
| db.session.add(new_moon) | ||
| db.session.commit() | ||
|
|
||
| return make_response(jsonify(f"Moon {new_moon.name} successfully created"), 201) | ||
|
|
||
| @moon_bp.route("", methods=["GET"]) | ||
| def read_one_moon_by_name(): | ||
|
|
||
| moons_query = Moon.query | ||
| name_query = request.args.get("name") | ||
| if name_query: | ||
| moons_query = moons_query.filter(Moon.name.ilike(f"%{name_query}%")) | ||
| moons = moons_query.all() | ||
| moons_response = [] | ||
| for moon in moons: | ||
| moons_response.append(moon.to_dict()) | ||
| return jsonify(moons_response) | ||
|
|
||
| @moon_bp.route("/<moon_id>", methods=["GET"]) | ||
| def read_one_moon_by_id(moon_id): | ||
|
|
||
| moon = validate_model(Moon, moon_id) | ||
| return moon.to_dict() | ||
|
|
||
| @moon_bp.route("", methods=["GET"]) | ||
| def read_all_moons(): | ||
|
|
||
| moons = Moon.query.all() | ||
|
|
||
| moons_response = [] | ||
| for moon in moons: | ||
| moons_response.append(moon.to_dict()) | ||
| return jsonify(moons_response) | ||
|
|
||
|
|
||
| @moon_bp.route("/<moon_id>", methods=["DELETE"]) | ||
| def delete_moon_by_id(moon_id): | ||
| moon = validate_model(Moon, moon_id) | ||
| planet = validate_model(Planet, moon.planet_id) | ||
|
|
||
| db.session.delete(moon) | ||
| planet.num_moons = len(planet.moons) | ||
| db.session.commit() | ||
|
|
||
| return make_response(jsonify(f"Moon {moon.name} successfully deleted")) | ||
|
|
||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| from app import db | ||
| from app.models.planet import Planet | ||
| from app.models.moon import Moon | ||
| from flask import Blueprint, jsonify, abort, make_response, request | ||
|
|
||
| planets_bp = Blueprint("planets_bp", __name__,url_prefix="/planets") | ||
|
|
||
| def validate_model(cls, model_id): | ||
| try: | ||
| model_id = int(model_id) | ||
| except: | ||
| abort(make_response({"message":f"{cls.__name__} {model_id} invalid"}, 400)) | ||
|
|
||
| model = cls.query.get(model_id) | ||
|
|
||
| if not model: | ||
| abort(make_response({"message":f"{cls.__name__} {model_id} not found"}, 404)) | ||
|
|
||
| return model | ||
|
|
||
| @planets_bp.route("", methods=["POST"]) | ||
| def create_planet(): | ||
| request_body = request.get_json() | ||
| if "name" not in request_body: | ||
| return make_response("Invalid Request", 400) | ||
|
|
||
| new_planet = Planet.from_dict(request_body) | ||
| db.session.add(new_planet) | ||
| db.session.commit() | ||
| return make_response(jsonify(f"Planet {new_planet.name} successfully created"), 201) | ||
|
|
||
| @planets_bp.route("", methods=["GET"]) | ||
| def read_all_planets(): | ||
| planets_response = [] | ||
| planet_query = Planet.query | ||
|
|
||
| name_query = request.args.get("name") | ||
| if name_query: | ||
| planet_query = planet_query.filter(Planet.name.ilike(f"%{name_query}%")) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nice use of SQLAlchemy's case-insensitive searching |
||
|
|
||
| sort_query = request.args.get("sort") | ||
| if sort_query == "desc": | ||
| planet_query = planet_query.order_by(Planet.name.desc()) | ||
| else: | ||
| planet_query = planet_query.order_by(Planet.name) | ||
|
|
||
|
|
||
| planets = planet_query.all() | ||
|
|
||
| for planet in planets: | ||
| planets_response.append(planet.to_dict()) | ||
| return jsonify(planets_response) | ||
|
|
||
| @planets_bp.route("/<planet_id>", methods=["GET"]) | ||
| def read_one_planet(planet_id): | ||
| planet = validate_model(Planet, planet_id) | ||
| return planet.to_dict() | ||
|
|
||
| @planets_bp.route("/<planet_id>", methods=["PUT"]) | ||
| def update_planet(planet_id): | ||
| planet = validate_model(Planet, planet_id) | ||
|
|
||
| request_body = request.get_json() | ||
|
|
||
| planet.name = request_body["name"] | ||
| planet.description = request_body["description"] | ||
| planet.orbit_days = request_body["orbit_days"] | ||
| planet.num_moons = request_body["num_moons"] | ||
|
|
||
| db.session.commit() | ||
|
|
||
| return make_response(jsonify(f"Planet #{planet.id} successfully updated")) | ||
|
|
||
| @planets_bp.route("/<planet_id>", methods=["DELETE"]) | ||
| def delete_planet(planet_id): | ||
| planet = validate_model(Planet, planet_id) | ||
|
|
||
| db.session.delete(planet) | ||
| db.session.commit() | ||
|
|
||
| return make_response(jsonify(f"Planet #{planet.id} successfully deleted")) | ||
|
|
||
| @planets_bp.route("/<planet_id>/moons", methods=["POST"]) | ||
| def create_one_moon_with_planet_id(planet_id): | ||
|
|
||
| planet = validate_model(Planet, planet_id) | ||
|
|
||
| request_body = request.get_json() | ||
| new_moon = Moon.from_dict(request_body) | ||
| new_moon.planet = planet | ||
| db.session.add(new_moon) | ||
| planet.num_moons = len(planet.moons) | ||
| db.session.commit() | ||
|
|
||
| return make_response(jsonify(f"Moon {new_moon.name} by {new_moon.planet.name} successfully created"), 201) | ||
|
|
||
| @planets_bp.route("/<planet_id>/moons", methods=["GET"]) | ||
| def read_all_moons_from_a_planet(planet_id): | ||
|
|
||
| planet = validate_model(Planet, planet_id) | ||
|
|
||
| moons_response = [] | ||
| for moon in planet.moons: | ||
| moons_response.append(moon.to_dict()) | ||
|
|
||
| return jsonify(moons_response) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| ALTER SEQUENCE planet_id_seq RESTART WITH 1; | ||
| ALTER SEQUENCE moon_id_seq RESTART WITH 1; | ||
| INSERT INTO planet VALUES (DEFAULT,'Mercury', 'Mercury is the closest planet to the Sun.', 88, 0); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This file is great to see here! |
||
| INSERT INTO planet VALUES (DEFAULT,'Venus', 'Venus is the hottest planet in the solar system.', 225 ,0); | ||
| INSERT INTO planet VALUES (DEFAULT,'Earth', 'Our home planet.', 365,1); | ||
| INSERT INTO planet VALUES (DEFAULT,'Mars', 'Also known as Red planet.', 687, 2); | ||
| INSERT INTO planet VALUES (DEFAULT,'Jupiter','Largest planet in the solar system.', 4333, 80); | ||
| INSERT INTO planet VALUES (DEFAULT,'Saturn', 'Only planet to have rings made of ice and rock.', 10759, 83); | ||
| INSERT INTO planet VALUES (DEFAULT,'Uranus', 'Only planet with a 97 degree tilted axis.', 30687, 27); | ||
| INSERT INTO planet VALUES (DEFAULT,'Neptune', 'Blue ice giant',60190, 14); | ||
| INSERT INTO moon VALUES (DEFAULT,'The Moon', 2159, 'The moon of Earth.', 238855, 3); | ||
| INSERT INTO moon VALUES (DEFAULT,'Deimos', 428, 'The smaller of the two moons of Mars.', 14580, 4); | ||
| INSERT INTO moon VALUES (DEFAULT,'The Phobos', 2618, 'The larger moon of Mars.', 3700, 4); | ||
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Generic single-database configuration. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice use of introspection here :)