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

Tags:

Python

Flask