Chris St. Pierre - @chris_st_pierre
https://github.com/stpierre/flask-microservices.gitmake and Python 2.7 are installed#flask-microservices at
usenix-lisa.slack.comuptime and iostat to the
internet.
make venv
uptime
emacs solution/app.py
% alias vi=emacs
% type vi
vi is aliased to `emacs'
make test
subprocess.check_output(["uptime"])
make service
curl http://localhost:5000/v1/uptime/
return {"uptime": subprocess.check_output(["uptime"]).strip()}
% curl http://localhost:5000/v1/uptime/
{"uptime": "20:16:57 up 14 days, 7:33, 25 users, load average: 0.58, 0.25, 0.14"}
iostatMac OS:
iostat -d [-c <count>] [-w <wait>]
Linux:
iostat -d <wait> <count>
http://localhost:5000/v1/iostat/?count=4&wait=2
wait = int(flask.request.args.get("wait", 1))
curl http://localhost:5000/v1/iostat/
curl http://localhost:5000/v1/iostat/\?count=2
curl http://localhost:5000/v1/iostat/\?count=5\&wait=1
"If you make something idiot-proof, someone will just make a better idiot."
curl http://localhost:5000/v1/iostat/\?count=-10
curl http://localhost:5000/v1/iostat/\?count=1.5
curl http://localhost:5000/v1/iostat/\?count=1\&wait=10
restful.abort(400, msg="Try harder, moron")
count or wait are not integerscount or wait are less than 1wait is specified, but count is 1
curl http://localhost:5000/v1/iostat/\?count=1000\&wait=1000
curl http://localhost:5000/v2/iostat/
@api.resource("/v1/uptime/", "/v2/uptime")
class UptimeV1(restful.Resource):
...
/v2/uptime/: no change!/v2/iostat/: returns task object/v2/task/: monitor and delete tasks
emacs solution/tasks.py
result = tasks.iostat.delay(count, wait)
return flask.make_response(
flask.jsonify({"task_id": result.id,
"links": [
{"rel": "task",
"href": api.url_for(TaskV2,
task_id=result.id)}]}),
201)
make celery
% curl http://localhost:5000/v2/iostat/
{
"links": [
{
"href": "/v2/task/1800799b-bfa1-4e14-9552-02d2dd82f01a",
"rel": "task"
}
],
"task_id": "1800799b-bfa1-4e14-9552-02d2dd82f01a"
}
GET /v2/task/<task_id>/: poll a
taskDELETE /v2/task/<task_id>/: cancel
a task
@api.resource("/v2/task/<string:task_id>")
class TaskV2(restful.Resource):
def get(self, task_id):
...
task = tasks.app.AsyncResult(task_id)
task.state == "PENDING", the task
doesn't exist.task.ready() tells you if the task is
done running and task.result is
meaningful.task.result is an exception, the task
failed.task_idstateresult, only if the task is readylinks
retval["links"].append({"rel": "cancel",
"method": "DELETE",
"href": api.url_for(TaskV2, task_id=task.id)})
@api.resource("/v2/task/<string:task_id>")
class TaskV2(restful.Resource):
def get(self, task_id):
...
def delete(self, task_id):
...
task.revoke()
return flask.make_response("", 204)
make
v3-database/v3/SOLUTION_DO_NOT_PEEK/