Асинхронный Python: курс asyncio с нуля — интерактивные уроки в браузере (20 уроков)
Ожидать, не останавливаясь: событийный цикл, задачи и конкурентность
Редакция Питоники

Асинхронность — то, что отличает скрипты от сервисов: пока одна загрузка ждёт сеть, код успевает сделать десять других дел. asyncio встроен в Python, и весь курс исполняется в песочнице по-настоящему: корутины, задачи и событийный цикл работают прямо на странице.
Двадцать уроков строят путь от первой async def до уверенных паттернов: корутины и await, create_task и gather, таймауты и отмена, исключения в конкурентном коде, очередь producer-consumer, семафоры против лавины запросов, асинхронные итераторы и контекст-менеджеры. Финал — диспетчер задач с таймаутами и лимитами: мини-версия того, что живёт внутри настоящих ботов и парсеров.
Курс идёт после основ Python и идеально стыкуется с разделом про телеграм-ботов: именно там async перестаёт быть теорией. Никаких установок — только стандартная библиотека и живой интерпретатор в браузере.
Чему научитесь
- Писать корутины async def и понимать, что именно делает await
- Запускать событийный цикл через asyncio.run
- Запускать конкурентные задачи: create_task и gather
- Ограничивать время операций таймаутами wait_for
- Отменять задачи и обрабатывать CancelledError
- Собирать конвейер producer-consumer на asyncio.Queue
- Регулировать параллелизм семафором вместо лавины запросов
- Читать tracebacks async-кода и не наступать на «never awaited»
- Собрать диспетчер задач: таймауты, лимиты, итоговый отчёт
Для кого: Тем, кто освоил основы Python и хочет понимать, как устроены боты, парсеры и API-сервисы — и почему они не падают, ожидая сеть.
- Урок 1. Зачем асинхронность: ожидание без блокировкиТри загрузки по секунде — три секунды простоя, если скрипт синхронный. Смотрим на честных замерах, где уходит время, и чем asyncio.sleep отличается от time.sleep.30 мин
- Урок 2. Первая корутина: async def и awaitasync def — функция с паузами, await — «дождись результата». Звучит просто, пока не выясняется, что вызов async-функции не выполняет её тело. Разбираем оба ключевых слова на живом коде.30 мин
- Урок 3. asyncio.run: событийный цикл под капотомОдна строка asyncio.run(main()) превращает обычный скрипт в асинхронную программу. Разбираем три работы этой строки: создать цикл, раскрутить корутину, убрать за собой.30 мин
- Урок 4. Coroutine never awaited: главная ошибка новичкаПрограмма завершилась успешно и ничего не сделала: классика потерянного await. Разбираем корутин-призраков, честно смотрим на RuntimeWarning и выучиваем три лекарства.30 мин
- Урок 5. Два await подряд: последовательность, не конкурентностьПоставил два await — и ожидаешь ускорения? Секундомер говорит: 2 + 2 = 4 секунды. Разбираем, почему await сам по себе не создаёт конкурентность, и замеряем всё честно.30 мин
- Урок 6. Задачи: asyncio.create_taskОдна строка — и два await из прошлого урока бегут одновременно: 4 секунды становятся 2. Знакомимся с задачами, их done() и result() и правилом о ссылке на задачу.35 мин
- Урок 7. asyncio.gather: пачка конкурентных операцийТри create_task — три строки, десять страниц — десять. gather собирает всю пачку одним вызовом: время по самой долгой операции, результаты в порядке аргументов.35 мин
- Урок 8. Порядок результатов: завершение против спискаgather возвращает результаты по порядку аргументов, даже если быстрая задача закончилась первой; as_completed отдаёт по мере готовности. Разбираем, когда какой нужен.30 мин
- Урок 9. Таймауты: asyncio.wait_for и timeoutСеть не отвечает — а программа не должна висеть вечно: wait_for ставит дедлайн на любую корутину, TimeoutError ловится try/except, а вместо падения отдаётся запасной ответ.30 мин
- Урок 10. Отмена задач: cancel и CancelledErrorЗадача больше не нужна — cancel() просит её остановиться. Отмена кооперативная: CancelledError возникает внутри корутины на её текущем await, а убирается задача сама — в finally.30 мин
- Урок 11. Исключения в конкурентном кодеОдна корутина с ValueError способна уронить весь gather. Флаг return_exceptions=True превращает исключения в значения списка — пачка выживает, а отчёт собирается целиком.30 мин
- Урок 12. Блокирующий вызов останавливает всёОдна строка time.sleep внутри async-функции — и весь событийный цикл мёртв: никакие задачи не работают, таймеры не тикают. Смотрим на таймстампах и формулируем правило.30 мин
- Урок 13. Очередь asyncio.Queue: producer-consumerПродюсер кладёт задания, консьюмеры разбирают — классический конвейер на asyncio.Queue: put, get, task_done и join, плюс maxsize, чтобы производитель не завалил обработку.35 мин
- Урок 14. Semaphore: когда конкурентов должно быть пять, а не пятьдесятТысячу задач gather запустит одновременно — и завалит API. Semaphore строит окно: максимум N конкурентов, остальные стоят в очереди. Считаем пики и подбираем размер.35 мин
- Урок 15. Асинхронные итераторы: async forasync for — это цикл, который умеет ждать: следующий элемент может прийти через секунду, и пока его нет, событийный цикл занимается другими делами.35 мин
- Урок 16. Асинхронные контекст-менеджеры: async withСоединение надо не только открыть, но и закрыть — даже если посреди работы задачу отменили. async with берёт эту уборку на себя.35 мин
- Урок 17. Мини-проект: загрузка страниц без сетиСеть необязательна: шесть «страниц», фиксированные задержки и asyncio — и ты своими глазами увидишь, как конкурентная загрузка сжимает десять секунд до трёх.40 мин
- Урок 18. Паттерн воркеров: ограниченный параллелизмТри исполнителя, одна очередь, девять заданий: паттерн, на котором держатся парсеры, боты и очереди рассылок — с честным graceful-завершением.40 мин
- Урок 19. Читаем async-ошибки: словарь типовых сообщенийСообщения asyncio пугают, пока их не переведёшь. Четыре типовые ошибки — причина, лечение, живой пример на каждую.35 мин
- Урок 20. Проект: диспетчер задач с таймаутами и лимитамиФинал курса: очередь заданий, семафор-лимит, wait_for-дедлайны и честный отчёт — успехи, таймауты, ошибки. Мини-версия движка настоящего бота.45 мин