Search code examples
flaskpython-decoratorsflask-restfulflask-login

how to implement flask redirect decorator


I have a flask application instance running on port 80 and another instance of same app on port 8080. I want all the users to use port 80 for all the urls except for one url named /parallel_url. So when they visit https://server:80/parallel_url it redirects to https://server:8080/parallel_url. I also don't want users to be able to visit any other url (excluding /parallel_url) on port 8080 and i want them to be redirected to post 80 so if they visit https://server:8080/* it needs to redirect to https://server:80/*

I am planning to write a decorator which sees if the current url is anything other than /parallel_url and redirect it to the 80. So if a user is visiting this in port 8080 they need to get redirected to 80


def parallel_redirect(func):

    @functools.wraps(func)
    def wrapper():
        """
           What to do here to redirect to 80
        """
        if request.url_rule == "/parallel_url":
            value = func()
        return value
    return wrapper

@mod.route('/parallel_url')
@parallel_redirect
@login_required
def parallel_url():
    template = tpl_env.get_template('my_index.html')
    x = "some data from db"
    y = "some other data from db"
    return template.render(x=x,y=y)

update: I found an a variable which tells me what port i am on. please refer the code below


def parallel_redirect(func):

    @functools.wraps(func)
    def wrapper():
        if os.environ.curr_port == 8080:
            if request.url_rule != "/parallel_url":
               # code to redirect to "https://server:80/"+request.url_rule
        elif os.environ.curr_port == 80:
            if request.url_rule == "/parallel_url":
               # code to redirect to "https://server:8080/"+request.url_rule
        else:
             value = func()

        return value
    return wrapper

@mod.route('/parallel_url')
@parallel_redirect
@login_required
def parallel_url():
    template = tpl_env.get_template('my_index.html')
    x = "some data from db"
    y = "some other data from db"
    return template.render(x=x,y=y)

Solution

  • I would just catch all possible combinations and use the redirect function to call the other server. You just need the current port from the request, like described here

    from flask import redirect
    
    def parallel_redirect(func):
      @functools.wraps(func):
        request_port = request.environ.get('REMOTE_PORT')
        if request.url_rule == "/parallel_url":
          if request_port == 80:
            # /parallel_url, but on port 80, redirect
            return redirect("https://...:8080/parallel_url", code=302)
          else:
            return func()
        elif request_port == 8080:
          # not /parallel_url, but on port 8080, also redirect
          return redirect("https://...:80" + request.url_rule, code=302)
        # finally, not /parallel_url, and on port 80, so we're all good
        return func()