Eva*_*ahn 84 python routes flask
我有一个前缀,我想添加到每个路由.现在我在每个定义中为路径添加一个常量.有没有办法自动执行此操作?
PREFIX = "/abc/123"
@app.route(PREFIX + "/")
def index_page():
return "This is a website about burritos"
@app.route(PREFIX + "/about")
def about_page():
return "This is a website about burritos"
Run Code Online (Sandbox Code Playgroud)
Mig*_*uel 84
您可以将路线放在蓝图中:
bp = Blueprint('burritos', __name__,
template_folder='templates')
@bp.route("/")
def index_page():
return "This is a website about burritos"
@bp.route("/about")
def about_page():
return "This is a website about burritos"
Run Code Online (Sandbox Code Playgroud)
然后使用前缀向应用程序注册蓝图:
app = Flask(__name__)
app.register_blueprint(bp, url_prefix='/abc/123')
Run Code Online (Sandbox Code Playgroud)
Sea*_*ira 66
答案取决于您如何提供此应用程序.
假设您要在WSGI容器(mod_wsgi,uwsgi,gunicorn等)中运行此应用程序; 你需要在该前缀下实际挂载应用程序作为WSGI容器的子部分(任何说WSGI的东西)并将APPLICATION_ROOT
配置值设置为你的前缀:
app.config["APPLICATION_ROOT"] = "/abc/123"
@app.route("/")
def index():
return "The URL for this page is {}".format(url_for("index"))
# Will return "The URL for this page is /abc/123/"
Run Code Online (Sandbox Code Playgroud)
设置APPLICATION_ROOT
配置值只是将Flask的会话cookie限制为该URL前缀.Flask和Werkzeug优秀的WSGI处理功能将为您自动处理其他所有内容.
如果您不确定第一段的含义,请查看此示例应用程序,其中安装了Flask:
from flask import Flask, url_for
from werkzeug.serving import run_simple
from werkzeug.wsgi import DispatcherMiddleware
app = Flask(__name__)
app.config['APPLICATION_ROOT'] = '/abc/123'
@app.route('/')
def index():
return 'The URL for this page is {}'.format(url_for('index'))
def simple(env, resp):
resp(b'200 OK', [(b'Content-Type', b'text/plain')])
return [b'Hello WSGI World']
app.wsgi_app = DispatcherMiddleware(simple, {'/abc/123': app.wsgi_app})
if __name__ == '__main__':
app.run('localhost', 5000)
Run Code Online (Sandbox Code Playgroud)
另一方面,如果您将在其WSGI容器的根目录下运行Flask应用程序并代理对它的请求(例如,如果它是FastCGI,或者如果nginx是proxy_pass
-ing请求子端点)对于您的独立uwsgi
/ gevent
服务器,您可以:
DispatcherMiddleware
from werkzeug
(或PrefixMiddleware
来自su27的答案)将您的应用程序分装到您正在使用的独立WSGI服务器中.(请参阅上面正确的子安装应用程序以获取要使用的代码的示例).su2*_*u27 38
你应该注意,这APPLICATION_ROOT
不是为了这个目的.
您所要做的就是编写一个中间件来进行以下更改:
PATH_INFO
以处理前缀url.SCRIPT_NAME
以生成带前缀的URL.像这样:
class PrefixMiddleware(object):
def __init__(self, app, prefix=''):
self.app = app
self.prefix = prefix
def __call__(self, environ, start_response):
if environ['PATH_INFO'].startswith(self.prefix):
environ['PATH_INFO'] = environ['PATH_INFO'][len(self.prefix):]
environ['SCRIPT_NAME'] = self.prefix
return self.app(environ, start_response)
else:
start_response('404', [('Content-Type', 'text/plain')])
return ["This url does not belong to the app.".encode()]
Run Code Online (Sandbox Code Playgroud)
用中间件包装你的应用程序,如下所示:
from flask import Flask, url_for
app = Flask(__name__)
app.debug = True
app.wsgi_app = PrefixMiddleware(app.wsgi_app, prefix='/foo')
@app.route('/bar')
def bar():
return "The URL for this page is {}".format(url_for('bar'))
if __name__ == '__main__':
app.run('0.0.0.0', 9010)
Run Code Online (Sandbox Code Playgroud)
访问http://localhost:9010/foo/bar
,
你会得到正确的结果: The URL for this page is /foo/bar
如果需要,请不要忘记设置cookie域.
这个解决方案由Larivact的要点给出.这APPLICATION_ROOT
不是为了这份工作,虽然它看起来像是.这真的令人困惑.
这更像是一个python答案,而不是Flask/werkzeug答案; 但它很简单而且很有效.
如果像我一样,您希望应用程序设置(从.ini
文件加载)也包含Flask应用程序的前缀(因此,不要在部署期间设置值,但在运行时),您可以选择以下内容:
def prefix_route(route_function, prefix='', mask='{0}{1}'):
'''
Defines a new route function with a prefix.
The mask argument is a `format string` formatted with, in that order:
prefix, route
'''
def newroute(route, *args, **kwargs):
'''New function to prefix the route'''
return route_function(mask.format(prefix, route), *args, **kwargs)
return newroute
Run Code Online (Sandbox Code Playgroud)
可以说,这是有点hackish的,并且依赖于该瓶路由功能的事实,需要一个route
作为第一个位置参数.
你可以像这样使用它:
app = Flask(__name__)
app.route = prefix_route(app.route, '/your_prefix')
Run Code Online (Sandbox Code Playgroud)
注意:在前缀中使用变量(例如通过将其设置为/<prefix>
)是可能的,然后在您使用您的装饰的函数中处理此前缀@app.route(...)
.如果这样做,您显然必须prefix
在装饰函数中声明参数.此外,您可能希望根据某些规则检查提交的前缀,如果检查失败则返回404.为了避免404定制的重新实施,请from werkzeug.exceptions import NotFound
然后raise NotFound()
如果检查失败.
因此,我认为对此的有效答案是:应该在开发完成时使用的实际服务器应用程序中配置前缀。Apache、nginx 等
但是,如果您希望在调试中运行 Flask 应用程序的同时在开发过程中使用它,请查看此要点。
DispatcherMiddleware
来拯救你了!我将在这里复制代码以供后代使用:
"Serve a Flask app on a sub-url during localhost development."
from flask import Flask
APPLICATION_ROOT = '/spam'
app = Flask(__name__)
app.config.from_object(__name__) # I think this adds APPLICATION_ROOT
# to the config - I'm not exactly sure how!
# alternatively:
# app.config['APPLICATION_ROOT'] = APPLICATION_ROOT
@app.route('/')
def index():
return 'Hello, world!'
if __name__ == '__main__':
# Relevant documents:
# http://werkzeug.pocoo.org/docs/middlewares/
# http://flask.pocoo.org/docs/patterns/appdispatch/
from werkzeug.serving import run_simple
from werkzeug.wsgi import DispatcherMiddleware
app.config['DEBUG'] = True
# Load a dummy app at the root URL to give 404 errors.
# Serve app at APPLICATION_ROOT for localhost development.
application = DispatcherMiddleware(Flask('dummy_app'), {
app.config['APPLICATION_ROOT']: app,
})
run_simple('localhost', 5000, application, use_reloader=True)
Run Code Online (Sandbox Code Playgroud)
现在,当将上述代码作为独立的 Flask 应用程序运行时,http://localhost:5000/spam/
将显示Hello, world!
.
在对另一个答案的评论中,我表示我希望做这样的事情:
from flask import Flask, Blueprint
# Let's pretend module_blueprint defines a route, '/record/<id>/'
from some_submodule.flask import module_blueprint
app = Flask(__name__)
app.config['APPLICATION_ROOT'] = '/api'
app.register_blueprint(module_blueprint, url_prefix='/some_submodule')
app.run()
# I now would like to be able to get to my route via this url:
# http://host:8080/api/some_submodule/record/1/
Run Code Online (Sandbox Code Playgroud)
适用DispatcherMiddleware
于我人为的例子:
from flask import Flask, Blueprint
from flask.serving import run_simple
from flask.wsgi import DispatcherMiddleware
# Let's pretend module_blueprint defines a route, '/record/<id>/'
from some_submodule.flask import module_blueprint
app = Flask(__name__)
app.config['APPLICATION_ROOT'] = '/api'
app.register_blueprint(module_blueprint, url_prefix='/some_submodule')
application = DispatcherMiddleware(Flask('dummy_app'), {
app.config['APPLICATION_ROOT']: app
})
run_simple('localhost', 5000, application, use_reloader=True)
# Now, this url works!
# http://host:8080/api/some_submodule/record/1/
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
62918 次 |
最近记录: |