Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flask Route Pattern Matching Order

Given that Flask Routes are not pattern matched from top to bottom, how does one deal with the following problem?

I have the following routes:

  1. /<poll_key>/close
  2. /<poll_key>/<participant_key>

If I make a request to http://localhost:5000/example-poll-key/close, Flask matches it as pattern 2, assigning the string 'close' to the <participant_key> URL parameter. How can I make the <poll_key>/close route get matched before the <participant_key> route?

like image 940
dmoench Avatar asked Jul 25 '13 21:07

dmoench


1 Answers

See my other answer to the same question: https://stackoverflow.com/a/17146563/880326.

Looks like the best solution is to add your own converters and create routes as

/<poll_key>/close
/<poll_key>/<no(close):participant_key>

where the no converter is defined

class NoConverter(BaseConverter):

    def __init__(self, map, *items):
        BaseConverter.__init__(self, map)
        self.items = items

    def to_python(self, value):
        if value in self.items:
            raise ValidationError()
        return value

Update:

I missed match_compare_key:

  1. for static endpoint: (True, -2, [(0, -6), (1, 200)])
  2. for /<poll_key>/close: (True, -2, [(1, 100), (0, -5)])
  3. for /<poll_key>/<participant_key>: (True, -2, [(1, 100), (1, 100)])

This means that static has higher priority than the others and close has higher priority than <participant_key>.

Example:

from flask import Flask

app = Flask(__name__)
app.add_url_rule('/<poll_key>/close', 'close',
                 lambda **kwargs: 'close\t' + str(kwargs))
app.add_url_rule('/<poll_key>/<participant_key>', 'p_key',
                 lambda **kwargs: 'p_key\t' + str(kwargs))


client = app.test_client()

print client.get('/example-poll-key/close').data
print client.get('/example-poll-key/example-participant-key').data

This outputs:

close   {'poll_key': u'example-poll-key'}
p_key   {'participant_key': u'example-participant-key', 'poll_key': u'example-poll-key'}

Looks like this is the right behaviour.

like image 71
tbicr Avatar answered Oct 17 '22 17:10

tbicr