Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
7a26300
Coworking agreement signed
smchavan Dec 14, 2022
5d7af5c
Coworking Agreement :)
diarreola Dec 14, 2022
984dd0b
Add planet class
diarreola Dec 14, 2022
40d41dd
Created Planets
smchavan Dec 14, 2022
ea5b064
Merge branch 'main' of https://github.com/diarreola/solar-system-api
smchavan Dec 14, 2022
9abc364
Created Planets
smchavan Dec 14, 2022
3f08639
Wave 01
smchavan Dec 14, 2022
2fda727
Wave 02
smchavan Dec 14, 2022
bf498b7
Wave 02: refactor
diarreola Dec 15, 2022
8898cfd
Add gravity endpoint
diarreola Dec 15, 2022
46e7bd1
Add greater_radius endpoint
diarreola Dec 15, 2022
f9544ba
Database Migrations and Created Model
smchavan Dec 20, 2022
55fbb44
retrieve planet name
diarreola Dec 20, 2022
676f0b7
Retrieve one planet
diarreola Dec 21, 2022
a382980
add PUT and DELETE endpoints
diarreola Dec 21, 2022
538d31a
Wave 5 GEt by name Asc and desc
smchavan Dec 22, 2022
9610dbc
Add testing env
diarreola Jan 3, 2023
dac5e28
requirements.txt
smchavan Jan 3, 2023
720c3bd
revert requirements file
diarreola Jan 3, 2023
78626af
requirements.txt
smchavan Jan 3, 2023
c175006
Merge branch 'main' of https://github.com/diarreola/solar-system-api
smchavan Jan 3, 2023
574952d
Add tests file
diarreola Jan 3, 2023
ede1669
testing endpoints
diarreola Jan 3, 2023
87d32e6
Fix code coverage
diarreola Jan 4, 2023
79a77ac
Merge branch 'main' of https://github.com/diarreola/solar-system-api
smchavan Jan 4, 2023
1be0f0a
wave7: refactor to_dict
diarreola Jan 4, 2023
f1f17a7
wave7: refactor and added from_dict
diarreola Jan 4, 2023
1f3c946
wave7: refactored valid_planet
diarreola Jan 4, 2023
e46da99
Co-authored-by: Diana <[email protected]>
smchavan Jan 4, 2023
dae1b06
Co-authored-by: Diana <[email protected]>
smchavan Jan 5, 2023
440bd7c
Added Moon Model and Nested Routes
smchavan Jan 5, 2023
2483ee6
Added Moon Model and Nested Routes New one
smchavan Jan 5, 2023
7ea390e
Add gunicorn adn procfile for heroku deployment
diarreola Jan 9, 2023
1209eec
Deployement procfile
smchavan Jan 9, 2023
83e8bd5
Merge branch 'main' of https://github.com/diarreola/solar-system-api
smchavan Jan 9, 2023
6d2dd5b
Deployement procfile 1
smchavan Jan 9, 2023
2cec17e
Merge pull request #1 from diarreola/New_Branch_Moon
smchavan Jan 9, 2023
0803b6b
Modified tests
smchavan Jan 9, 2023
5a4f547
Merge pull request #2 from diarreola/New_Branch_Moon
smchavan Jan 9, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.vscode
.DS_Store
.env

# Byte-compiled / optimized / DLL files
__pycache__/
Expand Down
1 change: 1 addition & 0 deletions Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
web: gunicorn 'app:create_app()'
26 changes: 26 additions & 0 deletions app/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,33 @@
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

if test_config:
app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get("SQLALCHEMY_TEST_DATABASE_URI")
app.config["Testing"] = True
else:
app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get("SQLALCHEMY_DATABASE_URI")

db.init_app(app)
migrate.init_app(app, db)

from app.models.planet import Planet

from .planet_routes import planets_bp
app.register_blueprint(planets_bp)

from .moon_routes import moons_bp
app.register_blueprint(moons_bp)
return app

Empty file added app/models/__init__.py
Empty file.
26 changes: 26 additions & 0 deletions app/models/moon.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from app import db

class Moon(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String, nullable=False)
size = db.Column(db.String, nullable=False)
description = db.Column(db.String, nullable=False)
planet_id = db.Column(db.Integer, db.ForeignKey("planet.id"))
planet = db.relationship("Planet", back_populates="moons")

def to_dict(self):
moon_dict = {}
moon_dict["id"] = self.id
moon_dict["name"] = self.name
moon_dict["size"] = self.size
moon_dict["description"] = self.description
return moon_dict

@classmethod
def from_dict(cls, moon_data):
new_moon = Moon(
name = moon_data["name"],
size = moon_data["size"],
description = moon_data["description"]
)
return new_moon
36 changes: 36 additions & 0 deletions app/models/planet.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
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)
radius = db.Column(db.Float)
num_moons = db.Column(db.Float)
gravity = db.Column(db.Float)
moons = db.relationship("Moon", back_populates="planet")

def to_dict(self):
planet_dict = {}
planet_dict["id"] = self.id
planet_dict["name"] = self.name
planet_dict["description"] = self.description
planet_dict["radius"] = self.radius
planet_dict["num_moons"] = self.num_moons
planet_dict["gravity"] = self.gravity

moon_names = []
for moon in self.moons:
moon_names.append(moon.name)
planet_dict["moon"] = moon_names
return planet_dict

@classmethod
def from_dict(cls, planet_data):
new_planet = Planet(name=planet_data["name"],
description=planet_data["description"],
radius=planet_data["radius"],
num_moons=planet_data["num_moons"],
gravity=planet_data["gravity"]
)
return new_planet

66 changes: 66 additions & 0 deletions app/moon_routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
from app import db
from app.models.moon import Moon
from app.planet_routes import validate_model
from flask import Blueprint, jsonify, make_response, request

moons_bp = Blueprint("moons_bp", __name__, url_prefix="/moons")

@moons_bp.route("", methods=["POST"])
def create_moon():
moon_data = request.get_json()
new_moon = Moon.from_dict(moon_data)

db.session.add(new_moon)
db.session.commit()

return make_response(f"Moon {new_moon.name} created", 201)

@moons_bp.route("", methods=["GET"])
def get_moons_optional_query():
moon_query = Moon.query

name_query = request.args.get("name")
if name_query:
moon_query = moon_query.filter(Moon.name.ilike(f"%{name_query}%"))

sort_query = request.args.get("sort")
if sort_query:
if sort_query == "desc":
moon_query = moon_query.order_by(Moon.size.desc())
else:
moon_query = moon_query.order_by(Moon.size.asc())

moons = moon_query.all()
moon_response = []
for moon in moons:
moon_response.append(moon.to_dict())

return jsonify(moon_response)

@moons_bp.route("/<moon_id>", methods=["GET"])
def get_moon_by_id(moon_id):
moon_to_return = validate_model(Moon, moon_id)

return jsonify(moon_to_return.to_dict())

@moons_bp.route("/<moon_id>", methods=["PUT"])
def replace_moon_with_id(moon_id):
moon_data = request.get_json()
moon_to_update = validate_model(Moon, moon_id)

moon_to_update.name = moon_data["name"],
moon_to_update.size = moon_data["size"],
moon_to_update.description = moon_data["description"],

db.session.commit()

return make_response(f"Moon {moon_to_update.name} updated", 200)

@moons_bp.route("/<moon_id>", methods=["DELETE"])
def delete_moons_by_id(moon_id):
moon_to_delete = validate_model(Moon, moon_id)
db.session.delete(moon_to_delete)
db.session.commit()

return make_response(f"Moon {moon_to_delete.name} deleted", 200)

109 changes: 109 additions & 0 deletions app/planet_routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
from app import db
from app.models.planet import Planet
from flask import Blueprint, jsonify, abort, make_response, request
from app.models.moon import Moon


planets_bp = Blueprint("planets_bp", __name__, url_prefix="/planets")


@planets_bp.route("", methods=["POST"])
def create_planet():
request_body = request.get_json()
new_planet = Planet.from_dict(request_body)

db.session.add(new_planet)
db.session.commit()

return make_response(f"Planet {new_planet.name} successfully created", 201)

@planets_bp.route("", methods=["GET"])
def read_all_planets():
planet_query = Planet.query
name_query = request.args.get("name")
if name_query:
planet_query = planet_query.filter(Planet.name.ilike(f"%{name_query}%"))

sort_query = request.args.get("sort")
if sort_query:
if sort_query == "desc":
planet_query = planet_query.order_by(Planet.name.desc())
else:
planet_query = planet_query.order_by(Planet.name.asc())

planets = planet_query.all()
planets_response = []
for planet in planets:
planets_response.append(planet.to_dict())
return jsonify(planets_response)

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("/<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()
# new_planet = Planet.from_dict(request_body)

planet.name = request_body["name"]
planet.description = request_body["description"]
planet.radius = request_body["radius"]
planet.num_moons = request_body["num_moons"]
planet.gravity = request_body["gravity"]

db.session.commit()
# new_planet = Planet.from_dict(request_body)
return make_response(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(f"Planet #{planet.id} successfully deleted")


@planets_bp.route("/<planet_id>/moons", methods=["POST"])
def add_new_moon_to_planet(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)
db.session.commit()

message = f"Moon {new_moon.name} created with Planet{planet.name}"
return make_response(jsonify(message), 201)

@planets_bp.route("/<planet_id>/moons", methods=["GET"])
def get_all_moons_for_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)

2 changes: 0 additions & 2 deletions app/routes.py

This file was deleted.

4 changes: 2 additions & 2 deletions coworking_agreement.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@ Talk through each section with your partner. Add notes on what you discussed and
*Other co-working agreements that were not captured in the above sections.*

## Signatures
______________ _______________
Date: _________
_Supriya Chavan_ __Diana Arreola________
Date: 12/14/2023
1 change: 1 addition & 0 deletions migrations/README
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Generic single-database configuration.
45 changes: 45 additions & 0 deletions migrations/alembic.ini
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
Loading