aiomisc - это библиотека с различными утилитами для asyncio#
Вам, как программисту, знакомы проблемы, связанные с дизайном и обслуживанием программ. Одним из мест, которое может быть особенно сложным, является создание архитектуры программы, использующего асинхронный ввод-вывод.
Вот тут на сцену выходит aiomisc. Это библиотека Python, которая предоставляет набор служебных функций и классов для работы с асинхронным IO более интуитивно понятным и эффективным способом. Она построена используя библиотеку asyncio и предназначена для облегчения написания асинхронного кода разработчиками, который является надежным и масштабируемым.
С aiomisc вы можете воспользоваться такими мощными функциями, как: worker пул, connection пул, шаблон «предохранитель», и механизмы повторов такие как asyncbackoff и asyncretry чтобы сделать ваш асинхронный код более надежным и простым в обслуживании. В этой документации мы более подробно рассмотрим, что может предложить aiomisc и как он может помочь вам упростить разработку сервисов с asyncio.
Установка#
Возможна установка стандартными способами, такими как PyPI или установка из репозитория git напрямую.
Установка с PyPI:
pip3 install aiomisc
Установка из репозитория на github.com:
# Using git tool
pip3 install git+https://github.com/aiokitchen/aiomisc.git
# Alternative way using http
pip3 install \
https://github.com/aiokitchen/aiomisc/archive/refs/heads/master.zip
Пакет содержит несколько дополнений, и вы можете установить дополнительные зависимости, если вы укажете их таким образом.
Вместе с uvloop
pip3 install "aiomisc[uvloop]"
Вместе с aiohttp:
pip3 install "aiomisc[aiohttp]"
Полная таблица дополнений ниже:
пример |
описание |
|---|---|
|
Для запуска приложений написанных с aiohttp. |
|
Для запуска ASGI приложений |
|
|
|
планирование задач с библиотекой croniter |
|
|
|
Можете использовать rich для логирования |
|
|
|
используйте uvloop как основной event-loop |
Вы можете комбинировать эти значения разделяя их запятыми, пример:
pip3 install "aiomisc[aiohttp,cron,rich,uvloop]"
Быстрый старт#
В этом разделе будет рассказано, как эта библиотека создает и использует цикл обработки событий и создает службы. Конечно, обо всем тут не напишешь, но о многом можно прочитать в разделе Учебник, и всегда можно обратиться к разделу Модули и разделу Описание API для справки.
Eventloop и entrypoint#
Сначала рассмотрим этот простой пример:
import asyncio
import logging
import aiomisc
log = logging.getLogger(__name__)
async def main():
log.info('Starting')
await asyncio.sleep(3)
log.info('Exiting')
if __name__ == '__main__':
with aiomisc.entrypoint(log_level="info", log_format="color") as loop:
loop.run_until_complete(main())
Этот код объявляет асинхронную функцию main(), которая завершается через 3 секунды. Казалось бы, ничего интересного, но все дело в entrypoint.
Что делает entrypoint, казалось бы не так уж и много, она создает event-loop и передает управление пользователю. Однако под капотом настраивается журналирование в отдельном потоке, создается пул потоков, запускаются сервисы, но об этом позже и сервисов в данном примере нет.
В принципе вы можете не использовать точку входа, а просто создать eventloop и установите его по умолчанию для текущего потока:
import asyncio
import aiomisc
# * Installs uvloop event loop is it's has been installed.
# * Creates and set `aiomisc.thread_pool.ThreadPoolExecutor`
# as a default executor
# * Sets just created event-loop as a current event-loop for this thread.
aiomisc.new_event_loop()
async def main():
await asyncio.sleep(1)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Приведенный выше пример полезен, если в вашем коде уже неявно используется созданный eventloop, тогда вам придется изменить меньше кода, просто добавьте aiomisc.new_event_loop() и все вызовы asyncio.get_event_loop() вернет созданный экземпляр.
Однако можно обойтись и одним вызовом. Следующий пример закрывает неявно созданный eventloop asyncio и устанавливает новый:
import asyncio
import aiomisc
async def main():
await asyncio.sleep(3)
if __name__ == '__main__':
loop = aiomisc.new_event_loop()
loop.run_until_complete(main())
Сервисы#
Главное, что делает точка входа, — это запускает и корректно останавливает «Сервисы».
Концепция «Сервис», в этой библиотеке, означает класс, наследованный от класса aiosmic.Service и реализующий метод async def start(self) -> None и, опционально, метод async def stop(self, exc: Optional[ Exception]) -> None.
Концепция остановки службы не обязательно заключается в нажатии пользователем клавиш Ctrl+C, на самом деле это просто выход из контекстного менеджера entrypoint.
Пример ниже иллюстрирует, как может выглядеть ваш сервис:
from aiomisc import entrypoint, Service
class MyService(Service):
async def start(self):
do_something_when_start()
async def stop(self, exc):
do_graceful_shutdown()
with entrypoint(MyService()) as loop:
loop.run_forever()
Точка входа может запускать любое количество экземпляров службы, и все они будут запускаться конкурентно.
Также есть способ, если метод start является полезной нагрузкой для сервиса, и тогда нет необходимости реализовывать метод stop, так как задача с функцией start будет отменена на этапе выхода из entrypoint. Но в этом случае вам придется уведомить entrypoint о том, что инициализация экземпляра службы завершена и ее можно продолжить.
Примерно так:
import asyncio
from threading import Event
from aiomisc import entrypoint, Service
event = Event()
class MyService(Service):
async def start(self):
# Send signal to entrypoint for continue running
self.start_event.set()
await asyncio.sleep(3600)
with entrypoint(MyService()) as loop:
assert event.is_set()
Примечание
entrypoint передает управление телу контекстного менеджера только после того, как все экземпляры службы запущены. Как упоминалось выше, стартом считается завершение метода start или установка стартового события с помощью self.start_event.set().
Вся мощь этой библиотеки это набор уже реализованных или абстрактных сервисов таких как: AIOHTTPService, ASGIService, TCPServer, UDPServer, TCPClient, PeriodicService, CronService и так далее.
К сожалению в данном разделе нет возможности уделить этому больше внимания, обратите внимание на раздел Учебник, там больше примеров и пояснений, ну и конечно вы всегда можете узнать ответ на Описание API или в исходном коде. Авторы постарались сделать исходный код максимально понятным и простым, поэтому не стесняйтесь исследовать его.
Версионирование#
Это программное обеспечение следует методологиии Семантического Версионирования
Кратко: учитывая номер версии МАЖОРНАЯ.МИНОРНАЯ.ПАТЧ, следует увеличивать:
МАЖОРНУЮ версию, когда сделаны обратно несовместимые изменения API.
МИНОРНУЮ версию, когда вы добавляете новую функциональность, не нарушая обратной совместимости.
ПАТЧ-версию, когда вы делаете обратно совместимые исправления.
Дополнительные обозначения для предрелизных и билд-метаданных возможны как дополнения к МАЖОРНАЯ.МИНОРНАЯ.ПАТЧ формату.
В этом проекте версия пакета назначается автоматически с помощью poem-plugins, он использует тег в репозитории как МАЖОР и МИНОР, а также счетчик, который берет количество коммитов между тегом и головой ветки.
Как разрабатывать этот проект?#
Этот проект, как и многие другие open source проекты, разрабатывается энтузиастами, и вы можете присоединиться к разработке, создавайте issues в github или присылайте свои правки как merge request.
Чтобы начать разработку в этом репозитории, вам необходимо сделать следующее:
Должно быть установлено
Python 3.7+ как
python3Установлен Poetry как
poetry
Для настройки окружения разработчика выполните:
# installing all dependencies poetry install # setting up pre-commit hooks poetry run pre-commit install # adding poem-plugins to the poetry poetry self add poem-plugins
- 1. Учебник
- 2. Модули
- 2.1. Точка входа (entrypoint)
- 2.2. Функция
run() - 2.3. Конфигурация журналов
- 2.4. Сервисы
- 2.4.1. Класс
TCPServer - 2.4.2. Класс
UDPServer - 2.4.3. Класс
TLSServer - 2.4.4.
TCPClient - 2.4.5.
TLSClient - 2.4.6.
RobustTCPClient - 2.4.7.
RobustTLSClient - 2.4.8. Класс
PeriodicService - 2.4.9. DNS Server
- 2.4.10. Класс
CronService - 2.4.11. Несколько сервисов
- 2.4.12. Конфигурация
- 2.4.13. aiohttp сервис
- 2.4.14. asgi сервис
- 2.4.15. uvicorn service
- 2.4.16. GRPC service
- 2.4.17. Трассировщик памяти
- 2.4.18.
Profiler- профилировщик - 2.4.19. Raven сервис
- 2.4.20.
SDWatchdogService - 2.4.21. Класс
ProcessService - 2.4.22. Класс
RespawningProcessService
- 2.4.1. Класс
- 2.5. Абстрактный пул соединений
- 2.6. Контекст
- 2.7.
@aiomisc.timeout - 2.8.
@aiomisc.asyncbackoff - 2.9.
asyncretry - 2.10. Предохранитель
- 2.11. Декоратор
cutout- «рубильник» - 2.12.
@aiomisc.aggregate - 2.13. асинхронные операции с файлами
- 2.14. Работа с потоками
- 2.15.
ProcessPoolExecutor - 2.16. Утилиты
- 2.17.
WorkerPool - 2.18. Конфигурация логирования
- 2.19. Плагин для Pytest
- 2.20.
Signal - 2.21. Plugins
- 2.22. Статистические счетчики
- 3. Описание API
- 3.1. Модуль
aiomisc- 3.1.1. Модуль
aiomisc.aggregate - 3.1.2. Модуль
aiomisc.backoff - 3.1.3. Модуль
aiomisc.circuit_breaker - 3.1.4. Модуль
aiomisc.compat - 3.1.5. Модуль
aiomisc.context - 3.1.6. Модуль
aiomisc.counters - 3.1.7. Модуль
aiomisc.cron - 3.1.8. Модуль
aiomisc.entrypoint - 3.1.9. Модуль
aiomisc.io - 3.1.10. Модуль
aiomisc.iterator_wrapper - 3.1.11. Модуль
aiomisc.log - 3.1.12. Модуль
aiomisc.periodic - 3.1.13. Модуль
aiomisc.plugins - 3.1.14. Модуль
aiomisc.pool - 3.1.15. Модуль
aiomisc.process_pool - 3.1.16. Модуль
aiomisc.recurring - 3.1.17. Модуль
aiomisc.signal - 3.1.18. Модуль
aiomisc.thread_pool - 3.1.19. Модуль
aiomisc.timeout - 3.1.20. Модуль
aiomisc.utils - 3.1.21. Модуль
aiomisc.worker_pool
- 3.1.1. Модуль
- 3.2. Модуль
aiomisc_log - 3.3. Модуль
aiomisc_worker
- 3.1. Модуль