From eaec270b0d0a8152dc064b4427fb8336f6fb44a5 Mon Sep 17 00:00:00 2001 From: Tami Date: Fri, 18 Oct 2024 15:06:02 -0400 Subject: [PATCH 01/31] work wave1,create virtual env, dependencies, creat planet class and list of planet instances --- app/models/planet.py | 19 +++++++++++++++++++ app/{ => routes}/routes.py | 0 2 files changed, 19 insertions(+) create mode 100644 app/models/planet.py rename app/{ => routes}/routes.py (100%) diff --git a/app/models/planet.py b/app/models/planet.py new file mode 100644 index 000000000..d0666add8 --- /dev/null +++ b/app/models/planet.py @@ -0,0 +1,19 @@ +class Planet: + def __init__(self,id, name, description, moon): + self.id = id + self.name = name + self.description = description + self.moon = moon + +planet = [ + 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, "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 ), +] + \ No newline at end of file diff --git a/app/routes.py b/app/routes/routes.py similarity index 100% rename from app/routes.py rename to app/routes/routes.py From 99141582fef307062ecd3098cfc46b898f0bfdf1 Mon Sep 17 00:00:00 2001 From: Salma Anany Date: Fri, 18 Oct 2024 20:37:38 -0700 Subject: [PATCH 02/31] wave one --- app/__init__.py | 16 +++++++++++++++- app/models/{planet.py => __init__.py} | 2 +- app/routes/planet_routes.py | 26 ++++++++++++++++++++++++++ app/routes/routes.py | 2 -- coworking_agreement.md | 2 +- 5 files changed, 43 insertions(+), 5 deletions(-) rename app/models/{planet.py => __init__.py} (99%) create mode 100644 app/routes/planet_routes.py delete mode 100644 app/routes/routes.py diff --git a/app/__init__.py b/app/__init__.py index 70b4cabfe..52a5d9c97 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,7 +1,21 @@ +from distutils.command.build_py import build_py + from flask import Flask +from .routes.planet_routes import planets_bp +# from .models.planet import Planet +# from .routes.planet_routes import planets_bp def create_app(test_config=None): app = Flask(__name__) - + app.register_blueprint(planets_bp) return app + + +def main(): + app = create_app() + app.run() + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/app/models/planet.py b/app/models/__init__.py similarity index 99% rename from app/models/planet.py rename to app/models/__init__.py index d0666add8..c181d4958 100644 --- a/app/models/planet.py +++ b/app/models/__init__.py @@ -5,7 +5,7 @@ def __init__(self,id, name, description, moon): self.description = description self.moon = moon -planet = [ +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, "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 ), diff --git a/app/routes/planet_routes.py b/app/routes/planet_routes.py new file mode 100644 index 000000000..1b67416d4 --- /dev/null +++ b/app/routes/planet_routes.py @@ -0,0 +1,26 @@ + +from flask import Blueprint +from app.models import planets +# from ..models.planet import Planet + +planets_bp = Blueprint("planets_bp", __name__, url_prefix="/planets") + +@planets_bp.get("", strict_slashes=False) + +def get_all_planet(): + result_list = [] + + for planet in planets: + result_list.append( + { + "id":planet.id, + "name":planet.name, + "description":planet.description, + "moon":planet.moon + + } + ) + return result_list + + + diff --git a/app/routes/routes.py b/app/routes/routes.py deleted file mode 100644 index 8e9dfe684..000000000 --- a/app/routes/routes.py +++ /dev/null @@ -1,2 +0,0 @@ -from flask import Blueprint - diff --git a/coworking_agreement.md b/coworking_agreement.md index 463598c27..1baa67813 100644 --- a/coworking_agreement.md +++ b/coworking_agreement.md @@ -1,4 +1,4 @@ -# 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. From b432ba2e0169cd9c026fd938784b06e0b50d63b0 Mon Sep 17 00:00:00 2001 From: Tami Date: Sat, 19 Oct 2024 22:10:01 -0400 Subject: [PATCH 03/31] work wave 2- get one existing planet and 404, 400 response. --- app/__init__.py | 3 ++- app/models/__init__.py | 3 ++- app/routes/planet_routes.py | 30 +++++++++++++++++++++++++++++- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/app/__init__.py b/app/__init__.py index 52a5d9c97..6b9b6c659 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,4 +1,4 @@ -from distutils.command.build_py import build_py +# from distutils.command.build_py import build_py from flask import Flask from .routes.planet_routes import planets_bp @@ -18,4 +18,5 @@ def main(): if __name__ == "__main__": + main() \ No newline at end of file diff --git a/app/models/__init__.py b/app/models/__init__.py index c181d4958..b7fabd3eb 100644 --- a/app/models/__init__.py +++ b/app/models/__init__.py @@ -8,7 +8,8 @@ def __init__(self,id, name, description, 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, "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(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), diff --git a/app/routes/planet_routes.py b/app/routes/planet_routes.py index 1b67416d4..2a7ce0914 100644 --- a/app/routes/planet_routes.py +++ b/app/routes/planet_routes.py @@ -1,5 +1,5 @@ -from flask import Blueprint +from flask import Blueprint, abort, make_response from app.models import planets # from ..models.planet import Planet @@ -23,4 +23,32 @@ def get_all_planet(): return result_list +@planets_bp.get("/") +def get_one_planet(planet_id): + planet = validate_planet(planet_id) + # planet_id = int(planet_id) + + for planet in planets: + if planet_id == planet_id: + return[{ + "id": planet.id, + "name": planet.name, + "description": planet.description, + "moon": planet.moon + }] + return {"message": f"planet {planet_id} not found"}, 404 + +def validate_planet(planet_id): + try: + planet_id = int(planet_id) + except: + response = {"messsage": f"Planet {planet_id} invalid"} + abort(make_response(response,400)) + + for planet in planets: + if planet.id == planet_id: + return planet + + response = {"message": f"planet {planet_id} not found"} + abort(make_response(response, 404)) \ No newline at end of file From f9ab1f38a84233ff27ca45e973679558f7183b28 Mon Sep 17 00:00:00 2001 From: Salma Anany Date: Sun, 20 Oct 2024 18:46:37 -0700 Subject: [PATCH 04/31] removing manual convert to dict --- app/routes/planet_routes.py | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/app/routes/planet_routes.py b/app/routes/planet_routes.py index 2a7ce0914..6970e17d8 100644 --- a/app/routes/planet_routes.py +++ b/app/routes/planet_routes.py @@ -11,15 +11,7 @@ def get_all_planet(): result_list = [] for planet in planets: - result_list.append( - { - "id":planet.id, - "name":planet.name, - "description":planet.description, - "moon":planet.moon - - } - ) + result_list.append(planet.__dict__) return result_list @@ -31,19 +23,14 @@ def get_one_planet(planet_id): for planet in planets: if planet_id == planet_id: - return[{ - "id": planet.id, - "name": planet.name, - "description": planet.description, - "moon": planet.moon - }] + return planet.__dict__ return {"message": f"planet {planet_id} not found"}, 404 def validate_planet(planet_id): try: planet_id = int(planet_id) except: - response = {"messsage": f"Planet {planet_id} invalid"} + response = {"message": f"Planet {planet_id} invalid"} abort(make_response(response,400)) for planet in planets: From 458170ade90d29a5b7f5ff90417049c738064369 Mon Sep 17 00:00:00 2001 From: Salma Anany Date: Sun, 20 Oct 2024 18:50:59 -0700 Subject: [PATCH 05/31] Found the bug Tami! --- app/routes/planet_routes.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/routes/planet_routes.py b/app/routes/planet_routes.py index 6970e17d8..d425f394a 100644 --- a/app/routes/planet_routes.py +++ b/app/routes/planet_routes.py @@ -22,6 +22,7 @@ def get_one_planet(planet_id): # planet_id = int(planet_id) for planet in planets: + # This is the bug Tami!, planet_id is always going to be planet id if planet_id == planet_id: return planet.__dict__ return {"message": f"planet {planet_id} not found"}, 404 @@ -30,7 +31,7 @@ def validate_planet(planet_id): try: planet_id = int(planet_id) except: - response = {"message": f"Planet {planet_id} invalid"} + response = {"messsage": f"Planet {planet_id} invalid"} abort(make_response(response,400)) for planet in planets: From 586f72c4afb925a4b6c537cc89fc619b6aa7b7fc Mon Sep 17 00:00:00 2001 From: Salma Anany Date: Sun, 20 Oct 2024 18:52:17 -0700 Subject: [PATCH 06/31] Refactor the validate function --- app/routes/planet_routes.py | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/app/routes/planet_routes.py b/app/routes/planet_routes.py index d425f394a..b9faccd3a 100644 --- a/app/routes/planet_routes.py +++ b/app/routes/planet_routes.py @@ -18,25 +18,15 @@ def get_all_planet(): @planets_bp.get("/") def get_one_planet(planet_id): - planet = validate_planet(planet_id) - # planet_id = int(planet_id) - - for planet in planets: - # This is the bug Tami!, planet_id is always going to be planet id - if planet_id == planet_id: - return planet.__dict__ - return {"message": f"planet {planet_id} not found"}, 404 - -def validate_planet(planet_id): try: planet_id = int(planet_id) except: - response = {"messsage": f"Planet {planet_id} invalid"} - abort(make_response(response,400)) - + response = {"message": f"Planet {planet_id} invalid"} + abort(make_response(response, 400)) + for planet in planets: if planet.id == planet_id: - return planet - + return planet.__dict__ + response = {"message": f"planet {planet_id} not found"} abort(make_response(response, 404)) \ No newline at end of file From 0b2d368d8ab9a2893b6979adc506b19031441a7c Mon Sep 17 00:00:00 2001 From: Salma Anany Date: Sun, 20 Oct 2024 18:54:40 -0700 Subject: [PATCH 07/31] clean up the try and catch, to a if check --- app/routes/planet_routes.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/app/routes/planet_routes.py b/app/routes/planet_routes.py index b9faccd3a..489911889 100644 --- a/app/routes/planet_routes.py +++ b/app/routes/planet_routes.py @@ -1,7 +1,5 @@ - from flask import Blueprint, abort, make_response from app.models import planets -# from ..models.planet import Planet planets_bp = Blueprint("planets_bp", __name__, url_prefix="/planets") @@ -9,21 +7,16 @@ def get_all_planet(): result_list = [] - for planet in planets: result_list.append(planet.__dict__) return result_list @planets_bp.get("/") - def get_one_planet(planet_id): - try: - planet_id = int(planet_id) - except: + if not planet_id.isnumeric(): response = {"message": f"Planet {planet_id} invalid"} abort(make_response(response, 400)) - for planet in planets: if planet.id == planet_id: return planet.__dict__ From 3ba5c57729141c616e5f6be8dcf804a7e06c5521 Mon Sep 17 00:00:00 2001 From: Salma Anany Date: Sun, 20 Oct 2024 18:56:32 -0700 Subject: [PATCH 08/31] clean up the try and catch, to a if check --- app/routes/planet_routes.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/routes/planet_routes.py b/app/routes/planet_routes.py index 489911889..31d91919d 100644 --- a/app/routes/planet_routes.py +++ b/app/routes/planet_routes.py @@ -17,8 +17,9 @@ def get_one_planet(planet_id): if not planet_id.isnumeric(): response = {"message": f"Planet {planet_id} invalid"} abort(make_response(response, 400)) + for planet in planets: - if planet.id == planet_id: + if planet.id == int(planet_id): return planet.__dict__ response = {"message": f"planet {planet_id} not found"} From 060a092e78e01bf3caea45b1324e55ec1e3b8093 Mon Sep 17 00:00:00 2001 From: Salma Anany Date: Sun, 20 Oct 2024 18:58:01 -0700 Subject: [PATCH 09/31] clean up the try and catch, to a if check --- app/routes/planet_routes.py | 1 - 1 file changed, 1 deletion(-) diff --git a/app/routes/planet_routes.py b/app/routes/planet_routes.py index 31d91919d..1c067cba1 100644 --- a/app/routes/planet_routes.py +++ b/app/routes/planet_routes.py @@ -4,7 +4,6 @@ planets_bp = Blueprint("planets_bp", __name__, url_prefix="/planets") @planets_bp.get("", strict_slashes=False) - def get_all_planet(): result_list = [] for planet in planets: From 9c30a4d6835af022f17a615172496d850366417a Mon Sep 17 00:00:00 2001 From: Salma Anany Date: Mon, 21 Oct 2024 12:04:25 -0700 Subject: [PATCH 10/31] clean up the try and catch, to a if check --- ...an_up_the_try_and_catch__to_a_if_check.xml | 4 +++ app/routes/planet_routes.py | 33 +++++++++++++++---- coworking_agreement.md | 23 +++++++++++-- 3 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 .idea/shelf/clean_up_the_try_and_catch__to_a_if_check.xml diff --git a/.idea/shelf/clean_up_the_try_and_catch__to_a_if_check.xml b/.idea/shelf/clean_up_the_try_and_catch__to_a_if_check.xml new file mode 100644 index 000000000..3103b921c --- /dev/null +++ b/.idea/shelf/clean_up_the_try_and_catch__to_a_if_check.xml @@ -0,0 +1,4 @@ + + \ No newline at end of file diff --git a/app/routes/planet_routes.py b/app/routes/planet_routes.py index 1c067cba1..478b66114 100644 --- a/app/routes/planet_routes.py +++ b/app/routes/planet_routes.py @@ -3,23 +3,44 @@ planets_bp = Blueprint("planets_bp", __name__, url_prefix="/planets") -@planets_bp.get("", strict_slashes=False) +@planets_bp.get("") def get_all_planet(): result_list = [] for planet in planets: + # .__dict__ to return any object to dict result_list.append(planet.__dict__) return result_list @planets_bp.get("/") def get_one_planet(planet_id): - if not planet_id.isnumeric(): - response = {"message": f"Planet {planet_id} invalid"} - abort(make_response(response, 400)) + planet = validate_planet(planet_id) for planet in planets: if planet.id == int(planet_id): return planet.__dict__ - response = {"message": f"planet {planet_id} not found"} - abort(make_response(response, 404)) \ No newline at end of file +def validate_planet(planet_id): + try: + planet_id = int(planet_id) + + except: + abort(make_response( {"message": f"planet {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)) + + + + # if not planet_id.isnumeric(): + # response = {"message": f"Planet {planet_id} invalid"} + # abort(make_response(response, 400)) + # + # for planet in planets: + # if planet.id == int(planet_id): + # return planet.__dict__ + # + # response = {"message": f"planet {planet_id} not found"} + # abort(make_response(response, 404)) \ No newline at end of file diff --git a/coworking_agreement.md b/coworking_agreement.md index 1baa67813..b24cc7b91 100644 --- a/coworking_agreement.md +++ b/coworking_agreement.md @@ -5,21 +5,40 @@ Talk through each section with your partner. Add notes on what you discussed and ## 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 From 48adb54af5858aeece3003c177db07139c760346 Mon Sep 17 00:00:00 2001 From: Salma Anany Date: Mon, 21 Oct 2024 12:04:25 -0700 Subject: [PATCH 11/31] clean up the try and catch, to a if check --- ...an_up_the_try_and_catch__to_a_if_check.xml | 4 +++ app/routes/planet_routes.py | 33 +++++++++++++++---- coworking_agreement.md | 23 +++++++++++-- 3 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 .idea/shelf/clean_up_the_try_and_catch__to_a_if_check.xml diff --git a/.idea/shelf/clean_up_the_try_and_catch__to_a_if_check.xml b/.idea/shelf/clean_up_the_try_and_catch__to_a_if_check.xml new file mode 100644 index 000000000..3103b921c --- /dev/null +++ b/.idea/shelf/clean_up_the_try_and_catch__to_a_if_check.xml @@ -0,0 +1,4 @@ + + \ No newline at end of file diff --git a/app/routes/planet_routes.py b/app/routes/planet_routes.py index 1c067cba1..478b66114 100644 --- a/app/routes/planet_routes.py +++ b/app/routes/planet_routes.py @@ -3,23 +3,44 @@ planets_bp = Blueprint("planets_bp", __name__, url_prefix="/planets") -@planets_bp.get("", strict_slashes=False) +@planets_bp.get("") def get_all_planet(): result_list = [] for planet in planets: + # .__dict__ to return any object to dict result_list.append(planet.__dict__) return result_list @planets_bp.get("/") def get_one_planet(planet_id): - if not planet_id.isnumeric(): - response = {"message": f"Planet {planet_id} invalid"} - abort(make_response(response, 400)) + planet = validate_planet(planet_id) for planet in planets: if planet.id == int(planet_id): return planet.__dict__ - response = {"message": f"planet {planet_id} not found"} - abort(make_response(response, 404)) \ No newline at end of file +def validate_planet(planet_id): + try: + planet_id = int(planet_id) + + except: + abort(make_response( {"message": f"planet {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)) + + + + # if not planet_id.isnumeric(): + # response = {"message": f"Planet {planet_id} invalid"} + # abort(make_response(response, 400)) + # + # for planet in planets: + # if planet.id == int(planet_id): + # return planet.__dict__ + # + # response = {"message": f"planet {planet_id} not found"} + # abort(make_response(response, 404)) \ No newline at end of file diff --git a/coworking_agreement.md b/coworking_agreement.md index 1baa67813..b24cc7b91 100644 --- a/coworking_agreement.md +++ b/coworking_agreement.md @@ -5,21 +5,40 @@ Talk through each section with your partner. Add notes on what you discussed and ## 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 From 5947424a1271bdb4b8806bd2ba2f13ebdfc60e2f Mon Sep 17 00:00:00 2001 From: Salma Anany Date: Mon, 21 Oct 2024 12:26:37 -0700 Subject: [PATCH 12/31] Wave Two completed --- app/routes/planet_routes.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/app/routes/planet_routes.py b/app/routes/planet_routes.py index 478b66114..ad049dd79 100644 --- a/app/routes/planet_routes.py +++ b/app/routes/planet_routes.py @@ -7,7 +7,6 @@ def get_all_planet(): result_list = [] for planet in planets: - # .__dict__ to return any object to dict result_list.append(planet.__dict__) return result_list @@ -33,14 +32,3 @@ def validate_planet(planet_id): abort(make_response({"message": f"planet {planet_id} not found"}, 404)) - - # if not planet_id.isnumeric(): - # response = {"message": f"Planet {planet_id} invalid"} - # abort(make_response(response, 400)) - # - # for planet in planets: - # if planet.id == int(planet_id): - # return planet.__dict__ - # - # response = {"message": f"planet {planet_id} not found"} - # abort(make_response(response, 404)) \ No newline at end of file From 8d8c5c70ca04f4e1141558e58d52ffa0e367924a Mon Sep 17 00:00:00 2001 From: Salma Anany Date: Mon, 21 Oct 2024 12:28:00 -0700 Subject: [PATCH 13/31] Wave Two completed --- app/routes/planet_routes.py | 1 + 1 file changed, 1 insertion(+) diff --git a/app/routes/planet_routes.py b/app/routes/planet_routes.py index ad049dd79..929c04cf8 100644 --- a/app/routes/planet_routes.py +++ b/app/routes/planet_routes.py @@ -32,3 +32,4 @@ def validate_planet(planet_id): abort(make_response({"message": f"planet {planet_id} not found"}, 404)) + From f9a58bcaf690fc4a255713230c2a691556055d7d Mon Sep 17 00:00:00 2001 From: Salma Anany Date: Fri, 25 Oct 2024 14:43:15 -0700 Subject: [PATCH 14/31] Wave Two completed --- app/__init__.py | 26 +++++++++---------- app/models/__init__.py | 20 -------------- app/models/__init__py | 0 app/models/planet.py | 48 ++++++++++++++++++++++++++++++++++ app/routes/planet_routes.py | 49 +++++++++++++++++++---------------- project-directions/wave_03.md | 1 + requirements.txt | 14 ++++++++-- 7 files changed, 99 insertions(+), 59 deletions(-) delete mode 100644 app/models/__init__.py create mode 100644 app/models/__init__py create mode 100644 app/models/planet.py diff --git a/app/__init__.py b/app/__init__.py index 6b9b6c659..e05988c5c 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,22 +1,20 @@ -# from distutils.command.build_py import build_py - from flask import Flask from .routes.planet_routes import planets_bp +from .db import db, migrate +from .models import planet -# from .models.planet import Planet -# from .routes.planet_routes import planets_bp - -def create_app(test_config=None): +def create_app(): + # __name__ stores the name of the module we're in app = Flask(__name__) - app.register_blueprint(planets_bp) - return app + app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False + app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql+psycopg2://postgres:postgres@localhost:5432/planet' -def main(): - app = create_app() - app.run() + db.init_app(app) + migrate.init_app(app, db) + + app.register_blueprint(planets_bp) + + return app -if __name__ == "__main__": - - main() \ No newline at end of file diff --git a/app/models/__init__.py b/app/models/__init__.py deleted file mode 100644 index b7fabd3eb..000000000 --- a/app/models/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -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 ), -] - \ No newline at end of file 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..6773fd164 --- /dev/null +++ b/app/models/planet.py @@ -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, + color=self.description, + personality=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 ), +# ] + + + + + diff --git a/app/routes/planet_routes.py b/app/routes/planet_routes.py index 929c04cf8..64565f840 100644 --- a/app/routes/planet_routes.py +++ b/app/routes/planet_routes.py @@ -1,35 +1,38 @@ -from flask import Blueprint, abort, make_response -from app.models import planets +from flask import Blueprint, abort, make_response, request +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"] + color = request_body["color"] + personality = request_body["personality"] + + new_planet = Planet(name=name, color=color, personality=personality) + db.session.add(new_planet) + db.session.commit() + response = new_planet.to_dict() + return response, 201 @planets_bp.get("") -def get_all_planet(): - result_list = [] - for planet in planets: - result_list.append(planet.__dict__) - return result_list - - -@planets_bp.get("/") -def get_one_planet(planet_id): - - planet = validate_planet(planet_id) - for planet in planets: - if planet.id == int(planet_id): - return planet.__dict__ - -def validate_planet(planet_id): +def get_all_planets(): + query = db.select(Planet).order_by(Planet.id) + planets = db.session.scalars(query) + + planets_response = [planet.to_dict() for planet in planets] + return planets_response +# +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 {planet_id} invalid"}, 400)) + abort(make_response({"message": f"Cat 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)) - - + abort(make_response({"message": f"Cat {planet_id} not found"}, 404)) \ No newline at end of file diff --git a/project-directions/wave_03.md b/project-directions/wave_03.md index f4128d650..fdbe8c705 100644 --- a/project-directions/wave_03.md +++ b/project-directions/wave_03.md @@ -18,3 +18,4 @@ As a client, I want to send a request... 1. ...with new valid `planet` data and get a success response, so that I know the API saved the planet data 1. ...to get all existing `planets`, so that I can see a list of planets, with their `id`, `name`, `description`, and other data of the `planet`. + diff --git a/requirements.txt b/requirements.txt index 24c7e56f8..bd4b5d142 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,17 +1,24 @@ alembic==1.13.1 autopep8==1.5.5 -blinker==1.7 +blinker==1.7.0 certifi==2020.12.5 chardet==4.0.0 click==8.1.7 +coverage==7.6.3 +exceptiongroup==1.2.2 Flask==3.0.2 Flask-Migrate==4.0.5 Flask-SQLAlchemy==3.1.1 idna==2.10 +importlib_metadata==8.5.0 +iniconfig==2.0.0 itsdangerous==2.1.2 Jinja2==3.1.3 Mako==1.1.4 MarkupSafe==2.1.5 +packaging==24.1 +pluggy==1.5.0 +psycopg2==2.9.10 psycopg2-binary==2.9.9 pycodestyle==2.6.0 pytest==8.0.0 @@ -23,5 +30,8 @@ requests==2.25.1 six==1.15.0 SQLAlchemy==2.0.25 toml==0.10.2 +tomli==2.0.2 +typing_extensions==4.12.2 urllib3==1.26.4 -Werkzeug==3.0.1 \ No newline at end of file +Werkzeug==3.0.1 +zipp==3.20.2 From b718e48a84bb732d8da3da59c7946777c392ae81 Mon Sep 17 00:00:00 2001 From: Salma Anany Date: Fri, 25 Oct 2024 14:43:33 -0700 Subject: [PATCH 15/31] Wave There completed --- app/db.py | 7 ++ app/models/base.py | 4 + migrations/README | 1 + migrations/alembic.ini | 50 ++++++++ migrations/env.py | 113 ++++++++++++++++++ migrations/script.py.mako | 24 ++++ .../4294dced1c4c_adds_planet_model.py | 42 +++++++ 7 files changed, 241 insertions(+) create mode 100644 app/db.py create mode 100644 app/models/base.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/4294dced1c4c_adds_planet_model.py diff --git a/app/db.py b/app/db.py new file mode 100644 index 000000000..e9b3927cb --- /dev/null +++ b/app/db.py @@ -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() + diff --git a/app/models/base.py b/app/models/base.py new file mode 100644 index 000000000..227841686 --- /dev/null +++ b/app/models/base.py @@ -0,0 +1,4 @@ +from sqlalchemy.orm import DeclarativeBase + +class Base(DeclarativeBase): + pass \ No newline at end of file diff --git a/migrations/README b/migrations/README new file mode 100644 index 000000000..0e0484415 --- /dev/null +++ b/migrations/README @@ -0,0 +1 @@ +Single-database configuration for Flask. diff --git a/migrations/alembic.ini b/migrations/alembic.ini new file mode 100644 index 000000000..ec9d45c26 --- /dev/null +++ b/migrations/alembic.ini @@ -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 diff --git a/migrations/env.py b/migrations/env.py new file mode 100644 index 000000000..4c9709271 --- /dev/null +++ b/migrations/env.py @@ -0,0 +1,113 @@ +import logging +from logging.config import fileConfig + +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') + + +def get_engine(): + try: + # this works with Flask-SQLAlchemy<3 and Alchemical + return current_app.extensions['migrate'].db.get_engine() + except (TypeError, AttributeError): + # this works with Flask-SQLAlchemy>=3 + return current_app.extensions['migrate'].db.engine + + +def get_engine_url(): + try: + return get_engine().url.render_as_string(hide_password=False).replace( + '%', '%%') + except AttributeError: + return str(get_engine().url).replace('%', '%%') + + +# 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', get_engine_url()) +target_db = current_app.extensions['migrate'].db + +# 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 get_metadata(): + if hasattr(target_db, 'metadatas'): + return target_db.metadatas[None] + return target_db.metadata + + +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=get_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.') + + conf_args = current_app.extensions['migrate'].configure_args + if conf_args.get("process_revision_directives") is None: + conf_args["process_revision_directives"] = process_revision_directives + + connectable = get_engine() + + with connectable.connect() as connection: + context.configure( + connection=connection, + target_metadata=get_metadata(), + **conf_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/4294dced1c4c_adds_planet_model.py b/migrations/versions/4294dced1c4c_adds_planet_model.py new file mode 100644 index 000000000..9717b4491 --- /dev/null +++ b/migrations/versions/4294dced1c4c_adds_planet_model.py @@ -0,0 +1,42 @@ +"""adds Planet model + +Revision ID: 4294dced1c4c +Revises: c72d9c7a8b07 +Create Date: 2024-10-25 13:10:11.729115 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '4294dced1c4c' +down_revision = 'c72d9c7a8b07' +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(), nullable=False), + sa.Column('description', sa.String(), nullable=False), + sa.Column('moon', sa.Integer(), nullable=False), + sa.PrimaryKeyConstraint('id') + ) + op.drop_table('planets') + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('planets', + sa.Column('id', sa.INTEGER(), sa.Identity(always=False, start=1, increment=1, minvalue=1, maxvalue=2147483647, cycle=False, cache=1), autoincrement=True, nullable=False), + sa.Column('name', sa.TEXT(), autoincrement=False, nullable=False), + sa.Column('description', sa.TEXT(), autoincrement=False, nullable=False), + sa.Column('moon', sa.INTEGER(), autoincrement=False, nullable=True), + sa.PrimaryKeyConstraint('id', name='planets_pkey') + ) + op.drop_table('planet') + # ### end Alembic commands ### From 8152076fcbadc6300864a25de60791c5cf43cade Mon Sep 17 00:00:00 2001 From: Tami Date: Fri, 25 Oct 2024 18:51:05 -0400 Subject: [PATCH 16/31] added info to planet.py --- app/__init__.py | 1 + app/models/planet.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/__init__.py b/app/__init__.py index e05988c5c..7294c7ba7 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -13,6 +13,7 @@ def create_app(): db.init_app(app) migrate.init_app(app, db) + app.register_blueprint(planets_bp) return app diff --git a/app/models/planet.py b/app/models/planet.py index 6773fd164..938ea049d 100644 --- a/app/models/planet.py +++ b/app/models/planet.py @@ -12,8 +12,8 @@ def to_dict(self): return dict( id=self.id, name=self.name, - color=self.description, - personality=self.moon + descripction=self.description, + moon=self.moon ) From 3876ed1c176791c98ceac91d31b844091f038180 Mon Sep 17 00:00:00 2001 From: Tami Date: Fri, 25 Oct 2024 18:53:17 -0400 Subject: [PATCH 17/31] fixed spelling --- 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 938ea049d..43e26c668 100644 --- a/app/models/planet.py +++ b/app/models/planet.py @@ -12,7 +12,7 @@ def to_dict(self): return dict( id=self.id, name=self.name, - descripction=self.description, + description=self.description, moon=self.moon ) From 27b45956312636aff1d7f4f1bedbd8357fbd69ca Mon Sep 17 00:00:00 2001 From: Salma Anany Date: Sun, 27 Oct 2024 09:34:44 -0700 Subject: [PATCH 18/31] Wave There completed --- app/routes/planet_routes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/routes/planet_routes.py b/app/routes/planet_routes.py index 64565f840..e913b3360 100644 --- a/app/routes/planet_routes.py +++ b/app/routes/planet_routes.py @@ -9,9 +9,9 @@ def create_planet(): request_body = request.get_json() name = request_body["name"] color = request_body["color"] - personality = request_body["personality"] + description = request_body["description"] - new_planet = Planet(name=name, color=color, personality=personality) + new_planet = Planet(name=name, color=color, description=description) db.session.add(new_planet) db.session.commit() response = new_planet.to_dict() From 15f540a2e3b60881217f914a285bec3243d86158 Mon Sep 17 00:00:00 2001 From: Salma Anany Date: Sun, 27 Oct 2024 12:01:37 -0700 Subject: [PATCH 19/31] working on wave four: read one planet and update --- app/routes/planet_routes.py | 56 ++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/app/routes/planet_routes.py b/app/routes/planet_routes.py index e913b3360..fbe0ffb1f 100644 --- a/app/routes/planet_routes.py +++ b/app/routes/planet_routes.py @@ -1,4 +1,4 @@ -from flask import Blueprint, abort, make_response, request +from flask import Blueprint, abort, make_response, request, Response from ..db import db from app.models.planet import Planet @@ -23,16 +23,64 @@ def get_all_planets(): planets_response = [planet.to_dict() for planet in planets] return planets_response -# + +@planets_bp.get("/") +def get_one_planet(planet_id): + planet = validate_planet_one(planet_id) + # query = db.select(Planet).where(Planet.id == planet_id) + # planet = db.session.scalar(query) + + + return { + "id": planet_id, + "name": planet.name, + "description": planet.description, + "moon": planet.moon + } + +@planets_bp.put("/") +def update_planet(planet_id): + # print("Content-Type:", request.headers.get('Content-Type')) + planets = Planet.query.all() + planet = validate_planet(planet_id, planets) + 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") + + + 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"Cat id {planet_id} invalid"}, 400)) + 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"Cat {planet_id} not found"}, 404)) \ No newline at end of file + 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 \ No newline at end of file From 8bc777e6ca2880f849b19b964afb3e8f389ba28c Mon Sep 17 00:00:00 2001 From: Tami Date: Sun, 27 Oct 2024 17:37:09 -0400 Subject: [PATCH 20/31] fix bug with update function, work delete function --- app/routes/planet_routes.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/routes/planet_routes.py b/app/routes/planet_routes.py index fbe0ffb1f..2c4111148 100644 --- a/app/routes/planet_routes.py +++ b/app/routes/planet_routes.py @@ -40,7 +40,6 @@ def get_one_planet(planet_id): @planets_bp.put("/") def update_planet(planet_id): - # print("Content-Type:", request.headers.get('Content-Type')) planets = Planet.query.all() planet = validate_planet(planet_id, planets) request_body = request.get_json() @@ -52,6 +51,13 @@ def update_planet(planet_id): return Response(status=204, mimetype="application/json") +@planets_bp.delete("/") +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): From af913c567ab53d7fbc29ff1ae64ed168abfd3847 Mon Sep 17 00:00:00 2001 From: Tami Date: Sun, 27 Oct 2024 18:31:58 -0400 Subject: [PATCH 21/31] work wave 5 retrieve description --- app/routes/planet_routes.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/routes/planet_routes.py b/app/routes/planet_routes.py index 2c4111148..3551eba5a 100644 --- a/app/routes/planet_routes.py +++ b/app/routes/planet_routes.py @@ -18,7 +18,14 @@ def create_planet(): return response, 201 @planets_bp.get("") def get_all_planets(): + description_param = request.args.get("description") + if description_param: + query = db.select(Planet).where(Planet.description.like(f"%{description_param}%")).order_by(Planet.id) + + else: + query = db.select(Planet).order_by(Planet.id) query = db.select(Planet).order_by(Planet.id) + planets = db.session.scalars(query) planets_response = [planet.to_dict() for planet in planets] From 2f8cabd368cba850961f29955c7df86d23ff562e Mon Sep 17 00:00:00 2001 From: Tami Date: Sun, 27 Oct 2024 18:53:17 -0400 Subject: [PATCH 22/31] work on adding moon to the request --- app/routes/planet_routes.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/app/routes/planet_routes.py b/app/routes/planet_routes.py index 3551eba5a..a6717c9ec 100644 --- a/app/routes/planet_routes.py +++ b/app/routes/planet_routes.py @@ -19,15 +19,21 @@ def create_planet(): @planets_bp.get("") def get_all_planets(): description_param = request.args.get("description") + moon_param = request.args.get("moon") + + query = db.select(Planet) + if description_param: query = db.select(Planet).where(Planet.description.like(f"%{description_param}%")).order_by(Planet.id) - - else: - query = db.select(Planet).order_by(Planet.id) - query = db.select(Planet).order_by(Planet.id) + if moon_param: + query = query.where(Planet.moon == int(moon_param)) + + query = query.order_by(Planet.id) + # else: + # query = db.select(Planet).order_by(Planet.id) + planets = db.session.scalars(query) - planets_response = [planet.to_dict() for planet in planets] return planets_response From c55376cb6e738459e0b041efbeece31572d64154 Mon Sep 17 00:00:00 2001 From: Tami Date: Mon, 28 Oct 2024 20:12:51 -0400 Subject: [PATCH 23/31] added sort and fixed moon and desc param --- app/routes/planet_routes.py | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/app/routes/planet_routes.py b/app/routes/planet_routes.py index a6717c9ec..7309c6fdb 100644 --- a/app/routes/planet_routes.py +++ b/app/routes/planet_routes.py @@ -16,24 +16,39 @@ def create_planet(): db.session.commit() response = new_planet.to_dict() return response, 201 + @planets_bp.get("") def get_all_planets(): description_param = request.args.get("description") moon_param = request.args.get("moon") + sort_param = request.args.get("sort") query = db.select(Planet) + # changed the desc param if description_param: - query = db.select(Planet).where(Planet.description.like(f"%{description_param}%")).order_by(Planet.id) - + query = query.where(Planet.description.like(f"%{description_param}%")) if moon_param: - query = query.where(Planet.moon == int(moon_param)) - - query = query.order_by(Planet.id) - # else: - # query = db.select(Planet).order_by(Planet.id) + try: + moon_count = int(moon_param) + query = query.where(Planet.moon == moon_count) + except ValueError: + return {"message": "Invalid moon parameter"}, 400 - planets = db.session.scalars(query) + # Apply Sort + 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) + + #execute query + planets = db.session.scalars(query).all() planets_response = [planet.to_dict() for planet in planets] return planets_response From 2a2291849cd475397a3af62d5bd5c724837e8013 Mon Sep 17 00:00:00 2001 From: Salma Anany Date: Mon, 28 Oct 2024 21:29:30 -0700 Subject: [PATCH 24/31] fixing the moon query using __eq__ instead of == wave 5 completed!! --- app/routes/planet_routes.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/routes/planet_routes.py b/app/routes/planet_routes.py index 7309c6fdb..7712fc942 100644 --- a/app/routes/planet_routes.py +++ b/app/routes/planet_routes.py @@ -31,7 +31,7 @@ def get_all_planets(): if moon_param: try: moon_count = int(moon_param) - query = query.where(Planet.moon == moon_count) + query = query.where(Planet.moon.__eq__(moon_count)) except ValueError: return {"message": "Invalid moon parameter"}, 400 @@ -55,8 +55,6 @@ def get_all_planets(): @planets_bp.get("/") def get_one_planet(planet_id): planet = validate_planet_one(planet_id) - # query = db.select(Planet).where(Planet.id == planet_id) - # planet = db.session.scalar(query) return { From c4a651fae5fc55737a016b533ccf64dfd12e1cdf Mon Sep 17 00:00:00 2001 From: Salma Anany Date: Tue, 29 Oct 2024 23:02:13 -0700 Subject: [PATCH 25/31] working on wave 6 (fixture) --- app/__init__.py | 17 ++++++++++++++--- app/models/base.py | 3 ++- app/routes/planet_routes.py | 1 + 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/app/__init__.py b/app/__init__.py index 7294c7ba7..6891a1298 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,14 +1,26 @@ +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(): +def create_app(config=None): # __name__ stores the name of the module we're in app = Flask(__name__) + # the base conf app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False - app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql+psycopg2://postgres:postgres@localhost:5432/planet' + + # app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql+psycopg2://postgres:postgres@localhost:5432/planet' + + 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') + db.init_app(app) migrate.init_app(app, db) @@ -18,4 +30,3 @@ def create_app(): return app - diff --git a/app/models/base.py b/app/models/base.py index 227841686..d4c131f33 100644 --- a/app/models/base.py +++ b/app/models/base.py @@ -1,4 +1,5 @@ from sqlalchemy.orm import DeclarativeBase class Base(DeclarativeBase): - pass \ No newline at end of file + pass + diff --git a/app/routes/planet_routes.py b/app/routes/planet_routes.py index 7712fc942..f2145d883 100644 --- a/app/routes/planet_routes.py +++ b/app/routes/planet_routes.py @@ -19,6 +19,7 @@ def create_planet(): @planets_bp.get("") def get_all_planets(): + # return make_response("I'm a teapot!", 200) description_param = request.args.get("description") moon_param = request.args.get("moon") sort_param = request.args.get("sort") From f7fe0b6e0ddc5d03d9e7fe3f137f8081873d6f2f Mon Sep 17 00:00:00 2001 From: Salma Anany Date: Tue, 29 Oct 2024 23:05:22 -0700 Subject: [PATCH 26/31] working on wave 6 (fixture) --- tests/__init__.py | 0 tests/conftest.py | 32 ++++++++++++++++++++++++++++++++ tests/test_routes.py | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 tests/__init__.py create mode 100644 tests/conftest.py create mode 100644 tests/test_routes.py diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 000000000..c5e0bddf5 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,32 @@ +import pytest +from app import create_app +from app.db import db +from flask.signals import request_finished +from dotenv import load_dotenv +import os + +load_dotenv() + +@pytest.fixture +def app(): + test_config = { + "TESTING": True, + "SQLALCHEMY_DATABASE_URI": os.environ.get('SQLALCHEMY_TEST_DATABASE_URI') + } + app = create_app(test_config) + + @request_finished.connect_via(app) + def expire_session(sender, response, **extra): + db.session.remove() + + with app.app_context(): + db.create_all() + yield app + + with app.app_context(): + db.drop_all() + + +@pytest.fixture +def client(app): + return app.test_client() \ No newline at end of file diff --git a/tests/test_routes.py b/tests/test_routes.py new file mode 100644 index 000000000..5baadecb8 --- /dev/null +++ b/tests/test_routes.py @@ -0,0 +1,32 @@ +import pytest + + +# @pytest.fixture +def empty_list(): + return [] +# @pytest.fixture +def test_len_of_empty_list(empty_list): + assert isinstance(empty_list, list) + assert len(empty_list) == 0 + +# @pytest.fixture +def test_get_all_planets_with_no_records(client): + # Act + response = client.get("/planets") + response_body = response.get_json() + + # Assert + assert response.status_code == 200 + assert response_body == [] + + + +def test_get_one_planet_404(client): + # Arrange + # No setup needed - we want an empty database + # Act + response = client.get(f" / planets / {planet_id}") + response_body = response.get_json() + # Assert + assert response.status_code == 404 + assert response_body == {f"message": "Planet not found"} From 01e806cda391ea4acb1664fd4d2dd9b501303bed Mon Sep 17 00:00:00 2001 From: Tami Date: Wed, 30 Oct 2024 14:09:52 -0400 Subject: [PATCH 27/31] work wave 6 add fixtures and test to creat,add one, fix bug --- app/routes/planet_routes.py | 6 +-- project-directions/wave_06.md | 12 +++--- tests/conftest.py | 16 +++++++- tests/test_routes.py | 75 +++++++++++++++++++++++------------ 4 files changed, 74 insertions(+), 35 deletions(-) diff --git a/app/routes/planet_routes.py b/app/routes/planet_routes.py index f2145d883..f4d791e57 100644 --- a/app/routes/planet_routes.py +++ b/app/routes/planet_routes.py @@ -8,10 +8,10 @@ def create_planet(): request_body = request.get_json() name = request_body["name"] - color = request_body["color"] + moon= request_body["moon"] description = request_body["description"] - new_planet = Planet(name=name, color=color, description=description) + new_planet = Planet(name=name, moon=moon, description=description) db.session.add(new_planet) db.session.commit() response = new_planet.to_dict() @@ -59,7 +59,7 @@ def get_one_planet(planet_id): return { - "id": planet_id, + "id": planet.id, "name": planet.name, "description": planet.description, "moon": planet.moon diff --git a/project-directions/wave_06.md b/project-directions/wave_06.md index 7d854f465..756a7e53e 100644 --- a/project-directions/wave_06.md +++ b/project-directions/wave_06.md @@ -8,13 +8,13 @@ Complete the following requirements, with similar functionality to the Hello Boo 1. Populate it with two environment variables: `SQLALCHEMY_DATABASE_URI` and `SQLALCHEMY_TEST_DATABASE_URI`. Set their values to the appropriate connection strings. 1. Create a test database with the correct, matching name. 1. Refactor the `create_app` method to: - * Check for a configuration flag - * Read the correct database location from the appropriate environment variables + - Check for a configuration flag + - Read the correct database location from the appropriate environment variables 1. Manually test that our development environment still works. 1. Create a `tests` folder with the files: - - `tests/__init__.py` - - `tests/conftest.py` - - `tests/test_routes.py`. + - `tests/__init__.py` + - `tests/conftest.py` + - `tests/test_routes.py`. 1. Populate `tests/conftest.py` with the recommended configuration. 1. Create a test to check `GET` `/planets` returns `200` and an empty array. 1. Confirm this test runs and passes. @@ -23,7 +23,7 @@ Complete the following requirements, with similar functionality to the Hello Boo Create test fixtures and unit tests for the following test cases: -1. `GET` `/planets/1` returns a response body that matches our fixture +1. `GET` `/planets/1` returns a response body that matches our fixture ( to get a planet, single planet) 1. `GET` `/planets/1` with no data in test database (no fixture) returns a `404` 1. `GET` `/planets` with valid test data (fixtures) returns a `200` with an array including appropriate test data 1. `POST` `/planets` with a JSON request body returns a `201` diff --git a/tests/conftest.py b/tests/conftest.py index c5e0bddf5..e033a8b9c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -4,6 +4,7 @@ from flask.signals import request_finished from dotenv import load_dotenv import os +from app.models.planet import Planet load_dotenv() @@ -29,4 +30,17 @@ def expire_session(sender, response, **extra): @pytest.fixture def client(app): - return app.test_client() \ No newline at end of file + return app.test_client() + +@pytest.fixture +def two_saved_planets(app): + mercury = Planet(name = "Mecury", description = "the hotess next to the sun", moon = 0) + vulcan = Planet(name = "Vulcan", description = "the best", moon = 2) + db.session.add_all([mercury, vulcan]) + db.session.commit() + +@pytest.fixture +def create_new_planet(app): + romulus = Planet(name = "Romulus", description = "Homeworld of the Romulan Star Empire, featuring green-tinted skies and advanced architecture.", moon = 2) + db.session.add(romulus) + db.session.commit() \ No newline at end of file diff --git a/tests/test_routes.py b/tests/test_routes.py index 5baadecb8..31a729121 100644 --- a/tests/test_routes.py +++ b/tests/test_routes.py @@ -1,32 +1,57 @@ import pytest -# @pytest.fixture -def empty_list(): - return [] -# @pytest.fixture -def test_len_of_empty_list(empty_list): - assert isinstance(empty_list, list) - assert len(empty_list) == 0 +# def test_get_all_planets_with_no_records(client): +# # Act +# response = client.get("/planets") +# response_body = response.get_json() -# @pytest.fixture -def test_get_all_planets_with_no_records(client): - # Act - response = client.get("/planets") - response_body = response.get_json() +# # Assert +# assert response.status_code == 200 +# assert response_body == [] - # Assert +# def test_get_one_planet_404(client): +# # Arrange +# # No setup needed - we want an empty database +# # Act +# response = client.get(f" / planets /10") +# response_body = response.get_json() +# # Assert +# assert response.status_code == 404 +# assert response_body == {f"message": "Planet not found"} + +def test_get_one_planet_success(client, two_saved_planets): + # arrange is in the conftest + # act + + response = client.get(f"/planets/2") + response_body = response.get_json() + + #assert assert response.status_code == 200 - assert response_body == [] - - - -def test_get_one_planet_404(client): - # Arrange - # No setup needed - we want an empty database - # Act - response = client.get(f" / planets / {planet_id}") + assert response_body == { + "id": 2, + "name": "Vulcan", + "description": "the best", + "moon": 2 + } + +def test_create_new_planet_with_data(client, create_new_planet): + #arrange is in the conftest + #act + response = client.post("/planets",json ={ + "name": "Romulus", + "description": "Homeworld of the Romulan Star Empire, featuring green-tinted skies and advanced architecture.", + "moon": 2 + }) response_body = response.get_json() - # Assert - assert response.status_code == 404 - assert response_body == {f"message": "Planet not found"} + response_body.pop("id") + + #assert + assert response.status_code == 201 + assert response_body == { + "name": "Romulus", + "description": "Homeworld of the Romulan Star Empire, featuring green-tinted skies and advanced architecture.", + "moon": 2 + } + From dd45b2097d26a676f4e5cac031b073d9ccab3977 Mon Sep 17 00:00:00 2001 From: Salma Anany Date: Wed, 30 Oct 2024 22:18:46 -0700 Subject: [PATCH 28/31] wave 6 is completed --- tests/conftest.py | 29 ++++++++++++++++ tests/test_routes.py | 82 ++++++++++++++++++++++++++++---------------- 2 files changed, 81 insertions(+), 30 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index e033a8b9c..e026874e7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -32,6 +32,35 @@ def expire_session(sender, response, **extra): def client(app): return app.test_client() +@pytest.fixture +def get_every_single_planet(app): + planet = [Planet(name="Coruscant", + description="City-covered planet that served as the seat of government for the Galactic Republic and Empire", + moon=4), + Planet(name="Tatooine", + description="Desert world with binary suns, home to the Skywalker family and Jabba the Hutt", + moon=3), Planet(name="Naboo", + description="Beautiful planet with rolling plains and vast seas, homeworld of Padmé Amidala", + moon=1), + Planet(name="Hoth", description="Frozen ice planet that briefly served as a Rebel Alliance base", + moon=2), + + Planet(name="Endor", + description="Forest moon home to the Ewoks and site of the second Death Star's destruction", + moon=9)] + db.session.add_all(planet) + db.session.commit() + + + + + + +@pytest.fixture +def get_planet_invalid_id(app): + return "abc" + + @pytest.fixture def two_saved_planets(app): mercury = Planet(name = "Mecury", description = "the hotess next to the sun", moon = 0) diff --git a/tests/test_routes.py b/tests/test_routes.py index 31a729121..bfabdb2ec 100644 --- a/tests/test_routes.py +++ b/tests/test_routes.py @@ -1,33 +1,55 @@ import pytest -# def test_get_all_planets_with_no_records(client): -# # Act -# response = client.get("/planets") -# response_body = response.get_json() - -# # Assert -# assert response.status_code == 200 -# assert response_body == [] - -# def test_get_one_planet_404(client): -# # Arrange -# # No setup needed - we want an empty database -# # Act -# response = client.get(f" / planets /10") -# response_body = response.get_json() -# # Assert -# assert response.status_code == 404 -# assert response_body == {f"message": "Planet not found"} - +def test_get_every_single_planet(client, get_every_single_planet): + response = client.get(f"/planets") + response_body = response.get_json() + + # assert + assert response.status_code == 200 + assert len(response_body) == 5 + + +def test_get_all_planets_with_no_records(client): + # Act + response = client.get("/planets") + response_body = response.get_json() + + # Assert + assert response.status_code == 200 + assert response_body == [] + + +def test_get_one_planet_404(client): + # Arrange + # No setup needed - we want an empty database + # Act + response = client.get(f"/planets/10") + response_body = response.get_json() + # Assert + assert response.status_code == 404 + assert response_body == {"message": "10 not found"} + + +def test_get_one_planet_400(client, get_planet_invalid_id): + # Arrange + # No setup needed - we want an empty database + # Act + response = client.get(f"/planets/abc") + response_body = response.get_json() + # Assert + assert response.status_code == 400 + assert response_body == {"message": f"planet abc invalid"} + + def test_get_one_planet_success(client, two_saved_planets): # arrange is in the conftest # act - - response = client.get(f"/planets/2") + + response = client.get(f"/planets/2") response_body = response.get_json() - - #assert + + # assert assert response.status_code == 200 assert response_body == { "id": 2, @@ -35,23 +57,23 @@ def test_get_one_planet_success(client, two_saved_planets): "description": "the best", "moon": 2 } - + + def test_create_new_planet_with_data(client, create_new_planet): - #arrange is in the conftest - #act - response = client.post("/planets",json ={ + # arrange is in the conftest + # act + response = client.post("/planets", json={ "name": "Romulus", "description": "Homeworld of the Romulan Star Empire, featuring green-tinted skies and advanced architecture.", "moon": 2 }) response_body = response.get_json() response_body.pop("id") - - #assert + + # assert assert response.status_code == 201 assert response_body == { "name": "Romulus", "description": "Homeworld of the Romulan Star Empire, featuring green-tinted skies and advanced architecture.", "moon": 2 } - From 631b646d30675b9b64ffa517b6a37dcf4d679c47 Mon Sep 17 00:00:00 2001 From: Tami Date: Thu, 31 Oct 2024 14:01:04 -0400 Subject: [PATCH 29/31] add pytest.fixture for update and delete and pytest, fixed update and delete functions in planet_routes folder --- app/__init__.py | 7 --- app/routes/planet_routes.py | 16 ++---- .../4294dced1c4c_adds_planet_model.py | 3 -- tests/conftest.py | 22 ++++++--- tests/test_routes.py | 49 +++++++++++++------ 5 files changed, 52 insertions(+), 45 deletions(-) diff --git a/app/__init__.py b/app/__init__.py index 6891a1298..eb9cfc91b 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,5 +1,4 @@ from importlib import import_module - from flask import Flask from .routes.planet_routes import planets_bp from .db import db, migrate @@ -7,25 +6,19 @@ import os def create_app(config=None): - # __name__ stores the name of the module we're in app = Flask(__name__) - # the base conf app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False - # app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql+psycopg2://postgres:postgres@localhost:5432/planet' - 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') - db.init_app(app) migrate.init_app(app, db) - app.register_blueprint(planets_bp) return app diff --git a/app/routes/planet_routes.py b/app/routes/planet_routes.py index f4d791e57..a77db0a57 100644 --- a/app/routes/planet_routes.py +++ b/app/routes/planet_routes.py @@ -19,14 +19,12 @@ def create_planet(): @planets_bp.get("") def get_all_planets(): - # return make_response("I'm a teapot!", 200) description_param = request.args.get("description") moon_param = request.args.get("moon") sort_param = request.args.get("sort") query = db.select(Planet) - - # changed the desc param + if description_param: query = query.where(Planet.description.like(f"%{description_param}%")) if moon_param: @@ -35,8 +33,7 @@ def get_all_planets(): query = query.where(Planet.moon.__eq__(moon_count)) except ValueError: return {"message": "Invalid moon parameter"}, 400 - - # Apply Sort + sort_options ={ "name": Planet.name, "name_desc": Planet.name.desc(), @@ -47,8 +44,7 @@ def get_all_planets(): sort_field = sort_options.get(sort_param, Planet.id) query = query.order_by(sort_field) - - #execute query + planets = db.session.scalars(query).all() planets_response = [planet.to_dict() for planet in planets] return planets_response @@ -57,7 +53,6 @@ def get_all_planets(): def get_one_planet(planet_id): planet = validate_planet_one(planet_id) - return { "id": planet.id, "name": planet.name, @@ -76,7 +71,7 @@ def update_planet(planet_id): planet.moon= request_body["moon"] db.session.commit() - return Response(status=204, mimetype="application/json") + return Response(status=204, mimetype="application/json") @planets_bp.delete("/") def delete_planet(planet_id): @@ -84,8 +79,7 @@ def delete_planet(planet_id): db.session.delete(planet) db.session.commit() - return Response(status=204, mimetype="application/json") - + return Response(status=204, mimetype="application/json") def validate_planet(planet_id, planets): # Narrow the errors - data error, type error diff --git a/migrations/versions/4294dced1c4c_adds_planet_model.py b/migrations/versions/4294dced1c4c_adds_planet_model.py index 9717b4491..9ea17816a 100644 --- a/migrations/versions/4294dced1c4c_adds_planet_model.py +++ b/migrations/versions/4294dced1c4c_adds_planet_model.py @@ -8,14 +8,12 @@ from alembic import op import sqlalchemy as sa - # revision identifiers, used by Alembic. revision = '4294dced1c4c' down_revision = 'c72d9c7a8b07' branch_labels = None depends_on = None - def upgrade(): # ### commands auto generated by Alembic - please adjust! ### op.create_table('planet', @@ -28,7 +26,6 @@ def upgrade(): op.drop_table('planets') # ### end Alembic commands ### - def downgrade(): # ### commands auto generated by Alembic - please adjust! ### op.create_table('planets', diff --git a/tests/conftest.py b/tests/conftest.py index e026874e7..1477a5a2d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -27,7 +27,6 @@ def expire_session(sender, response, **extra): with app.app_context(): db.drop_all() - @pytest.fixture def client(app): return app.test_client() @@ -51,16 +50,10 @@ def get_every_single_planet(app): db.session.add_all(planet) db.session.commit() - - - - - @pytest.fixture def get_planet_invalid_id(app): return "abc" - @pytest.fixture def two_saved_planets(app): mercury = Planet(name = "Mecury", description = "the hotess next to the sun", moon = 0) @@ -72,4 +65,17 @@ def two_saved_planets(app): def create_new_planet(app): romulus = Planet(name = "Romulus", description = "Homeworld of the Romulan Star Empire, featuring green-tinted skies and advanced architecture.", moon = 2) db.session.add(romulus) - db.session.commit() \ No newline at end of file + db.session.commit() + +@pytest.fixture +def update_existing_planet(app): + kronos= Planet(name ="Kronos", description = "Homeword of the Klingon Empire, rich in warrior culture and tradition, featuring magnificent cities built among dramatic mountain ranges, home to the legendary Great Hall of the High Council, and birthplace of many of the quadrant's greatest warriors and most honored traditions", moon = 7) + db.session.add(kronos) + db.session.commit() + +@pytest.fixture +def delete_existing_planet_romulus(app): + romulus = Planet(name = "Romulus", description = "Homeworld of the Romulan Star Empire, featuring green-tinted skies and advanced architecture.", moon = 2) + db.session.add(romulus) + db.session.commit() + \ No newline at end of file diff --git a/tests/test_routes.py b/tests/test_routes.py index bfabdb2ec..19c6eec65 100644 --- a/tests/test_routes.py +++ b/tests/test_routes.py @@ -1,6 +1,5 @@ import pytest - def test_get_every_single_planet(client, get_every_single_planet): response = client.get(f"/planets") response_body = response.get_json() @@ -9,7 +8,6 @@ def test_get_every_single_planet(client, get_every_single_planet): assert response.status_code == 200 assert len(response_body) == 5 - def test_get_all_planets_with_no_records(client): # Act response = client.get("/planets") @@ -19,8 +17,7 @@ def test_get_all_planets_with_no_records(client): assert response.status_code == 200 assert response_body == [] - -def test_get_one_planet_404(client): +def test_get_one_planet_not_found_404(client): # Arrange # No setup needed - we want an empty database # Act @@ -30,7 +27,6 @@ def test_get_one_planet_404(client): assert response.status_code == 404 assert response_body == {"message": "10 not found"} - def test_get_one_planet_400(client, get_planet_invalid_id): # Arrange # No setup needed - we want an empty database @@ -41,15 +37,12 @@ def test_get_one_planet_400(client, get_planet_invalid_id): assert response.status_code == 400 assert response_body == {"message": f"planet abc invalid"} - -def test_get_one_planet_success(client, two_saved_planets): - # arrange is in the conftest - # act - +def test_get_one_planet_success_200(client, two_saved_planets): + # Act response = client.get(f"/planets/2") response_body = response.get_json() - # assert + # Assert assert response.status_code == 200 assert response_body == { "id": 2, @@ -58,10 +51,8 @@ def test_get_one_planet_success(client, two_saved_planets): "moon": 2 } - -def test_create_new_planet_with_data(client, create_new_planet): - # arrange is in the conftest - # act +def test_create_new_planet_with_data_201(client, create_new_planet): + # Act response = client.post("/planets", json={ "name": "Romulus", "description": "Homeworld of the Romulan Star Empire, featuring green-tinted skies and advanced architecture.", @@ -70,10 +61,36 @@ def test_create_new_planet_with_data(client, create_new_planet): response_body = response.get_json() response_body.pop("id") - # assert + # Assert assert response.status_code == 201 assert response_body == { "name": "Romulus", "description": "Homeworld of the Romulan Star Empire, featuring green-tinted skies and advanced architecture.", "moon": 2 } + +def test_update_existing_planet_minus_one_moon(client, update_existing_planet): + # Act + response = client.put("/planets/1", json={ + "name": "Kronos", + "description": "rich in warrior culture and tradition, featuring magnificent cities built among dramatic mountain ranges, home to the legendary Great Hall of the High Council, and birthplace of many of the quadrant's greatest warriors and most honored traditions", + "moon": 6 + }) + + # Assert + assert response.status_code == 204 + verify_response = client.get("planets/1") + verify_body = verify_response.get_json() + assert verify_body["moon"] == 6 + +def test_delete_existing_planet(client,delete_existing_planet_romulus): + # Act + response = client.delete("/planets/1") + + # Assert + assert response.status_code == 204 + check_respone = client.get("/planets/1") + assert check_respone.status_code == 404 + + + \ No newline at end of file From 40d8c589133eaafffc1222a11fa129d09b79ac8a Mon Sep 17 00:00:00 2001 From: Tami Date: Thu, 31 Oct 2024 14:23:11 -0400 Subject: [PATCH 30/31] change pytest delete fuct and commented out the pytest.fixture --- tests/conftest.py | 10 +++++----- tests/test_routes.py | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 1477a5a2d..384fb0dcd 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -73,9 +73,9 @@ def update_existing_planet(app): db.session.add(kronos) db.session.commit() -@pytest.fixture -def delete_existing_planet_romulus(app): - romulus = Planet(name = "Romulus", description = "Homeworld of the Romulan Star Empire, featuring green-tinted skies and advanced architecture.", moon = 2) - db.session.add(romulus) - db.session.commit() +# @pytest.fixture +# def delete_existing_planet_romulus(app): +# romulus = Planet(name = "Romulus", description = "Homeworld of the Romulan Star Empire, featuring green-tinted skies and advanced architecture.", moon = 2) +# db.session.add(romulus) +# db.session.commit() \ No newline at end of file diff --git a/tests/test_routes.py b/tests/test_routes.py index 19c6eec65..cf653d427 100644 --- a/tests/test_routes.py +++ b/tests/test_routes.py @@ -83,7 +83,7 @@ def test_update_existing_planet_minus_one_moon(client, update_existing_planet): verify_body = verify_response.get_json() assert verify_body["moon"] == 6 -def test_delete_existing_planet(client,delete_existing_planet_romulus): +def test_delete_existing_planet(client,create_new_planet): # Act response = client.delete("/planets/1") From 492fa72625553ee7eebe7da4d52f0aea199bf43f Mon Sep 17 00:00:00 2001 From: Salma Anany Date: Thu, 31 Oct 2024 14:47:54 -0700 Subject: [PATCH 31/31] fixed moon_param bug not if there is no param is going to retrieve normally wave 6 is completed --- app/routes/planet_routes.py | 14 +++++++++++++- tests/conftest.py | 8 ++------ tests/test_routes.py | 4 ++-- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/app/routes/planet_routes.py b/app/routes/planet_routes.py index a77db0a57..617525d6f 100644 --- a/app/routes/planet_routes.py +++ b/app/routes/planet_routes.py @@ -21,16 +21,28 @@ def create_planet(): def get_all_planets(): 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) - query = query.where(Planet.moon.__eq__(moon_count)) + # 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 diff --git a/tests/conftest.py b/tests/conftest.py index 384fb0dcd..3bc0b9de8 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -62,7 +62,7 @@ def two_saved_planets(app): db.session.commit() @pytest.fixture -def create_new_planet(app): +def add_new_planet(app): romulus = Planet(name = "Romulus", description = "Homeworld of the Romulan Star Empire, featuring green-tinted skies and advanced architecture.", moon = 2) db.session.add(romulus) db.session.commit() @@ -73,9 +73,5 @@ def update_existing_planet(app): db.session.add(kronos) db.session.commit() -# @pytest.fixture -# def delete_existing_planet_romulus(app): -# romulus = Planet(name = "Romulus", description = "Homeworld of the Romulan Star Empire, featuring green-tinted skies and advanced architecture.", moon = 2) -# db.session.add(romulus) -# db.session.commit() + \ No newline at end of file diff --git a/tests/test_routes.py b/tests/test_routes.py index cf653d427..bc4ace3a1 100644 --- a/tests/test_routes.py +++ b/tests/test_routes.py @@ -51,7 +51,7 @@ def test_get_one_planet_success_200(client, two_saved_planets): "moon": 2 } -def test_create_new_planet_with_data_201(client, create_new_planet): +def test_create_new_planet_with_data_201(client, add_new_planet): # Act response = client.post("/planets", json={ "name": "Romulus", @@ -83,7 +83,7 @@ def test_update_existing_planet_minus_one_moon(client, update_existing_planet): verify_body = verify_response.get_json() assert verify_body["moon"] == 6 -def test_delete_existing_planet(client,create_new_planet): +def test_delete_existing_planet(client,add_new_planet): # Act response = client.delete("/planets/1")