在 Flask 作为服务端时手动推送情境的解决方案和拆解回调的使用方法详解
  TEZNKK3IfmPf 2024年03月29日 15 0

手动推送情境

如果尝试访问请求或在请求上下文之外使用它的任何内容,将收到以下错误消息:

RuntimeError: Working outside of request context.

这通常只在测试代码期望一个活动请求时发生。一个选项是使用测试客户端来模拟完整的请求。或者可以在block_request_Context()中使用test,块中运行的所有内容都可以访问请求并填写测试数据。:

def generate_report(year):
    format = request.args.get('format')
    ...

with app.test_request_context(
        '/make_report/2017', data={'format': 'short'}):
    generate_report()

如果在代码中的其他地方看到与测试无关的错误,则表明应该将代码移到视图函数。

拆解回调

拆除回调与请求分派无关,但在情况弹出时由情况调用。即使在调度过程中存在未处理的异常和手动推送场景,也会调用这些函数。这意味着不能保证请求调度的任何其他部分将首先运行。确保以不依赖于其他回调且不会失败的方式编写这些函数。 在测试过程中,延迟请求的结束和弹出场景非常有用,以便可以在测试功能中访问它们的数据。在withblock_Client()中使用test保存情况,直到withblock结束。

from flask import Flask, request

app = Flask(__name__)

@app.route('/')
def hello():
    print('during view')
    return 'Hello, World!'

@app.teardown_request
def show_teardown(exception):
    print('after with block')

with app.test_request_context():
    print('during with block')

# teardown functions are called after the context with block exits

with app.test_client() as client:
    client.get('/')
    # the contexts are not popped even though the request ended
    print(request.path)

# the contexts are popped and teardown functions are called after
# the client with block exists

测试 JSON API

Flask非常支持JSON,是创建JSON API的热门选择。使用JSON生成请求并检查响应中的JSON数据非常方便:

from flask import request, jsonify

@app.route('/api/auth')
def auth():
    json_data = request.get_json()
    email = json_data['email']
    password = json_data['password']
    return jsonify(token=generate_token(email, password))

with app.test_client() as c:
    rv = c.post('/api/auth', json={
        'email': '[email protected]', 'password': 'secret'
    })
    json_data = rv.get_json()
    assert verify_token(email, json_data['token'])

在测试客户端方法中传递json参数,将请求数据设置为json序列化对象,并将内容类型设置为application/json。可以使用get_Json从请求或响应中获取Json数据。

静态文件

动态web应用程序还需要静态文件,通常是CSS和JavaScript文件。

理想情况下,服务器已经配置为为提供静态文件服务。

然而,Flask也可以在开发过程中做得很好。

只需在包或模块旁边创建一个名为static的文件夹。静态文件位于应用程序的/static中。使用特定的“静态”端点生成相应的URL

url_for('static', filename='style.css')

这个静态文件在文件系统中的位置应该是 static/style.css

Cookies

要访问cookies,可以使用cookies属性。

可以使用响应对象_ Cookie方法的集合来设置Cookie。

请求对象的cookie属性是一个包含客户端传输的所有cookie的字典。在Flask中,如果使用会话,则不应直接使用cookies,因为会话更安全。 阅读cookies:

from flask import request

@app.route('/')
def index():
    username = request.cookies.get('username')
    # use cookies.get(key) instead of cookies[key] to not get a
    # KeyError if the cookie is missing.

储存 cookies:

from flask import make_response

@app.route('/')
def index():
    resp = make_response(render_template(...))
    resp.set_cookie('username', 'the username')
    return resp

请注意,cookies是在响应对象上设置的。通常,只从视图函数返回字符串,Flask会将它们转换为响应对象。如果要显式转换,可以使make_Theresponse()函数,然后修改它。使用延迟请求回调方案,可以设置没有响应对象的cookie。

流内容

有时,需要将大量数据传输到客户端,而不需要将其保存在内存中。

想将操作中生成的数据直接发送到客户端而不通过文件系统时,应该怎么办? 答案是使用生成器和直接响应。

from flask import Response

@app.route('/large.csv')
def generate_large_csv():
    def generate():
        for row in iter_all_rows():
            yield ','.join(row) + '\n'
    return Response(generate(), mimetype='text/csv')

上面示例的技巧是从Jinja2环境中获取应用的模板对象,调用stream()而不是render(),并返回stream对象而不是字符串。

from flask import Response

def stream_template(template_name, **context):
    app.update_template_context(context)
    t = app.jinja_env.get_template(template_name)
    rv = t.stream(context)
    rv.enable_buffering(5)
    return rv

@app.route('/my-large-page.html')
def render_large_template():
    rows = iter_all_rows()
    return Response(stream_template('the_template.html', rows=rows))

由于我们绕过Flask的模板渲染函数并使用模板对象本身,所以我们需要调用update_template_Context()来确保渲染的内容得到更新。

通过这种方式,模板遍历流内容。由于每次生成内容时服务器都会将内容发送给客户端,因此可能需要缓存来保存内容。我们使用了rvenable_Buffering(大小)。5是合理的违约。

访问和修改会话

with app.test_client() as c:
    rv = c.get('/')
    assert flask.session['foo'] == 42

但是,在发出请求之前,此方法无法修改会话或访问会话。

自Flask 0.8以来,我们提供了“会话处理”来在测试环境中打开和修改会话。

最后,会话被保存并准备好由客户端进行测试。处理的会话独立于后端实际使用的会话:

with app.test_client() as c:
    with c.session_transaction() as sess:
        sess['a_key'] = 'a value'

    # once this is reached the session was stored and ready to be used by the client
    c.get(...)
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2024年03月29日 0

暂无评论

推荐阅读
  TEZNKK3IfmPf   24天前   21   0   0 json
TEZNKK3IfmPf