Перейти к содержанию

Соответствие тестовому заданию

Основное выбранное задание — №7 «Асинхронный Парсер/Скрапер сайтов».

Требование задания Реализация Проверка
Асинхронный Python-скрипт asyncio, httpx.AsyncClient, роли tender_lens.crawler test_http_concurrency_is_bounded, role smoke в CI
Сбор новых закупок TedAdapter, ContractsFinderAdapter, cursor в таблице sources adapter fixtures, cursor integration tests
Параллельная обработка BoundedSemaphore, отдельные лимиты запросов и вложений восемь одновременных запросов в unit-тесте
Базовые задержки polite delay, jitter, bounded retry, Retry-After, cooldown 403 HTTP policy unit-тесты
Скачивание вложений streaming в .part, лимит размера, SHA-256, atomic replace unit-тесты файлов и fixture E2E
Сохранение метаданных в PostgreSQL SQLAlchemy async, Alembic, idempotent UPSERT PostgreSQL integration suite
Работа источников независимо ошибка записи изолируется; ошибка одного source не завершает общий цикл malformed-record tests и orchestration path
Безопасность URL и файлов закрытый allowlist, проверка каждого redirect, блок local/private target, safe filename SSRF/redirect/path traversal regression tests
Markdown с логикой решения README.md, docs/algorithm.md, docs/architecture.md delivery contract test
LICENSE MIT LICENSE delivery contract test
Ветка и merge в main feature/fix-ветки, содержательные коммиты, merge commit публичная история GitHub

Дополнительные возможности

Расширение Реализация Проверка
№3: RAG pgvector, relevance threshold, grounded /ask low-relevance short circuit и E2E
№8: Rate limiter API key в PostgreSQL, общий лимит 5/мин concurrent integration и шестой запрос 429
№9: Docker/CI один image, Compose, GitHub Actions container role smoke и зелёный workflow

Обычный CI использует fixtures и fake AI. Live API и Ollama проверяются отдельно и не влияют на детерминированность основной сборки.