I'm trying to implement routing based on the host of the requested URL for a Flask site I'm building.
Based on what I've read here and elsewhere, it seems like this should be possible with something like
from flask import Flask
application = Flask(__name__)
application.url_map.host_matching = True
@application.route("/", host="<prefix>.mydomain.com:<port>")
def mydomain(prefix='', port=0, **kwargs):
return 'This is My Domain: with prefix ' + prefix
@application.route("/", host="<prefix>.<project>elasticbeanstalk.com:<port>")
def test(prefix='', project='', port=0, **kwargs):
return 'You are reading from EB ' + project
@application.route("/", host="<host>:<port>")
def catchall(**kwargs):
return 'This is anything'
but this fails with 404 "page not found". Is there something else I need to do to get this working? The linked SO answer mentions "the need to specify the host for all routes when you set host_matching to true" but I'm not sure what this means or what it would look like (I thought that's what I had been doing above).
How do I route in Flask based on the domain of the requested URL?
If it matters, this site is hosted on AWS Elastic Beanstalk.
One way of debugging these situations is to just jump into a console and play with the underlying functions:
>>> from werkzeug.routing import Map, Rule
>>> m = Map([Rule('/', endpoint='endpoint', host='<host>.example.com:<port>')], host_matching=True)
>>> c = m.bind('open.example.com:888')
>>> c.match('/')
('endpoint', {'host': u'open', 'port': u'888'})
If it didn't match it would raise a NotFound exception.
You can run that command on one line
>>> Map([Rule('/', endpoint='endpoint', host='<host>.example.com:<port>')], host_matching=True).bind('open.example.com:888').match('/')
And get a really quick feedback loop about what you are doing wrong. The only thing I can't tell from your code example is what the actual host string looks like... and that's the important part. That's what you need to know and feed into the m.bind
call. So if you can tell me what the host string looks like in your particular situation I can definitely debug this for you.
An example host string provided by you was: www.myproject-elasticbeanstalk.com.
>>> Map([Rule('/', endpoint='endpoint', host='<prefix>.<project>-elasticbeanstalk.com')], host_matching=True).bind('www.myproject-elasticbeanstalk.com').match('/')
('endpoint', {'prefix': u'www', 'project': u'myproject'})
So a modified host string of '<prefix>.<project>-elasticbeanstalk.com'
matches that and would pass the prefix and project into the view. Maybe it's simply that you're trying to match on port numbers when the host strings don't include them?
来源:https://stackoverflow.com/questions/28544180/how-do-i-route-in-flask-based-on-the-domain-of-the-requested-url