uvicorn是一个基于asyncio开发的一个轻量级高效的web服务器框架
uvicorn 设计的初衷是想要实现两个目标:
它目前支持http, websockets, Pub/Sub 广播,并且可以扩展到其他协议和消息类型。
官网:uvicorn
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(名字可以自取)
在这个文件中,来编写一个简单的服务器应用。
# coding: utf-8
async def hello_word(message, channels):
content = b"Hello World
"
resp = {
"status": 200,
"headers": [[b'content-type', b'text/html']],
"content": content,
}
await channels['reply'].send(resp)
写好以后, 先来尝试运行一下,再看代码含义。
运行方式是: 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号字体的HelloWorld,也就是我们代码中定义的content的字符串内容。
Ok, 服务器跑起来了,接下来,我们看一下代码是如何将内容返回给浏览器的。
在代码中我们定义了一个协程函数,ASGI的协议要求应用应该对外暴露一个可接受message和channels 这两个参数的协程可调用对象(callable):
是具有以下属性的对象:
uvicorn中的message区别于ASGI中的消息:
举例:
传进来一个HTTP请求可能会是类似下面的message和channels.
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>
}
为了做出响应,应用程序需要向reply的channel发送(.send())一个http响应,例如:
await channels["reply"].send({
"status": 200,
"headers": [
[b'content-type', b'text/plain'],
],
'content': b'Hellow, world'
})
参考:Uvicorn初体验