为Python Flask应用程序创建代理

时间:2015-06-09 22:09:27

标签: python nginx proxy flask

我们有一个内部应用程序,后端是用Java编写的,前端是用HTML编写的,Javascript ..等等。该应用是使用nginx server托管的。但是,我有另一个Web应用程序是用Python烧瓶编写的,老板希望将这两个工具集成在一起。

例如,初始项目(Java解决方案)具有域

inv.datafireball.com 

管理员告诉我他可以用这种方式更改nginx的配置文件,路由可以mapped/proxy到另一台服务器上运行的第二个应用程序

inv.datafireball.com/competitor -> datafireball.com:5000

但是,根据我的研究,Python应用程序中的所有路径都需要以某种方式重新编码:/static/js/d3.js需要更改为/competitor/static/js/d3.js ...

我们对一些看起来非常有前景的路径进行了编码,然而,我们的Python应用程序相当大,并且在手动更改所有路径之后它确实是一个很大的问题。

如果有一种简单的方法可以将Python烧瓶应用程序映射/代理到用Java编写的现有应用程序并更改现有的Python代码,那么任何人都可以给我一个指导吗?

1 个答案:

答案 0 :(得分:2)

这是一个解决方案,需要对Flask应用程序进行miminal更改并且运行良好:

这就是它本质上的作用:我们告诉Nginx将一些特殊的标题传递给我们的代理烧瓶应用程序然后我们创建一个包装器(ReverseProxied)来拦截每个请求,提取由Nginx设置的标头并修改请求处理环境,以便它匹配我们想要的网址。

在Nginx中,在服务器指令中添加以下内容:

location /competitor {
    proxy_pass http://127.0.0.1:5001;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Scheme $scheme;
    proxy_set_header X-Script-Name /competitor;
}

在Flask中,将下面的类添加到主应用程序文件中(无论您在何处创建主Flask应用程序对象)

class ReverseProxied(object):
    def __init__(self, app):
        self.app = app

    def __call__(self, environ, start_response):
        script_name = environ.get('HTTP_X_SCRIPT_NAME', '')
        if script_name:
            environ['SCRIPT_NAME'] = script_name
            path_info = environ['PATH_INFO']
            if path_info.startswith(script_name):
                environ['PATH_INFO'] = path_info[len(script_name):]

        scheme = environ.get('HTTP_X_SCHEME', '')
        if scheme:
            environ['wsgi.url_scheme'] = scheme
        return self.app(environ, start_response)

最后,强制您的应用使用新的ReverseProxied中间件

app = Flask(__name__)
app.wsgi_app = ReverseProxied(app.wsgi_app)

您可以在http://flask.pocoo.org/snippets/35/

找到原始解决方案和代码段