美文网首页
[Python]Uvicorn初体验

[Python]Uvicorn初体验

作者: Vimiix | 来源:发表于2018-02-26 12:23 被阅读0次

    原文链接:http://vimiix.com/post/2018/02/26/first-practise-of-uvicorn/

    uvicorn简介

    uvicorn是一个基于asyncio开发的一个轻量级高效的web服务器框架。

    官网:http://www.uvicorn.org

    uvicorn 设计的初衷是想要实现两个目标:

    它目前支持httpwebsocketsPub/Sub 广播,并且可以扩展到其他协议和消息类型。

    安装使用

    uvicorn 仅支持python 3.5.3以上版本,我们可以通过pip3来快速的安装。

    Tip:建议和我一样,直接使用pip3来安装,就不用关心系统默认版本了。
    ➜ pip3 install uvicorn
        ...
    Successfully installed gunicorn-19.7.1 httptools-0.0.10 
    uvicorn-0.0.15 uvloop-0.9.1 websockets-4.0.1
    

    安装成功以后。就可以来编写我们的服务器应用代码了。

    先创建一个应用文件app.py(名字可以自取)

    在这个文件中,来编写一个简单的服务器应用。

    1 # coding:utf-8
    2
    3 async def hello_world(message, channels):
    4     content = b'<h1>Hello World</h1>'
    5     resp = {
    6         'status': 200,
    7         'headers': [[b'content-type', b'text/html'],],
    8         'content': content,
    9     }
    10     await channels['reply'].send(resp)
    11
    

    写好以后,先来尝试运行一下,跑通了再看代码中具体内容的含义。

    运行方式是: uvicorn 文件名:callable对象名

    ➜ uvicorn app:hello_world
    

    提示下面的内容就表示服务器启动成功了

    (信息中包括了访问地址和端口号,以及worker运行的线程id)

    [2018-02-26 00:48:52 +0800] [55984] [INFO] Starting gunicorn 19.7.1
    [2018-02-26 00:48:52 +0800] [55984] [INFO] Listening at: http://127.0.0.1:8000 (55984)
    [2018-02-26 00:48:52 +0800] [55984] [INFO] Using worker: uvicorn 0.0.15
    [2018-02-26 00:48:52 +0800] [55987] [INFO] Booting worker with pid: 55987
    
    

    这时候我们在浏览器中访问http://127.0.0.1:8000,会看到网页上显示出 h1 号字体的Hello World,也就是我们代码中定义的 content 的字符串内容。

    OK,服务器跑起来了,接下来,我们来看一下代码是如何将内容返回给浏览器的。

    接口分析

    在代码中我们定义了一个协程函数,ASGI的协议要求应用应该对外暴露一个可接受 messagechannels 这两个参数的协程可调用对象(callable):

    • message:一个ASGI消息(但有区别,见下文)
    • channels:一个字典( <unicode string> : <channel interface>

    <channel interface> 是具有以下属性的对象:

    • .send(message) 一个协程,用于发送返回的消息。可选
    • .receive() 一个协程,用于接收进来的消息。可选
    • .name 一个unicode字符串,channel的唯一标识。可选

    uvicorn中的message区别于ASGI中的消息:

    • 消息还包括一个channel关键字,区别消息类型,例如:'channel':'http.request'
    • 消息不包括例如reply_channelbody_channel这样的channel名称,,而是channels字典可以查看允许的channel类型。

    举例:

    传进来的一个HTTP请求可能会是类似下面这样的messagechannels.

    message

    {
        'channel': 'http.request',
        'scheme': 'http',
        'root_path': '',
        'server': ('127.0.0.1', 8000),
        'http_version': '1.1',
        'method': 'GET',
        'path': '/',
        'headers': [
            [b'host', b'127.0.0.1:8000'],
            [b'user-agent', b'curl/7.51.0'],
            [b'accept', b'*/*']
        ]
    }
    

    channels

    {
        'reply': <ReplyChannel>
    }
    

    为了做出响应,应用程序需要向replychannel发送(.send())一个http响应,例如:

    await channels['reply'].send({
        'status': 200,
        'headers': [
            [b'content-type', b'text/plain'],
        ],
        'content': b'Hello, world'
    })
    

    相关文章

      网友评论

          本文标题:[Python]Uvicorn初体验

          本文链接:https://www.haomeiwen.com/subject/iyxyxftx.html