Разработка проекта на aioworkers - aioworkers/aioworkers GitHub Wiki

Создание проекта заключается в создании модуля со специальными колбеками конфигурирующими систему запуска.

Модуль может включать в себя(и обычно включает) один или несколько конфигурационных файлов.

Конфигурационные файлы при запуске сливаются в одну конфигурацию. Конфигурация представляет из себя то из чего состоит система, также могут определяться связи между компонентами. Конфигурация реализует одну из основных идей - возможность получить понимание о системе и её составе, при чтении кода, не вдаваясь в детали реализации компонентов. С этой же целью в конфигурации указываются связи.

Итак, приступим к созданию проекта. Наш проект будет встречать запросы по http и складывать тело запроса в файл. Так как наш проект будет включать конфигурационные файлы, оформим его в виде пакета с составом:

keeper/
    __init__.py
    config.yaml
    web.py
    worker.py

В первом приближении, на основе файловой структуры, видно примерный состав приложения, который частично детализируется в конфиге:

app:
    resources:
        /save:
            post: keeper.web.save
storage:
    cls: aioworkers.storage.filesystem.FileSystemStorage
    path: /path/to/storage

Конфиг в данном случае описан в формате yaml. При запуске приложения, для элементов у которых есть вложенный элемент cls, будут созданы соответствующие классы и размещены в корневом объекте context.

У элемента app нет cls, в данном случае мы доверимся слиянию конфигураций, cls появится при подключении плагина отвечающего за обслуживание по http. Объект app проанализирует свою конфигурацию, и добавит обслуживание /saveпо методу POST. keeper.web.save это путь до нашего обработчика.

Элемент storage на первый взгляд выглядит избыточным, нам же просто нужно сохранить в файл то, что приходит по http. Но он решает несколько важных задач. Во первых, наш сервис асинхронный, а значит мы должны использовать неблокирующий ввод/вывод. Во вторых, нам нужно где-то конфигурировать базовый путь.

Обработчик POST /save достаточно прост, он находится в файле web.py:

async def save(request):
    storage = request.app.context.storage
    data = await request.read()
    await storage.set('post.save', data)

Для запуска понадобится окружение и пакет aioworkers:

python3.6 -m venv env
. env/bin/activate
pip install aioworkers httptools

Теперь можно запустить наш сервис:

aioworkers aioworkers.net.web -c keeper/config.yaml --port 8080

Сервис запустится и будет готов обслуживать по http на порту 8080. aioworkers.net.web это модуль-плагин, привносит в конфигурацию класс для app. Вместо него можно установить пакет aioworkers-aiohttp, который самостоятельно подцепится как плагин при запуске благодаря префиксу. Он также привносит класс для app и является своего рода микропрослойкой между aioworkers и aiohttp. В каких-то случаях подойдет встроенный aioworkers.net.web, но у aiohttp возможности шире.

Мы можем трансформировать наш проект в плагин, для этого потребуется объявить конфиги в модуле __init__.py:

from pathlib import Path

BASE = Path(__file__).parent
configs = (
    BASE / 'config.yaml',
)

Установив дополнительно aioworkers-aiohttp, запускать можно так:

aioworkers keeper --port 8080

Попробуем отправить данные нашему сервису:

python -c "from urllib.request import urlopen; print(urlopen('http://localhost:8080/save', data=b'123').read())"

{to be continued}