Skip to content

Commit d8e10e3

Browse files
committed
Fixed health endpoint
1 parent 14c1881 commit d8e10e3

File tree

4 files changed

+49
-36
lines changed

4 files changed

+49
-36
lines changed

service/config.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
Global Configuration for Application
33
"""
44
import os
5-
import json
65
import logging
76

87
# Get configuration from environment
@@ -11,11 +10,6 @@
1110
"postgresql+psycopg://postgres:postgres@localhost:5432/postgres"
1211
)
1312

14-
# override if we are running in Cloud Foundry
15-
if 'VCAP_SERVICES' in os.environ:
16-
vcap = json.loads(os.environ['VCAP_SERVICES'])
17-
DATABASE_URI = vcap['user-provided'][0]['credentials']['url']
18-
1913
# Configure SQLAlchemy
2014
SQLALCHEMY_DATABASE_URI = DATABASE_URI
2115
SQLALCHEMY_TRACK_MODIFICATIONS = False

service/routes.py

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright 2016, 2019 John J. Rofrano. All Rights Reserved.
1+
# Copyright 2016, 2024 John J. Rofrano. All Rights Reserved.
22
#
33
# Licensed under the Apache License, Version 2.0 (the "License");
44
# you may not use this file except in compliance with the License.
@@ -15,13 +15,8 @@
1515
"""
1616
Pet Store Service
1717
18-
Paths:
19-
------
20-
GET /pets - Returns a list all of the Pets
21-
GET /pets/{id} - Returns the Pet with a given id number
22-
POST /pets - creates a new Pet record in the database
23-
PUT /pets/{id} - updates a Pet record in the database
24-
DELETE /pets/{id} - deletes a Pet record in the database
18+
This service implements a REST API that allows you to Create, Read, Update
19+
and Delete Pets from the inventory of pets in the PetShop
2520
"""
2621

2722
from flask import jsonify, request, url_for, abort
@@ -33,8 +28,8 @@
3328
######################################################################
3429
# GET HEALTH CHECK
3530
######################################################################
36-
@app.route("/healthcheck")
37-
def healthcheck():
31+
@app.route("/health")
32+
def health_check():
3833
"""Let them know our heart is still beating"""
3934
return jsonify(status=200, message="Healthy"), status.HTTP_200_OK
4035

@@ -63,7 +58,10 @@ def index():
6358
def list_pets():
6459
"""Returns all of the Pets"""
6560
app.logger.info("Request for pet list")
61+
6662
pets = []
63+
64+
# See if any query filters were passed in
6765
category = request.args.get("category")
6866
name = request.args.get("name")
6967
if category:
@@ -79,7 +77,7 @@ def list_pets():
7977

8078

8179
######################################################################
82-
# RETRIEVE A PET
80+
# READ A PET
8381
######################################################################
8482
@app.route("/pets/<int:pet_id>", methods=["GET"])
8583
def get_pets(pet_id):
@@ -89,32 +87,35 @@ def get_pets(pet_id):
8987
This endpoint will return a Pet based on it's id
9088
"""
9189
app.logger.info("Request for pet with id: %s", pet_id)
90+
9291
pet = Pet.find(pet_id)
9392
if not pet:
94-
abort(status.HTTP_404_NOT_FOUND, f"Pet with id '{pet_id}' was not found.")
93+
error(status.HTTP_404_NOT_FOUND, f"Pet with id '{pet_id}' was not found.")
9594

9695
app.logger.info("Returning pet: %s", pet.name)
9796
return jsonify(pet.serialize()), status.HTTP_200_OK
9897

9998

10099
######################################################################
101-
# ADD A NEW PET
100+
# CREATE A NEW PET
102101
######################################################################
103102
@app.route("/pets", methods=["POST"])
104103
def create_pets():
105104
"""
106105
Creates a Pet
106+
107107
This endpoint will create a Pet based the data in the body that is posted
108108
"""
109109
app.logger.info("Request to create a pet")
110110
check_content_type("application/json")
111+
111112
pet = Pet()
112113
pet.deserialize(request.get_json())
113114
pet.create()
114115
message = pet.serialize()
115116
location_url = url_for("get_pets", pet_id=pet.id, _external=True)
116117

117-
app.logger.info("Pet with ID [%s] created.", pet.id)
118+
app.logger.info("Pet with ID: %d created.", pet.id)
118119
return jsonify(message), status.HTTP_201_CREATED, {"Location": location_url}
119120

120121

@@ -128,18 +129,18 @@ def update_pets(pet_id):
128129
129130
This endpoint will update a Pet based the body that is posted
130131
"""
131-
app.logger.info("Request to update pet with id: %s", pet_id)
132+
app.logger.info("Request to update pet with id: %d", pet_id)
132133
check_content_type("application/json")
133134

134135
pet = Pet.find(pet_id)
135136
if not pet:
136-
abort(status.HTTP_404_NOT_FOUND, f"Pet with id '{pet_id}' was not found.")
137+
error(status.HTTP_404_NOT_FOUND, f"Pet with id: '{pet_id}' was not found.")
137138

138139
pet.deserialize(request.get_json())
139140
pet.id = pet_id
140141
pet.update()
141142

142-
app.logger.info("Pet with ID [%s] updated.", pet.id)
143+
app.logger.info("Pet with ID: %d updated.", pet.id)
143144
return jsonify(pet.serialize()), status.HTTP_200_OK
144145

145146

@@ -153,12 +154,13 @@ def delete_pets(pet_id):
153154
154155
This endpoint will delete a Pet based the id specified in the path
155156
"""
156-
app.logger.info("Request to delete pet with id: %s", pet_id)
157+
app.logger.info("Request to delete pet with id: %d", pet_id)
158+
157159
pet = Pet.find(pet_id)
158160
if pet:
159161
pet.delete()
160162

161-
app.logger.info("Pet with ID [%s] delete complete.", pet_id)
163+
app.logger.info("Pet with ID: %d delete complete.", pet_id)
162164
return "", status.HTTP_204_NO_CONTENT
163165

164166

@@ -167,14 +169,22 @@ def delete_pets(pet_id):
167169
######################################################################
168170
@app.route("/pets/<int:pet_id>/purchase", methods=["PUT"])
169171
def purchase_pets(pet_id):
170-
"""Purchasing a Pet makes it unavailable"""
172+
"""
173+
Purchasing a Pet
174+
175+
This endpoint will purchase a pet makes it unavailable
176+
"""
177+
app.logger.info("Request to purchase pet with id: %d", pet_id)
178+
171179
pet = Pet.find(pet_id)
172180
if not pet:
173-
abort(status.HTTP_404_NOT_FOUND, f"Pet with id '{pet_id}' was not found.")
181+
error(status.HTTP_404_NOT_FOUND, f"Pet with id '{pet_id}' was not found.")
182+
183+
# you can only purchase pets that are available
174184
if not pet.available:
175-
abort(
185+
error(
176186
status.HTTP_409_CONFLICT,
177-
f"Pet with id '{pet_id}' is not available.",
187+
f"Pet with ID: '{pet_id}' is not available.",
178188
)
179189

180190
# At this point you would execute code to purchase the pet
@@ -183,6 +193,7 @@ def purchase_pets(pet_id):
183193
pet.available = False
184194
pet.update()
185195

196+
app.logger.info("Pet with ID: %d has been purchased.", pet_id)
186197
return pet.serialize(), status.HTTP_200_OK
187198

188199

@@ -191,11 +202,14 @@ def purchase_pets(pet_id):
191202
######################################################################
192203

193204

205+
######################################################################
206+
# Checks the ContentType of a request
207+
######################################################################
194208
def check_content_type(content_type):
195209
"""Checks that the media type is correct"""
196210
if "Content-Type" not in request.headers:
197211
app.logger.error("No Content-Type specified.")
198-
abort(
212+
error(
199213
status.HTTP_415_UNSUPPORTED_MEDIA_TYPE,
200214
f"Content-Type must be {content_type}",
201215
)
@@ -204,7 +218,16 @@ def check_content_type(content_type):
204218
return
205219

206220
app.logger.error("Invalid Content-Type: %s", request.headers["Content-Type"])
207-
abort(
221+
error(
208222
status.HTTP_415_UNSUPPORTED_MEDIA_TYPE,
209223
f"Content-Type must be {content_type}",
210224
)
225+
226+
227+
######################################################################
228+
# Logs error messages before aborting
229+
######################################################################
230+
def error(status_code, reason):
231+
"""Logs the error and then aborts"""
232+
app.logger.error(reason)
233+
abort(status_code, reason)

tests/test_models.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,13 @@
2828
from unittest import TestCase
2929
from datetime import date
3030
from wsgi import app
31-
# from service import create_app
3231
from service.models import Pet, Gender, DataValidationError, db
3332
from tests.factories import PetFactory
3433

3534
DATABASE_URI = os.getenv(
3635
"DATABASE_URI", "postgresql+psycopg://postgres:postgres@localhost:5432/testdb"
3736
)
3837

39-
# app = create_app()
40-
4138

4239
######################################################################
4340
# B A S E T E S T C A S E S
@@ -54,7 +51,6 @@ def setUpClass(cls):
5451
app.config["SQLALCHEMY_DATABASE_URI"] = DATABASE_URI
5552
app.logger.setLevel(logging.CRITICAL)
5653
app.app_context().push()
57-
# Pet.init_db(app)
5854

5955
@classmethod
6056
def tearDownClass(cls):

tests/test_routes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ def test_index(self):
107107

108108
def test_health(self):
109109
"""It should be healthy"""
110-
response = self.client.get("/healthcheck")
110+
response = self.client.get("/health")
111111
self.assertEqual(response.status_code, status.HTTP_200_OK)
112112
data = response.get_json()
113113
self.assertEqual(data["status"], 200)

0 commit comments

Comments
 (0)