From 04af445a57a17a9baf1129a6c43b26e057bf1fdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denis=20Nut=CC=A6iu?= Date: Wed, 19 Apr 2017 01:27:26 +0300 Subject: [PATCH] Modify the application so it respects the REST api standard --- src/templates/index.html | 2 +- src/templates/result.html | 2 +- src/templates/upload.html | 4 +-- src/views/scoreboard.py | 56 ++++++++++++++++++++++++--------------- test/test_scoreboard.py | 8 +++--- 5 files changed, 42 insertions(+), 30 deletions(-) diff --git a/src/templates/index.html b/src/templates/index.html index b915e77..527dac8 100644 --- a/src/templates/index.html +++ b/src/templates/index.html @@ -25,7 +25,7 @@ {{ item.gpu }} {{ item.cpu }} {{ item.score }} - See more + See more {% endfor %} diff --git a/src/templates/result.html b/src/templates/result.html index eb4b9f8..4f89ed7 100644 --- a/src/templates/result.html +++ b/src/templates/result.html @@ -5,7 +5,7 @@ {{ super() }}
diff --git a/src/templates/upload.html b/src/templates/upload.html index 4c63c0b..4c2c1df 100644 --- a/src/templates/upload.html +++ b/src/templates/upload.html @@ -5,8 +5,8 @@ {{ super() }}

Uploading Data

-

Uploading data is simple, all you need to is send a POST request with content-type application/json to this URL.

+

Uploading data is simple, all you need to is send a POST request with content-type application/json to /result.

Your JSON must respect all the required fields.

-

Example: curl -H "Content-Type: application/json" -X POST -d '{"gpu":"GPU DUMMY TEXT","cpu":"CPU DUMMY TEXT","log":"So this will be a detailed log.","score": 1}' http://localhost:5000/upload

+

Example: curl -H "Content-Type: application/json" -X POST -d '{"gpu":"GPU DUMMY TEXT","cpu":"CPU DUMMY TEXT","log":"So this will be a detailed log.","score": 1}' http://localhost:5000/result

{% endblock %} \ No newline at end of file diff --git a/src/views/scoreboard.py b/src/views/scoreboard.py index 9fb4d33..9699818 100644 --- a/src/views/scoreboard.py +++ b/src/views/scoreboard.py @@ -17,27 +17,35 @@ """ from src.models import Result from src.models import db -import json import math import flask scoreboard = flask.Blueprint('scoreboard', __name__, template_folder='templates') -@scoreboard.route("/upload", methods=['POST', 'GET']) +@scoreboard.route("/upload") def upload(): """ - This is the upload view. It accepts JSON only. - - Returns: - This method returns a JSON object with tree variables - status code, success true if the data was received successfully and false otherwise and - an error string. + Returns a page containing instructions on how to upload things. """ - if flask.request.method == 'GET': - return flask.render_template('upload.html') + return flask.render_template('upload.html') +# @scoreboard.route("/result", methods=['GET']) +# def result_get(): +# """ +# Instead of method not allowed we redirect to scoreboard.upload +# """ +# return flask.redirect(flask.url_for('scoreboard.upload')) + + +@scoreboard.route("/result", methods=['POST']) +def result_post(): + """ + Allows the upload of resources via POST. + """ content = flask.request.get_json() + error = None + gpu = cpu = log = score = None try: gpu = content['gpu'] @@ -46,36 +54,39 @@ def upload(): score = int(content['score']) except KeyError: # Json doesn't contain the keys we need. error = "invalid json keys: gpu, cpu, log, score" - return json.dumps({'error': error, 'success': False}), 400, {'ContentType': 'application/json'} except TypeError: # The types from the json object are not correct. error = "invalid json object" - return json.dumps({'error': error, 'success': False}), 400, {'ContentType': 'application/json'} + + if error: + return flask.jsonify({'error': error, 'success': False}), 400 # Add data to the database entry = Result(gpu=gpu, cpu=cpu, log=log, score=score) db.session.add(entry) db.session.commit() - return json.dumps({'success': True}), 200, {'ContentType': 'application/json'} + location = "/result/{}".format(entry.id) + + return flask.jsonify({'success': True, 'location': location}), 201, {'location': location} -@scoreboard.route("/entry/") -def entry(id): +@scoreboard.route("/result/", methods=['GET']) +def result(id): """ - The entry view display an entry based on it's ID. - The entry is retrieved from the database and the ID is a primary key for the entry. + Fetches an entry from the database and displays it in a view. + The entry is retrieved from the database and the ID is a primary key for the entry. """ entry_name = Result.query.filter_by(id=id).first() if entry_name: - return flask.render_template("entry.html", name=entry_name) - - flask.abort(404) + return flask.render_template("result.html", name=entry_name) + else: + flask.abort(404) @scoreboard.route("/") def index(): """ - This method returns the index page. + This method returns the index page. """ results_per_page = flask.current_app.config["MAX_RESULTS_PER_PAGE"] max_pages = flask.current_app.config["MAX_PAGES"] @@ -85,7 +96,8 @@ def index(): page_no = flask.request.args.get('page') try: page_no = int(page_no) - 1 - if page_no < 0: page_no = 0 + if page_no < 0: + page_no = 0 except (TypeError, ValueError): # page_no is not an int page_no = 0 diff --git a/test/test_scoreboard.py b/test/test_scoreboard.py index c657206..e08ffec 100644 --- a/test/test_scoreboard.py +++ b/test/test_scoreboard.py @@ -44,14 +44,14 @@ class ScoreboardTestCase(unittest.TestCase): self.assertEqual(response.status_code, 404) def test_entry(self): - response = self.client.get("/entry/1") + response = self.client.get("/result/1") self.assertEqual(response.status_code, 404) data = Result(cpu="TestCPU", gpu="TestGPU", log="TestLOG") db.session.add(data) db.session.commit() - response = self.client.get("/entry/1") + response = self.client.get("/result/1") self.assertEqual(response.status_code, 200) def test_add_entry(self): @@ -61,10 +61,10 @@ class ScoreboardTestCase(unittest.TestCase): log="This is a logfile", score=200 ) - response = self.client.post('/upload', data=json.dumps(data), content_type='application/json') + response = self.client.post('/result', data=json.dumps(data), content_type='application/json') self.assertTrue("true" in response.get_data(as_text=True)) - self.assertEqual(response.status_code, 200) + self.assertEqual(response.status_code, 201) def test_get_upload(self): response = self.client.get('/upload')