Asynchronní parsér mangy v Pythonu: od architektury po mikroslužby
Vytvoření škálovatelného parséru mangy je úloha, která kombinuje složitosti asynchronního programování, návrhu kontraktů a správy stavu. Manga-Day je praktický příklad přechodu od monolitu k mikroservisní architektuře s využitím asyncio, Pydantic a SQLAlchemy. Projekt byl původně zamýšlen jako nástroj pro automatický sběr dat z desítek webů, ale stal se učební pomůckou pro návrh rozšiřitelných systémů.
Architekturální základy: kontrakty a asynchronita
Jádro systému je postaveno kolem abstraktní třídy BaseSpider. Každý konkrétní parsér (např. pro multi-manga) implementuje jednotné rozhraní, což umožňuje dynamicky připojovat nové zdroje bez změny jádra. Kontrakt zahrnuje tři klíčové metody:
from abc import ABC, abstractmethod
class BaseSpider(ABC):
BASE_URL = "https://example-manga.com"
@abstractmethod
async def get(self, url: str, **kwargs) -> Optional[MangaSchema]: ...
@abstractmethod
async def pages(
self, start_page: int | None = None
) -> AsyncGenerator[list[BaseManga], Any]: ...
Takový přístup zajišťuje:
- Jednotnost zpracování chyb a timeoutů
- Možnost testování každého pavouka nezávisle
- Podporu horizontálního škálování prostřednictvím asynchronních generátorů
Asynchronita je realizována na úrovni asyncio, což umožnilo efektivně zpracovávat stovky souběžných požadavků bez blokování I/O. To je obzvláště důležité při práci s pomalými nebo nestabilními zdroji.
Validace dat a ORM modely
Pro striktní typizaci a validaci se používá Pydantic. Systém je postaven na třech úrovních modelů:
- BaseManga — minimální sada polí: title, poster, url, sku (hash SHA256)
- MangaWithGallery — přidává seznam URL obrázků
- MangaSchema — kompletní model s žánry, autorem a jazykem (volitelně)
V databázi spravované SQLAlchemy jsou implementovány následující entity:
- Manga, Author, Genre, Language — hlavní tabulky
- GenreManga — relace mnoho-ku-mnoha pro žánry
- Gallery — samostatná tabulka pro obrázky (aby se nezatěžovala hlavní výběr)
- GeneratedPdf — zastaralá tabulka, plánováno k odstranění
Rozdělení galerie do samostatné entity umožnilo vyhnout se problémům N+1 při načítání seznamů mangy — nyní se obrázky načtou pouze na explicitní požadavek.
Manažeři: logika nad daty
Vrstvou business logiky jsou manažeři — třídy odpovědné za konkrétní operace:
- MangaManager: CRUD operace podle SKU, URL, ID
- RequestManager: HTTP požadavky s retry logikou a timeouty
- AlertManager: univerzální systém notifikací (Telegram, Discord aj.)
- SpiderManager: centrální orchestrátor všech pavouků
SpiderManager je obzvláště zajímavý svou modularitou. Je rozdělen do čtyř souborů:
_load.py— dynamické načítání pavouků přes__all___status.py— modely stavů a výčty_starter.py— spuštění a správa životního cyklu_spider.py— sladění komponent do jednotného rozhraní
Taková dekompozice zjednodušila testování a umožnila izolovat změny — např. přidání nového pavouka vyžaduje pouze jeho registraci v __init__.py, bez úprav v jádře.
Přechod na mikroslužby: bolestivé body a řešení
Původně byl projekt monolitický, ale dva servisy se staly katalyzátory změn:
- PDFService — spotřebovával příliš mnoho RAM, byl vyveden do samostatného kontejneru
- Bot — vyžadoval WebSocket a JWT autentizaci, také migroval do izolovaného servisu
Migrace proběhla několika etapy:
- Frontend je oddělen od jádra — nyní pracuje výhradně přes REST API, s minimálním Jinja pouze pro konfigurace
- Bot přepsán s využitím aiohttp pro WebSocket a implementací role-based modelu přes JWT
- PDF generace nyní běží jako background úloha s omezenou spotřebou paměti
Hlavní obtíže:
- Serializace složitých objektů mezi službami
- Konzistence dat při částečných selháních
- Nastavení health-checků a graceful shutdown
Co je důležité
- Kontrakty jsou důležitější než implementace — abstraktní třídy umožnily škálovat systém bez refaktoringu jádra
- Asynchronita ≠ automatická výkonnost — je třeba kontrolovat počet souběžných úloh a používat semafory
- ORM není lék na vše — ruční optimalizace dotazů a denormalizace (např. vyvedení galerie) jsou klíčové pro výkon
- Mikroslužby komplikují, ale dávají flexibilitu — vyvedení PDFService vyřešilo problém s pamětí, ale přidalo složitost nasazení
- Testovatelnost je výsledkem architektury — modularita SpiderManager umožnila psát unit testy bez mocků externích závislostí
Projekt se stal výchozím bodem pro pochopení, jak stavět systémy, které lze rozvíjet roky. Kódová báze vyrostla na desítky tisíc řádků, ale díky jasnému oddělení odpovědností zůstává udržitelná. Další kroky — implementace message brokeru pro fronty úloh a plnohodnotné CI/CD s autotesty na každý pull request.
— Editorial Team
Zatím žádné komentáře.