web_service.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. #!/usr/bin/env python3
  2. import uuid
  3. from flask import Flask, request, jsonify, Response
  4. import sqlite3
  5. import os
  6. import time
  7. app = Flask(__name__)
  8. DB_FILENAME = "db.sqlite"
  9. SQL_INSERT_REQUEST = "INSERT INTO requests ('id', 'username', 'depth', 'width', 'int_cycles', 'ext_cycles', 'status') VALUES ('{request_id}', '{username}', '{depth}', '{width}', '{int_cycles}', '{ext_cycles}', '{status}');"
  10. SQL_SELECT_USERNAME = "SELECT username FROM users WHERE api_key='{api_key}'"
  11. SQL_SELECT_REQUEST_STATUS = "SELECT status FROM requests WHERE id='{request_id}'"
  12. SQL_UPDATE_STATUS = "UPDATE requests SET status='{status}' WHERE id='{request_id}'"
  13. def get_username_from_api_key(api_key):
  14. conn = sqlite3.connect(DB_FILENAME)
  15. c = conn.cursor()
  16. sql = SQL_SELECT_USERNAME.format(api_key=api_key)
  17. res = c.execute(sql).fetchall()
  18. conn.close()
  19. return res[0][0] if res else None
  20. def get_request_status(request_id):
  21. conn = sqlite3.connect(DB_FILENAME)
  22. c = conn.cursor()
  23. sql = SQL_SELECT_REQUEST_STATUS.format(request_id=request_id)
  24. res = c.execute(sql).fetchall()
  25. conn.close()
  26. return res[0][0] if res else None
  27. def submit_devstone(request_id, username, depth, width, int_cycles, ext_cycles):
  28. conn = sqlite3.connect(DB_FILENAME)
  29. c = conn.cursor()
  30. sql = SQL_INSERT_REQUEST.format(request_id=request_id, username=username, depth=depth, width=width, int_cycles=int_cycles, ext_cycles=ext_cycles, status="pending")
  31. c.execute(sql)
  32. conn.commit()
  33. conn.close()
  34. # TODO: here it would be the devstone comparative script call
  35. # time.sleep(5)
  36. open("results/%s.csv" % request_id, "w").write(username)
  37. conn = sqlite3.connect(DB_FILENAME)
  38. sql = SQL_UPDATE_STATUS.format(request_id=request_id, status="finished")
  39. c = conn.cursor()
  40. c.execute(sql)
  41. conn.commit()
  42. conn.close()
  43. @app.route('/')
  44. def hello():
  45. return 'Hey there! Ready to execute some DEVStone models?'
  46. @app.route('/run_devstone')
  47. def run_devstone():
  48. try:
  49. api_key = request.args["api_key"]
  50. except Exception as e:
  51. return jsonify({"status": "denied", "reason": "No api_key was specified."})
  52. try:
  53. depth = int(request.args["depth"])
  54. width = int(request.args["width"])
  55. int_cycles = int(request.args["int_cycles"]) if "int_cycles" in request.args else 0
  56. ext_cycles = int(request.args["ext_cycles"]) if "ext_cycles" in request.args else 0
  57. except Exception as e:
  58. return jsonify({"status": "denied", "reason": "Invalid params."})
  59. # Check that api key exists
  60. username = get_username_from_api_key(api_key)
  61. if username is None:
  62. return jsonify({"status": "denied", "reason": "Invalid api key."})
  63. # Execute task
  64. request_id = uuid.uuid4().hex
  65. submit_devstone(request_id, username, depth, width, int_cycles, ext_cycles)
  66. status_url = request.host_url + "status?request_id=" + request_id
  67. return jsonify({"status": "submitted", "request_id": request_id, "status_url": status_url})
  68. @app.route('/status')
  69. def status():
  70. try:
  71. request_id = request.args["request_id"]
  72. except Exception as e:
  73. return jsonify({"status": "denied", "reason": "No request_id was specified."})
  74. status = get_request_status(request_id)
  75. res = {"status": status, "request_id": request_id}
  76. if status == "finished":
  77. download_url = request.host_url + "download?request_id=" + request_id
  78. res["download_link"] = download_url
  79. return jsonify(res)
  80. @app.route('/download')
  81. def download():
  82. try:
  83. request_id = request.args["request_id"]
  84. except Exception as e:
  85. return jsonify({"status": "denied", "reason": "No request_id was specified."})
  86. status = get_request_status(request_id)
  87. if status != "finished":
  88. status_url = request.host_url + "status?request_id=" + request_id
  89. return redirect(status_url)
  90. with open("results/%s.csv" % request_id) as f:
  91. csv = f.read()
  92. return Response(
  93. csv,
  94. mimetype="text/csv",
  95. headers={"Content-disposition":
  96. "attachment; filename=%s.csv" % request_id})
  97. if __name__ == '__main__':
  98. if not os.path.exists('results'):
  99. os.makedirs('results')
  100. app.run(debug=True, port=8080)