[Python] Первый опыт Uvicorn

задняя часть Python сервер

Оригинальная ссылка:vim тип II.com/post/2018/0…

Знакомство с увикорном

uvicornоснован наasyncioРазработана легкая и эффективная структура веб-сервера.

Официальный сайт:www.uvicorn.org

uvicornПервоначальный замысел дизайна состоит в достижении двух целей:

  • использоватьuvloopиhttptoolsдобиться чрезвычайно быстрогоasyncioсервер.
  • реализовать на основеASGI(异步服务器网关接口)Минимальный интерфейс прикладного программирования.

в настоящее время поддерживаетhttp,websockets,Pub/SubШироковещательный и может быть расширен на другие протоколы и типы сообщений.

Установите и используйте

uvicornПоддерживает только python 3.5.3 и выше, мы можем быстро установить его через pip3.

Совет: рекомендуется использовать то же, что и я, напрямую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

Следующее сообщение указывает на то, что сервер успешно запущен

(Информация включает адрес доступа и номер порта, а также идентификатор потока, в котором работает рабочий процесс)

[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строковое содержимое.

Хорошо, сервер запущен. Теперь давайте посмотрим, как код возвращает содержимое в браузер.

Анализ интерфейса

В коде мы определяем функцию сопрограммы.Протокол ASGI требует, чтобы приложение предоставляло приемлемыйmessageиchannelsСопрограмма, вызываемая с этими двумя параметрами:

  • message: сообщение ASGI (но есть отличия, см. ниже)
  • channels: словарь (<unicode string> : <channel interface>)

<channel interface>является объектом со следующими свойствами:

  • .send(message) Сопрограмма, которая отправляет возвращаемое сообщение. по желанию
  • .receive() Сопрограмма, которая получает входящие сообщения. по желанию
  • .назовитеunicodeСтрока, уникальный идентификатор канала. по желанию

в увикорнеmessageОтличие от сообщений в ASGI:

  • Сообщение также включаетchannelКлючевые слова, различающие типы сообщений, например:'channel':'http.request'
  • Сообщение не включает, например.reply_channelилиbody_channelТакойchannelимя, ноchannelsСловарь для просмотра разрешенchannelтип.

Пример:

Входящий 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'Hello, world'
})