Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
eaec270
work wave1,create virtual env, dependencies, creat planet class and l…
tagaertner Oct 18, 2024
9914158
wave one
SalmaAnany Oct 19, 2024
b432ba2
work wave 2- get one existing planet and 404, 400 response.
tagaertner Oct 20, 2024
f9ab1f3
removing manual convert to dict
SalmaAnany Oct 21, 2024
458170a
Found the bug Tami!
SalmaAnany Oct 21, 2024
586f72c
Refactor the validate function
SalmaAnany Oct 21, 2024
0b2d368
clean up the try and catch, to a if check
SalmaAnany Oct 21, 2024
3ba5c57
clean up the try and catch, to a if check
SalmaAnany Oct 21, 2024
060a092
clean up the try and catch, to a if check
SalmaAnany Oct 21, 2024
9c30a4d
clean up the try and catch, to a if check
SalmaAnany Oct 21, 2024
48adb54
clean up the try and catch, to a if check
SalmaAnany Oct 21, 2024
8e38137
Merge branch 'main' of https://github.com/tagaertner/solar-system-api
SalmaAnany Oct 21, 2024
5947424
Wave Two completed
SalmaAnany Oct 21, 2024
8d8c5c7
Wave Two completed
SalmaAnany Oct 21, 2024
f9a58bc
Wave Two completed
SalmaAnany Oct 25, 2024
b718e48
Wave There completed
SalmaAnany Oct 25, 2024
8152076
added info to planet.py
tagaertner Oct 25, 2024
3876ed1
fixed spelling
tagaertner Oct 25, 2024
27b4595
Wave There completed
SalmaAnany Oct 27, 2024
15f540a
working on wave four: read one planet and update
SalmaAnany Oct 27, 2024
8bc777e
fix bug with update function, work delete function
tagaertner Oct 27, 2024
af913c5
work wave 5 retrieve description
tagaertner Oct 27, 2024
2f8cabd
work on adding moon to the request
tagaertner Oct 27, 2024
c55376c
added sort and fixed moon and desc param
tagaertner Oct 29, 2024
2a22918
fixing the moon query using __eq__ instead of ==
SalmaAnany Oct 29, 2024
c4a651f
working on wave 6 (fixture)
SalmaAnany Oct 30, 2024
f7fe0b6
working on wave 6 (fixture)
SalmaAnany Oct 30, 2024
01e806c
work wave 6 add fixtures and test to creat,add one, fix bug
tagaertner Oct 30, 2024
dd45b20
wave 6 is completed
SalmaAnany Oct 31, 2024
631b646
add pytest.fixture for update and delete and pytest, fixed update and…
tagaertner Oct 31, 2024
40d8c58
change pytest delete fuct and commented out the pytest.fixture
tagaertner Oct 31, 2024
492fa72
fixed moon_param bug not if there is no param is going to retrieve no…
SalmaAnany Oct 31, 2024
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
4 changes: 4 additions & 0 deletions .idea/shelf/clean_up_the_try_and_catch__to_a_if_check.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 20 additions & 2 deletions app/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
from importlib import import_module
from flask import Flask
from .routes.planet_routes import planets_bp
from .db import db, migrate
from .models import planet
import os


def create_app(test_config=None):
def create_app(config=None):
app = Flask(__name__)

app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

if config:
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('SQLALCHEMY_DATABASE_URI')
app.config.update(config)
else:
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('SQLALCHEMY_DATABASE_URI')
Comment on lines +11 to +17

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're duplicating some code by having the same statement in either side of the if/else. When we see this, we can factor out the repeated code and just keep what's unique in the if/else:

    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
    app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('SQLALCHEMY_DATABASE_URI')

    if config:
        app.config.update(config)


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

app.register_blueprint(planets_bp)

return app

7 changes: 7 additions & 0 deletions app/db.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from .models.base import Base

db = SQLAlchemy(model_class=Base)
migrate = Migrate()

Empty file added app/models/__init__py
Empty file.
5 changes: 5 additions & 0 deletions app/models/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from sqlalchemy.orm import DeclarativeBase

class Base(DeclarativeBase):
pass

48 changes: 48 additions & 0 deletions app/models/planet.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from sqlalchemy.orm import Mapped, mapped_column
from ..db import db

class Planet(db.Model):
__tablename__ = "planets"
id: Mapped[int] = mapped_column(primary_key= True, autoincrement=True)
name: Mapped[str]
description: Mapped[str]
moon: Mapped[int]

def to_dict(self):
return dict(
id=self.id,
name=self.name,
description=self.description,
moon=self.moon
)







# class Planet:
# def __init__(self,id, name, description, moon):
# self.id = id
# self.name = name
# self.description = description
# self.moon = moon
#
# planets = [
# Planet(1, "Mercury", "the smallest planet in the solar system and orbits closest to the Sun, with extreme temperatures ranging from 430°C (800°F) during the day to -180°C (-290°F) at night.", 0),
# Planet(2, "Venus", "the Sun and has a thick, toxic atmosphere composed mostly of carbon dioxide, creating a runaway greenhouse effect that makes it the hottest planet in the solar system with surface temperatures around 465°C (870°F", 0),
# Planet(3, "Earth", "Our home planet, the only known planet to harbor life",1),
# Planet(4,"Mars", "Red Planet due to its reddish appearance caused by iron oxide (rust) on its surface. It has a thin atmosphere composed mostly of carbon dioxide", 2 ),
# Planet(4, "Pluto", " filled with icy bodies and other small objects. Once considered the ninth planet in the solar system, it was reclassified as a dwarf planet in 2006 due to its size and the fact that it hasn’t cleared its orbit of other debris. Pluto has a rocky core surrounded by a mantle of water ice and a thin atmosphere of nitrogen, methane, and carbon monoxide.", 5),
# Planet(5, "Jupiter","is the largest planet in the solar system, a gas giant composed primarily of hydrogen and helium, known for its Great Red Spot—a massive storm larger than Earth", 92),
# Planet(6, "Saturn","sixth planet from the Sun and is best known for its extensive and stunning ring system, made mostly of ice and rock particles. It is a gas giant composed primarily of hydrogen and helium" , 146),
# Planet(7, "Uranus","is the seventh planet from the Sun, an ice giant with a blue-green color due to the presence of methane in its atmosphere. It is unique for rotating on its side, with an extreme axial tilt of about 98 degrees", 27 ),
# Planet(8, "Neptune", "is a blue ice giant, the eighth planet from the Sun. Known for strong winds and dark storms", 14),
# Planet(9, "Pluto", " a small, icy world in the outer solar system. It has a diverse, frozen landscape featuring a distinctive heart-shaped region", 5 ),
# ]





Comment on lines +25 to +48

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are creating commits as we go, then all of our prior work can be revisited by looking at our code through our git commit history. This means we can and should delete out commented code that we are no longer using, since we can always refer back to that old code.

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

This file was deleted.

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

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

@planets_bp.post("")
def create_planet():
request_body = request.get_json()
name = request_body["name"]
moon= request_body["moon"]
description = request_body["description"]
Comment on lines +10 to +12

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What kind of error could be raised by this code? What's a way we could handle it?


new_planet = Planet(name=name, moon=moon, description=description)
db.session.add(new_planet)
db.session.commit()
response = new_planet.to_dict()
return response, 201

@planets_bp.get("")
def get_all_planets():

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is starting to get long, some considerations could be if there are ways we could move some logic into helper functions or move constants to another file to keep the logic a little more concise.

description_param = request.args.get("description")
moon_param = request.args.get("moon")
moon_op_param = request.args.get("moon_param")
sort_param = request.args.get("sort")

query = db.select(Planet)

if description_param:
query = query.where(Planet.description.like(f"%{description_param}%"))

if moon_param:
try:
moon_count = int(moon_param)
# Dictionary of comparison operators
moon_operators = {
"eq": Planet.moon.__eq__,
"gt": Planet.moon.__gt__,
"lt": Planet.moon.__lt__,
"gte": Planet.moon.__ge__,
"lte": Planet.moon.__le__
}
operator_func = moon_operators.get(moon_op_param, Planet.moon.__eq__)
if operator_func:
query = query.where(operator_func(moon_count))
except ValueError:
return {"message": "Invalid moon parameter"}, 400

sort_options ={
"name": Planet.name,
"name_desc": Planet.name.desc(),
"moon": Planet.moon,
"moon_desc": Planet.moon.desc(),
"id": Planet.id
}

sort_field = sort_options.get(sort_param, Planet.id)
query = query.order_by(sort_field)

planets = db.session.scalars(query).all()
planets_response = [planet.to_dict() for planet in planets]
return planets_response

@planets_bp.get("/<planet_id>")
def get_one_planet(planet_id):
planet = validate_planet_one(planet_id)

return {
"id": planet.id,
"name": planet.name,
"description": planet.description,
"moon": planet.moon
}

@planets_bp.put("/<planet_id>")
def update_planet(planet_id):
planets = Planet.query.all()
planet = validate_planet(planet_id, planets)
Comment on lines +77 to +78

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we use validate_planet_one here instead?

request_body = request.get_json()

planet.name= request_body["name"]
planet.description = request_body["description"]
planet.moon= request_body["moon"]
db.session.commit()

return Response(status=204, mimetype="application/json")

@planets_bp.delete("/<planet_id>")
def delete_planet(planet_id):
planet = validate_planet_one(planet_id)
db.session.delete(planet)
db.session.commit()

return Response(status=204, mimetype="application/json")

def validate_planet(planet_id, planets):
# Narrow the errors - data error, type error
try:
planet_id = int(planet_id)
except:
abort(make_response({"message": f"Planet id {planet_id} invalid"}, 400))

for planet in planets:
if planet.id == planet_id:
return planet

abort(make_response({"message": f"Planet {planet_id} not found"}, 404))


def validate_planet_one(planet_id):

try:
planet_id = int(planet_id)
except:
response = {"message": f"planet {planet_id} invalid"}
abort(make_response(response, 400))

query = db.select(Planet).where(Planet.id == planet_id)
planet = db.session.scalar(query)

if not planet:
response = {"message": f"{planet_id} not found"}
abort(make_response(response, 404))

return planet
Comment on lines +96 to +125

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two functions are duplicating work. How could we remove validate_planet and keep just the validate_planet_one function?

25 changes: 22 additions & 3 deletions coworking_agreement.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,44 @@
# Coworking Agreement
.# Coworking Agreement

Talk through each section with your partner. Add notes on what you discussed and agreed upon in each section. At the bottom, type your names to sign off on your agreement.

## Accessibility Needs
*What does each team member need access to in order to succeed and show up the best they can?*

1- Time and energy
2- Slowness
3- Communication
4- Fallibility

## Collaboration vs. individual work expectations
*Clarify your collaboration expectations- does your group want to write code together all of the time? Or divide work to do independently, then come together to share accomplishments? What tools and technologies can help your collaboration?*
Depends
1- pair programming
2- Independent- when we work independent we Communicate and share our changes via slack or zoom, etc.
3- tools and technologies we used to collaborate is zoom and slack.

## Learning Style
*How does each team member learn best in project settings?*
1- Doing
2- Explaining
3- Researching
4- Coping

## Preferred Feedback Style
*How does each team member best receive feedback?*
- By being honest and open.

## One Team Communication Skill to Improve
*What is a teamwork-related skill you want to work on?*
for Salma
- Speak more
- Repeat the info to make sure that I understand correctly
for Tami
- Speck clear and slowly

## Optional: Other agreements
*Other co-working agreements that were not captured in the above sections.*

## Signatures
______________ _______________
Date: _________
Salma Anany, Tami Gaertner
Date: oct 21,2024
1 change: 1 addition & 0 deletions migrations/README
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Single-database configuration for Flask.
50 changes: 50 additions & 0 deletions migrations/alembic.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# 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,flask_migrate

[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

[logger_flask_migrate]
level = INFO
handlers =
qualname = flask_migrate

[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