Modify the application so it respects the REST api standard

This commit is contained in:
Denis-Cosmin Nutiu 2017-04-19 01:27:26 +03:00
parent 65a83d3761
commit 04af445a57
5 changed files with 42 additions and 30 deletions

View file

@ -25,7 +25,7 @@
<td>{{ item.gpu }}</td>
<td>{{ item.cpu }}</td>
<td>{{ item.score }}</td>
<td><a href="{{ url_for('scoreboard.entry', id=item.id) }}">See more</a></td>
<td><a href="{{ url_for('scoreboard.result', id=item.id) }}">See more</a></td>
</tr>
{% endfor %}
</tbody>

View file

@ -5,7 +5,7 @@
{{ super() }}
<div class="page-header">
<h1>Entry number #{{ name.id }} <small>Yeeeah!</small></h1>
<h1>Result number #{{ name.id }} <small>Yeeeah!</small></h1>
</div>
<div class="panel panel-default">
<div class="panel-heading">

View file

@ -5,8 +5,8 @@
{{ super() }}
<div>
<h4>Uploading Data</h4>
<p>Uploading data is simple, all you need to is send a POST request with content-type <code>application/json</code> to this URL.</p>
<p>Uploading data is simple, all you need to is send a POST request with content-type <code>application/json</code> to <code>/result</code>.</p>
<p>Your JSON must respect all the required fields.</p>
<p>Example: <code>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</code></p>
<p>Example: <code>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</code></p>
</div>
{% endblock %}

View file

@ -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')
# @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,29 +54,32 @@ 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/<id>")
def entry(id):
@scoreboard.route("/result/<id>", methods=['GET'])
def result(id):
"""
The entry view display an entry based on it's ID.
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)
return flask.render_template("result.html", name=entry_name)
else:
flask.abort(404)
@ -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

View file

@ -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')