流
请求流
Sanic 允许你通过流来获取请求,如下。当请求结束,request.stream.get() 返回 None。只有 post、 put 和 patch 装饰器才能有流参数。
from sanic import Sanicfrom sanic.views import CompositionViewfrom sanic.views import HTTPMethodViewfrom sanic.views import stream as stream_decoratorfrom sanic.blueprints import Blueprintfrom sanic.response import stream, textbp = Blueprint('blueprint_request_stream')app = Sanic('request_stream')class SimpleView(HTTPMethodView):@stream_decoratorasync def post(self, request):result = ''while True:body = await request.stream.get()if body is None:breakresult += body.decode('utf-8')return text(result)@app.post('/stream', stream=True)async def handler(request):async def streaming(response):while True:body = await request.stream.get()if body is None:breakbody = body.decode('utf-8').replace('1', 'A')response.write(body)return stream(streaming)@bp.put('/bp_stream', stream=True)async def bp_handler(request):result = ''while True:body = await request.stream.get()if body is None:breakresult += body.decode('utf-8').replace('1', 'A')return text(result)async def post_handler(request):result = ''while True:body = await request.stream.get()if body is None:breakresult += body.decode('utf-8')return text(result)app.blueprint(bp)app.add_route(SimpleView.as_view(), '/method_view')view = CompositionView()view.add(['POST'], post_handler, stream=True)app.add_route(view, '/composition_view')if __name__ == '__main__':app.run(host='127.0.0.1', port=8000)
响应流
Sanic 允许您使用流方法将内容传输到客户端。此方法接受通过写入的 StreamingHTTPResponse 对象传递的协程回调。一个简单的例子如下:
from sanic import Sanicfrom sanic.response import streamapp = Sanic(__name__)@app.route("/")async def test(request):async def sample_streaming_fn(response):response.write('foo,')response.write('bar')return stream(sample_streaming_fn, content_type='text/csv')
这会在当你想要用流的方法将内容发送到来自外部服务的客户端的情况下变得有用,就像数据库。例如,你可以用流的方法将 asyncpg 提供的异步游标把数据记录发送到客户端:
@app.route("/")async def index(request):async def stream_from_db(response):conn = await asyncpg.connect(database='test')async with conn.transaction():async for record in conn.cursor('SELECT generate_series(0, 10)'):response.write(record[0])return stream(stream_from_db)
