API with Flask:将参数传递给基于 URL 的蓝图(为每个视图强制执行 url 参数)
API with Flask: hand parameter to blueprint based on URL (enforce url parameter for EVERY view)
我想快速设置一个 API 作为草稿,我发现 Flask 具有我想要的轻量级特性。
但是,作为 Flask 的新手,我仍然不确定如何将我的文件布局设计得既漂亮又清晰,以便与多个贡献者一起工作,随着时间的推移充实 API。
到目前为止我得到的是,我需要蓝图来包含我来自其他模块的路线。这就像一个魅力。但现在让我们进入棘手的部分。
我们数据库的设计方式是,我们对多种语言使用相同的表。
API 的访问将按语言进行,因此使用语言作为参数并没有多大意义,语言对于确定我们对哪些表执行操作很重要。这是根据每个请求完成的。
基本上我希望 API 看起来像这样:
/v1.0/<language-code>/entries
/v1.0/<language-code>/sentences
旁注:
条目的路由来自 v1/entries/access.py
。
(我采纳了将 api 的实体打包成更好的文件结构方案的建议)
那么我如何确保我的视图(路由链接到的函数)知道请求了哪个 language-code
。
是否有一种很好的方法可以通过在应用程序或其他东西中使参数全局可用来实现它,或者我应该从请求的 url 中提取它?
我也乐于接受黑客攻击! :3
// 编辑:
我发现了这个:http://flask.pocoo.org/docs/0.10/patterns/urlprocessors/
然而,这是正确的方向,提取语言代码并将其写入 g,稍后仍需要我验证该语言是否可用。
我想验证(必须提供的)语言是否有效,如果无效,return 一个错误。
@app.url_value_preprocessor
def pull_lang_code(endpoint, values):
// do some verification in here
if values:
g.lang_code = values.pop('lang_code', None)
因此,如果验证失败,则以错误响应,如果没有失败,我可以在我的所有函数中假设语言代码存在于某处(可能在 g
中)并且可以访问
你可以得到 language_code
作为函数的参数。
blueprint = Blueprint('entries', __name__)
@blueprint.route('/v1.0/<language_code>/entries')
def get_entries(language_code):
return jsonify({'result': "your language code is " + language_code})
name language-code
不允许,参数名应该是有效的 python 变量名。
我不确定这是否可行,但我偶然发现了 before_request
装饰器,它似乎可以满足我的要求:
from flask import Flask, g, abort, jsonify, request
from v1.entries import access as entry_access
app = Flask(__name__)
# load the endpoints
PRE = "/v1.0/<lang_code>"
app.register_blueprint(entry_access.entries, url_prefix=PRE+"/entries")
@app.before_request
def verify_language():
# check if there are any parameters in the url and get lang_code
url_params = request.view_args
lang = (url_params and url_params.pop('lang_code', None)) or None
# if lang_code is given, make sure it is valid
if lang:
LANG = ["eng-code", "swe-code"]
if lang in LANG or lang == "global":
# set globally to provide access for all views
g.lang = lang
else:
return jsonify({"error": "Invalid Parameters (lang_code)"})
我想快速设置一个 API 作为草稿,我发现 Flask 具有我想要的轻量级特性。
但是,作为 Flask 的新手,我仍然不确定如何将我的文件布局设计得既漂亮又清晰,以便与多个贡献者一起工作,随着时间的推移充实 API。
到目前为止我得到的是,我需要蓝图来包含我来自其他模块的路线。这就像一个魅力。但现在让我们进入棘手的部分。
我们数据库的设计方式是,我们对多种语言使用相同的表。
API 的访问将按语言进行,因此使用语言作为参数并没有多大意义,语言对于确定我们对哪些表执行操作很重要。这是根据每个请求完成的。
基本上我希望 API 看起来像这样:
/v1.0/<language-code>/entries
/v1.0/<language-code>/sentences
旁注:
条目的路由来自 v1/entries/access.py
。
(我采纳了将 api 的实体打包成更好的文件结构方案的建议)
那么我如何确保我的视图(路由链接到的函数)知道请求了哪个 language-code
。
是否有一种很好的方法可以通过在应用程序或其他东西中使参数全局可用来实现它,或者我应该从请求的 url 中提取它?
我也乐于接受黑客攻击! :3
// 编辑: 我发现了这个:http://flask.pocoo.org/docs/0.10/patterns/urlprocessors/ 然而,这是正确的方向,提取语言代码并将其写入 g,稍后仍需要我验证该语言是否可用。
我想验证(必须提供的)语言是否有效,如果无效,return 一个错误。
@app.url_value_preprocessor
def pull_lang_code(endpoint, values):
// do some verification in here
if values:
g.lang_code = values.pop('lang_code', None)
因此,如果验证失败,则以错误响应,如果没有失败,我可以在我的所有函数中假设语言代码存在于某处(可能在 g
中)并且可以访问
你可以得到 language_code
作为函数的参数。
blueprint = Blueprint('entries', __name__)
@blueprint.route('/v1.0/<language_code>/entries')
def get_entries(language_code):
return jsonify({'result': "your language code is " + language_code})
name language-code
不允许,参数名应该是有效的 python 变量名。
我不确定这是否可行,但我偶然发现了 before_request
装饰器,它似乎可以满足我的要求:
from flask import Flask, g, abort, jsonify, request
from v1.entries import access as entry_access
app = Flask(__name__)
# load the endpoints
PRE = "/v1.0/<lang_code>"
app.register_blueprint(entry_access.entries, url_prefix=PRE+"/entries")
@app.before_request
def verify_language():
# check if there are any parameters in the url and get lang_code
url_params = request.view_args
lang = (url_params and url_params.pop('lang_code', None)) or None
# if lang_code is given, make sure it is valid
if lang:
LANG = ["eng-code", "swe-code"]
if lang in LANG or lang == "global":
# set globally to provide access for all views
g.lang = lang
else:
return jsonify({"error": "Invalid Parameters (lang_code)"})