Chris St. Pierre - @chris_st_pierre
https://github.com/stpierre/flask-microservices.git
make
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"}
iostat
Mac 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_id
state
result
, 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/