I'm testing API CRUD with browsable web API flask implementation, but the browser seems to send unexpected requests to the API.
Here is the code I'm testing :
from flask import request, url_for
from flask_api import FlaskAPI, status, exceptions
app = FlaskAPI(__name__)
notes = {
0: 'do the shopping',
1: 'build the codez',
2: 'paint the door',
}
def note_repr(key):
return {
'url': request.host_url.rstrip('/') + url_for('notes_detail', key=key),
'text': notes[key]
}
@app.route("/", methods=['GET', 'POST'])
def notes_list():
"""
List or create notes.
"""
if request.method == 'POST':
note = str(request.data.get('text', ''))
idx = max(notes.keys()) + 1
notes[idx] = note
return note_repr(idx), status.HTTP_201_CREATED
# request.method == 'GET'
return [note_repr(idx) for idx in sorted(notes.keys())]
@app.route("/<int:key>/", methods=['GET', 'PUT', 'DELETE'])
def notes_detail(key):
"""
Retrieve, update or delete note instances.
"""
if request.method == 'PUT':
note = str(request.data.get('text', ''))
notes[key] = note
return note_repr(key)
elif request.method == 'DELETE':
notes.pop(key, None)
return '', status.HTTP_204_NO_CONTENT
# request.method == 'GET'
if key not in notes:
raise exceptions.NotFound()
return note_repr(key)
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)
When I tried to delete a specific note given its id (key
) from the example notes list, the browser sends a POST
method instead of DELETE
, which is not supported by the route.
The base render template is located here where you can see DELETE
button statement at line 104
.
I edited the library code and move the form method
there from POST
to DELETE
thinking it could solve the problem this way :
104 {% if 'DELETE' in allowed_methods %}
105 <form class="button-form" action="{{ request.url }}" method="DELETE" class="pull-right">
106 <!-- csrf_token -->
107 <input type="hidden" name="_method" value="DELETE" />
108 <button class="btn btn-danger js-tooltip" title="Make a DELETE request on the resource">DELETE</button>
109 </form>
110 {% endif %}
But not, the browser is now sending a GET
request with the query string _method=DELETE
, instead of DELETE
request/method.
Everything is OK when sending request to the API using curl
Can one of you guys with good flask html rendering skills check this out and test on its side?