Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Implement exception-based catchall host routing with flask & tests
from werkzeug.routing import Rule as BaseRule
class Rule(BaseRule):
except_hosts = []
def match(self, path):
""" Monkey patched version of the default Werkzeug behavior to achieve host matching with catchall.
By default, if host matching is enabled, the match is only done if the host is always provided, which is
unpractical. This modified version matches normally if host matching is not enabled. If host matching is
enabled, if it fails, and if the host is not part of a blacklist, it will try matching again without host
matching ('catch all').
host, route = path.split('|')
result = super().match(path)
if result is None and host and host not in self.except_hosts:
result = super().match('|' + route)
return result
def configure_app_host_routing(app, except_hosts):
app.url_rule_class = type('LocalRule', (Rule, ), {'except_hosts': except_hosts})
app.url_map.host_matching = True
from flask import Flask
app = Flask('test_app')
configure_app_host_routing(app, [''])
# add host-specific endpoint
@app.route('/<argument>', host='')
def specific_host_endpoint():
# add normal endpoint, could be a blueprint too.
def test():
### TEST
import unittest
from werkzeug.exceptions import NotFound
class TestHostRouting(unittest.TestCase):
def main_test(self):
m = app.url_map
# host specific endpoint is routed correctly for
('specific_host_endpoint', {'argument': 'yo'}),
with self.assertRaises(NotFound):
# host specific endpoint does not work for other domains
with self.assertRaises(NotFound):
with self.assertRaises(NotFound):
# normal endpoint works as expected
self.assertEqual(('test', {'id': '1'}), m.bind('').match('/test/1'))
self.assertEqual(('test', {'id': '1'}), m.bind('').match('/test/1'))
# normal endpoint doesn't work for specific host
with self.assertRaises(NotFound):
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.