-
Notifications
You must be signed in to change notification settings - Fork 1
/
app.py
158 lines (124 loc) · 4.49 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# cspell: ignore jsonify
"""
Simple REST API using Flask
"""
from flask import Flask, jsonify, abort, url_for
import status
app = Flask(__name__)
COUNTERS: dict = {}
############################################################
# Index page
############################################################
@app.route("/", methods=["GET"])
def index():
"""Root URL"""
return {"status": "OK"}
############################################################
# List counters
############################################################
@app.route("/counters", methods=["GET"])
def list_counters():
"""List counters"""
app.logger.info("Request to list all counters...")
counters = [
{"name": name, "counter": counter} for name, counter in COUNTERS.items()
]
return counters
############################################################
# Create counter
############################################################
@app.route("/counters/<name>", methods=["POST"])
def create_counters(name):
"""Create a counter"""
app.logger.info("Request to Create counter...")
if name in COUNTERS:
abort(status.HTTP_409_CONFLICT, f"Counter '{name}' already exists.")
counter = 0
COUNTERS[name] = counter
app.logger.info("Counter %s created.", name)
location_url = url_for("read_counters", name=name, _external=True)
return (
jsonify(name=name, counter=counter),
status.HTTP_201_CREATED,
{"Location": location_url},
)
############################################################
# Read counters
############################################################
@app.route("/counters/<name>", methods=["GET"])
def read_counters(name: str):
"""Read a counter"""
app.logger.info("Request to Read counter: %s...", name)
# Try and get the counter
counter = COUNTERS.get(name)
# Return an error if the counter cannot be found
if counter is None:
abort(status.HTTP_404_NOT_FOUND, f"Counter '{name}' does not exist")
app.logger.info("Returning: %s = %d...", name, counter)
return jsonify(name=name, counter=counter), status.HTTP_200_OK
############################################################
# Update counters
############################################################
@app.route("/counters/<name>", methods=["PUT"])
def update_counters(name):
"""Update a counter"""
app.logger.info("Request to Update counter %s...", name)
# Try and get the counter
counter = COUNTERS.get(name)
# Return an error if the counter cannot be found
if counter is None:
abort(status.HTTP_404_NOT_FOUND, f"Counter '{name}' does not exist")
# Increment the counter
COUNTERS[name] += 1
app.logger.info("Updated: %s = %d...", name, COUNTERS[name])
return jsonify(name=name, counter=COUNTERS[name]), status.HTTP_200_OK
############################################################
# Delete counters
############################################################
@app.route("/counters/<name>", methods=["DELETE"])
def delete_counters(name):
"""Delete a counter"""
app.logger.info("Request to Delete counter...")
if name in COUNTERS:
del COUNTERS[name]
return "", status.HTTP_204_NO_CONTENT
######################################################################
# Error Handlers
######################################################################
@app.errorhandler(status.HTTP_404_NOT_FOUND)
def not_found(error):
"""Handles resources not found with 404_NOT_FOUND"""
message = str(error)
app.logger.warning(message)
return (
jsonify(
status=status.HTTP_404_NOT_FOUND, error="404 Not Found", message=message
),
status.HTTP_404_NOT_FOUND,
)
@app.errorhandler(status.HTTP_405_METHOD_NOT_ALLOWED)
def method_not_supported(error):
"""Handles unsupported HTTP methods with 405_METHOD_NOT_SUPPORTED"""
message = str(error)
app.logger.warning(message)
return (
jsonify(
status=status.HTTP_405_METHOD_NOT_ALLOWED,
error="Method not Allowed",
message=message,
),
status.HTTP_405_METHOD_NOT_ALLOWED,
)
@app.errorhandler(status.HTTP_409_CONFLICT)
def conflicting_action(error):
"""Handles unsupported HTTP methods with HTTP_409_CONFLICT"""
message = str(error)
app.logger.warning(message)
return (
jsonify(
status=status.HTTP_409_CONFLICT,
error="409 Conflict",
message=message,
),
status.HTTP_409_CONFLICT,
)