designed27
designed27

Reputation: 55

How to create dynamic subdomains in a Flask application

I am trying to setup variable route handling in a Flask application such as described in this answer: Dynamic Subdomain Handling in a Web App (Flask)

However, I want to be able to recognize certain subdomains BEFORE they are caught by the variable route so I can use the flask-restful api extension (Routing with RESTful).

For example, I have tried the following:

@app.route('/', subdomain="<user>", defaults={'path':''})
@app.route('/<path:path>', subdomain="<user>")
def user_profile(user,path):
    pass

class Api(restful.Resource):
    def get(self):
        #Do Api things.

api.add_resource(Api, '/v1', subdomain="api")

When I test this, all of URLs go to the variable route handler and call user_prof(). I tried putting the api route first and the standard @app.route rule second and vice versa but there was no change.

Am I missing some other parameter or need to go deeper in Flask to make this happen?

Update:

The URL patterns I am trying to match are like this:

user1.mysite.com -> handled by user_profile()
user2.mysite.com -> handled by user_profile()
any_future_string.mysite.com -> handled by user_profile()
api.mysite.com/v1 -> handled by Api class

Other cases include:

www.mysite.com -> handled by index_display()
mysite.com -> handled by index_display()

Upvotes: 2

Views: 2843

Answers (2)

designed27
designed27

Reputation: 55

To keep it simple, I redesigned the logic of my application into two distinct parts.

This way the Flask application only handles the API endpoint logic. The user profile logic is handled by another application. I can now add multiple Resources to the API application without worry about breaking the routing.

Upvotes: 0

Matthew Scragg
Matthew Scragg

Reputation: 4638

@app.before_request
def before_request():
    if 'api' == request.host[:-len(app.config['SERVER_NAME'])].rstrip('.'):
        redirect(url_for('api'))


@app.route('/', defaults={'path': ''}, subdomain='api')
@app.route('/<path:path>', subdomain='api')
def api(path):
    return "hello"

This should work. Add your api version to the path if needed or that could be processed by your API class.

Upvotes: 3

Related Questions