Allow ALL method types in flask route
See below, which is some code (that I've trimmed down) from the Flask app object. This code handles adding a url rule (which is also what is called by flask when you do app.route() on your view)....
@setupmethod
def add_url_rule(self, rule, endpoint=None, view_func=None, **options):
""" I remove a ton the documentation here.... """
if endpoint is None:
endpoint = _endpoint_from_view_func(view_func)
options['endpoint'] = endpoint
methods = options.pop('methods', None)
# if the methods are not given and the view_func object knows its
# methods we can use that instead. If neither exists, we go with
# a tuple of only `GET` as default.
if methods is None:
methods = getattr(view_func, 'methods', None) or ('GET',)
methods = set(methods)
# ... SNIP a bunch more code...
rule = self.url_rule_class(rule, methods=methods, **options)
rule.provide_automatic_options = provide_automatic_options
self.url_map.add(rule)
As you can see, Flask will do it's darndest to ensure that the methods are explicitely defined. Now, Flask is based on Werkzeug, and the line...
rule = self.url_rule_class(rule, methods=methods, **options)
...typically uses Werkzeug's Rule class. This class has the following documentation for the "methods" argument...
A sequence of http methods this rule applies to. If not specified, all methods are allowed.
So, this tells me that you MIGHT be able to do something like the following...
from werkzeug.routing import Rule
app = Flask(__name__)
def my_rule_wrapper(rule, **kwargs):
kwargs['methods'] = None
return Rule(rule, **kwargs)
app.url_rule_class = my_rule_wrapper
I haven't tested this out, but hopefully that can get you on the right track.
Edit:
Or you could just use DazWorrall's answer, which seems better :P
You can change the url_map directly for this, by adding a Rule
with no methods:
from flask import Flask, request
import unittest
from werkzeug.routing import Rule
app = Flask(__name__)
app.url_map.add(Rule('/', endpoint='index'))
@app.endpoint('index')
def index():
return request.method
class TestMethod(unittest.TestCase):
def setUp(self):
self.client = app.test_client()
def test_custom_method(self):
resp = self.client.open('/', method='BACON')
self.assertEqual('BACON', resp.data)
if __name__ == '__main__':
unittest.main()
methods
A sequence of http methods this rule applies to. If not specified, all methods are allowed.
To quickly enable all HTTP Request Methods for a route
without manually adding rules to the Flask url_map
, modify the route
definition as follows:
from flask import request
HTTP_METHODS = ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE', 'PATCH']
@app.route('/', methods=HTTP_METHODS)
def index():
return request.method