If we declare a route for every model action and do the same things for each (in your case, call the corresponding method with or without parameter), it will duplicate the code. Commonly, people use design patterns (primarily for big projects) and algorithms to avoid code duplications. And I want to show a simple example that defines one generic route and handles all requests in one handler function.
Suppose we have the following file structure.
application/
├─ models/
│ ├─ door.py
│ ├─ window.py
├─ main.py
The prototype of the Door
looks like
# door.py
class Door:
def open(self):
try:
# open the door
return 0
except:
return 1
def close(self):
try:
# close the door
return 0
except:
return 1
def openlater(self, waitseconds=2):
print("Waiting for ", waitseconds)
try:
# wait and open the door
return 0
except:
return 1
Where I conditionally set exit codes of the C, 0
for success and 1
for error or failure.
We must separate and group the model actions into one as they have a common structure.
+----------+----------+------------+----------------------+
| API base | model | action | arguments (optional) |
+----------+----------+------------+----------------------+
| /api | /door | /open | |
| /api | /door | /close | |
| /api | /door | /openlater | ?waitseconds=10 |
| /api | /window | /open | |
| /api | /<model> | /<action> | |
+----------+----------+------------+----------------------+
After we separate our groups by usage interface, we can implement a generic handler for each.
Generic handler
implementation
# main.py
from flask import Flask, Response, request
import json
from models.door import Door
from models.window import Window
app = Flask(__name__)
door = Door()
window = Window()
MODELS = {
"door": door,
"window": window,
}
@app.route("/api/<model>/<action>")
def handler(model, action):
model_ = MODELS.get(model)
action_ = getattr(model_, action, None)
if callable(action_):
try:
error = action_(**request.args)
if not error:
return Response(json.dumps({
"message": "Operation succeeded"
}), status=200, mimetype="application/json")
return Response(json.dumps({
"message": "Operation failed"
}), status=400, mimetype="application/json")
except (TypeError, Exception):
return Response(json.dumps({
"message": "Invalid parameters"
}), status=400, mimetype="application/json")
return Response(json.dumps({
"message": "Wrong action"
}), status=404, mimetype="application/json")
if __name__ == "__main__":
app.run()
So you can control the actions of the models by using different API paths and query parameters.