Skip to main content

librarykit

Жирное ядро экосистемы китов — переиспользуемый фундамент, на котором строятся тонкие надстройки (adapterkit, clikit) и любые доменные пакеты. Вся общая логика живёт здесь один раз, вместо копипасты по проектам: единая иерархия ошибок, config/paths-утили, политики повторов, HTTP-транспорт, авторизация, шифрованное хранилище сессий, antibot/браузер, пагинация, RPC/stream и оркестраторы онбординга/health.

corekit      ← ОСНОВАНИЕ: значения, ошибки, чистая классификация. Без зависимостей
   ▲
netkit       ← СЕТЬ: транспорт, лимиты, повторы, лестница, пагинация, кодеки
   ▲
librarykit   ← ОРКЕСТРАТОР и ФАСАД: auth · sessions · cookies · live_session ·
                        anchors · factory · orchestration + прежние пути ко всему,
                        что уехало этажами ниже
   ▲
clikit       ← CLI-обёртка (поверх librarykit)
   ▲
adapterkit   ← SDK сетевых адаптеров (поверх librarykit + clikit)
   ▲
домен        ← конкретный продукт (поверх всех трёх)

Зависимости направлены только внутрь, к корню: librarykit знает об основании, сети и слое доступа (s-corekit, s-netkit, s-authkit-client — прямые зависимости; браузерный s-browserkit — extra), но ничего не знает о потребителях.

Где чей дом

У каждого модуля ОДИН дом. Всё, что уехало в отдельный кит, доступно по прежнему пути — и это алиас модуля, а не реэкспорт имён: sys.modules["librarykit.limit"] указывает на тот же объект, что sys.modules["netkit.limit"]. Значит, объект ровно один: isinstance, except и is совпадают по обоим путям, а monkeypatch.setattr("librarykit.transport.X", …) влияет на реальный вызов, включая код внутри дома. Реэкспорт имён давал бы два пространства имён: имена те же, а подмена по старому пути уходила бы в пустоту — молча, без единого красного теста.

Прежний путь Дом
librarykit.errors, .redaction, .diagnosis.access/.egress/.verdict corekit.*
librarykit.transport (со всеми подмодулями), .ladder (со всеми подмодулями) netkit.*
librarykit.limit, .retry, .errmap, .forms, .graphql, .rpc, .stream, .pagination, .upload netkit.*
librarykit.sessions, .secret_store, .oauth, .access_probe, .session_fingerprint authkit_client.*
librarykit.browser, .antibot, .browser_guard, .profile_health, .testing browserkit.*

Исключение одно и оно намеренное: librarykit.contract остаётся гибридом — он реэкспортирует «талию» из основания и сети, но и объявляет свои протоколы (BrowserBackend, SyncBrowserBackend, SessionStoreProtocol), о которых основание и сеть знать не могут. Алиасом такой модуль стать не может: самоподмена выбросила бы собственные объявления. Решение закреплено тестом, чтобы «оставили осознанно» нельзя было спутать с «забыли перевести».

Проверяется прогоном: tests/test_module_home_aliases.py (тождество модулей, двусторонний шов подмены, отсутствие второй копии подмодулей, живые прежние формы импорта) и tests/test_browserkit_facade.py (граница с браузерным китом).

Установка

uv add s-librarykit

Имя дистрибутива — s-librarykit, имя для импорта — librarykit.

Опциональные extra (тяжёлые зависимости ставятся по требованию):

uv add "s-librarykit[browser]"   # Playwright + patchright — warm/cold-login, snapshot сессий
uv add "s-librarykit[antibot]"   # curl-cffi — JA3-impersonate транспорт
uv add "s-librarykit[ws]"        # websockets — persistent stream-транспорт

Ядро (errors/config_util/retry/checkpoint/contract) почти-stdlib — единственная не-stdlib зависимость ядра platformdirs (нативные пути ОС для AppPaths). Сетевые модули тянут httpx/stamina, шифрование сессий — cryptography/keyring.

Состав

Слой Модуль Что даёт
Ошибки librarykit.errors единая иерархия CliError/ApiError + сетевые подклассы (AuthRequired/RateLimited/NotFound/ServerError/TransportError/Blocked) + множество RETRYABLE
Конфиг/пути librarykit.config_util deep_merge, interpolate_env, load_dotenv, slugify, normalize_account_id, atomic_write_text, chmod_600, AppPaths
Контракт librarykit.contract граничные Protocol (Transport/Auth/Refreshable/ErrorMapper/Paginator/SessionStoreProtocol/StreamTransport/Codec) + DTO/enum (SessionRef/Creds/PaginationMode/AuthMode/TransportKind)
Протоколы librarykit.protocols опциональные онбординг/health-контракты (LoginMode/OnboardingProtocol/HealthProtocol/HealthState/InteractiveFlow)
Повторы librarykit.retry RetryPolicy (header-driven: Retry-After/rate-limit) поверх stamina + SimpleRetryPolicy
Транспорт librarykit.transport HttpxTransport + HttpClient — единый choke-point HTTP-вызовов
Ошибки→исключения librarykit.errmap декларативная карта {status|code|body-predicate → ErrorSubclass} (build_error_map)
Пагинация librarykit.pagination CursorPaginator (offset/cursor/page) + tweepy-стиль обёртки
Авторизация librarykit.auth TokenAuth/CookieSessionAuth/OAuth2Auth/BrowserLoginAuth + dump/load/encrypt настроек
Сессии librarykit.sessions SessionStore — envelope-шифрованное файловое хранилище сессий (DEK под KEK), resolve_kek
Секреты librarykit.secret_store SecretStore — keyring + file-fallback
Antibot librarykit.antibot выбор транспорта Tier 0-4 (curl-cffi JA3 / реальный браузер по CDP)
Браузер librarykit.browser warm/cold-login, snapshot/restore storage-state
RPC librarykit.rpc RpcClient + codec-слой (JsonCodec/PrefixedJsonCodec) поверх HttpClient
Stream librarykit.stream persistent-транспорты (StubStreamTransport + WebSocketsStreamTransport)
Checkpoint librarykit.checkpoint Checkpoint (атомарный JSON-state), JsonlSink (forensic-лог), RunMetrics
Веер задач librarykit.fanout fan_out — N параллельных задач на asyncio.TaskGroup: результаты И ошибки, привязанные к ключам (падение одной ветки не рвёт остальные); fan_out_all — «нужны все»
Кеш диалогов librarykit.dialog_cache DialogCache — активные диалоги + маркер «где остановились» (SQLite/WAL, мультитенантно), pull_new — «дай мне только новое» (docs/DIALOG_CACHE.md)
Проба доступа librarykit.access_probe probe_access(service, ctx) — ЖИВОЙ вердикт по ответу сервера вместо «есть файл с куками = залогинен»; плагин объявляет заход (probe_for/AccessProbe), ядро исполняет и кэширует на короткий TTL (ключ включает egress)
Отпечаток сессии librarykit.session_fingerprint инвариант «один egress + один профиль»: capture_fingerprint/save_fingerprint при логине, guard_session_fingerprint ДО сетевого вызова → SessionEgressMismatch («при логине было X, сейчас Y»)
Здоровье профиля librarykit.profile_health check_profile ДО спавна браузера (размер, битые ключевые JSON, зависший SingletonLock) → INFRA_DOWN, а не «login expired»; quarantine_profile/ensure_healthy_profile
Эфемерный минт librarykit.ephemeral mint_ephemeral — минт с инъекцией кук из хранилища и извлечением обратно БЕЗ дискового профиля (каталог профилей не растёт); ephemeral_context — сам примитив контекста
OAuth и TTL librarykit.oauth OAuthTokens/OAuthSession/exchange_code — пара токенов со СРОКОМ рядом и ПРОАКТИВНЫМ обновлением: живой токен = ноль запросов, истекающий = один refresh ДО вызова, отозванный = OAuthRevoked вместо бесконечного ретрая
Поверхность API librarykit.ladder.capabilities ApiSurface (white/hidden) + AccessCapability (прямой запрос / обход отпечатка / браузерный минт / продвинутый стелс): навык объявляет НУЖДУ, движок выбирает кит (ENGINE_BINDING/bind_capability). У белого API минта и антибота нет вовсе
Порты хранилищ librarykit.repositories сессии/лимиты/идемпотентность через Protocol-порты; реализации память / SQLite / форма Redis / форма asyncpg выбираются в composition root (RepositorySet, memory_repositories, local_repositories)
Сущности librarykit.entities нейтральные data-классы (Session/SessionContext/HealthReport)
Оркестрация librarykit.orchestration OnboardingService, HealthMonitor, SessionLoader — переиспользуемые сценарии онбординга/health
Якоря разметки librarykit.anchors привязка к фронту как ПРАВИЛО ПОИСКА, а не строка-константа: Anchor (сигнатуры по убыванию устойчивости + валидатор ФОРМЫ), AnchorCache (сработавшая сигнатура закрепляется и пробуется первой), самолечение со сменой якоря вместо молчаливой пустоты и три разных диагноза (AnchorLost / AnchorPageMismatch) (docs/ANCHORS.md)
Диагностика доступа librarykit.diagnosis ПОЧЕМУ не работает: Reason/Verdict + порядок разбора (REASON_ORDER), гео-блок сервиса (classify_geo), «лёг выход» vs авторизация (classify_failure), passive-разлогин по цепочке (classify_landing_chain), сведение улик (diagnose), ЧТО именно мертво — сессия / эндпоинт / инфраструктура (AccessState/classify_access)

Топ-уровневый import librarykit ре-экспортирует публичный API (см. librarykit.__all__).

Быстрый старт

import librarykit as lk

# единая иерархия ошибок
try:
    ...
except lk.RateLimited as e:
    ...

# header-driven повторы + choke-point HTTP-клиент
client = lk.HttpClient(base_url="https://api.example.com", retry=lk.DEFAULT_RETRY)

# декларативная карта ответ → доменная ошибка
err_map = lk.build_error_map()

# envelope-шифрованное хранилище сессий
store = lk.SessionStore(root=..., kek=lk.resolve_kek())

Разработка

uv sync --extra dev
uv run --extra dev pytest -q
uv run --extra dev ruff check librarykit

Релиз кита и гейт 3 (kitsctl)

CI кита не видит соседние репозитории — в раннер клонируется только librarykit, поэтому вопрос «не сломает ли эта правка потребителей» в общем пайплайне проверить нечем. Это делается локально, перед тегом:

python scripts/kitsctl.py consumers s-librarykit        # кто зависит от кита
python scripts/kitsctl.py consumers s-librarykit --run  # + прогнать их тесты

Правило: перед git tag vX.Y.Z — python scripts/kitsctl.py consumers <dist> --run; красный потребитель = тег не ставится. <dist> здесь — имя дистрибутива (s-librarykit, s-corekit), а не тип колеса. --run ставит локально собранный wheel в ПРОЕКТНЫЙ .venv каждого потребителя, гоняет его тесты и в finally возвращает окружение к его же локу; упавший откат тоже красит гейт.

Исключение из правила ровно одно: падение потребителя воспроизводится и БЕЗ нового колеса (то есть сломано у него, а не у нас). Тогда — issue у потребителя и ruling в журнале волны, и только после этого тег.

Лицензия

MIT © 2026 Dmitry.

Metadata

Release files for s-librarykit 0.8.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for s-librarykit 0.8.3
File Size Uploaded
s_librarykit-0.8.3.tar.gz 566.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for s-librarykit 0.8.3
File Interpreter ABI Platform
s_librarykit-0.8.3-py3-none-any.whl Python 3 none any Details

Total release size: 754.6 kB

Release files / s_librarykit-0.8.3.tar.gz

Download URL s_librarykit-0.8.3.tar.gz
Size 566.2 kB
Tags Source
SHA-256 checksum
How to use checksums
f91481f31b68140478768769ab1e157922d4d549ce03070d26686388e22facc3
BLAKE2b-256 checksum
How to use checksums
068031d3344a03bbe604b9508ec543c2f504780acd9fd41ab379f5bb7152c5b9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.9.30 {"installer":{"name":"uv","version":"0.9.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / s_librarykit-0.8.3-py3-none-any.whl

Download URL s_librarykit-0.8.3-py3-none-any.whl
Size 188.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
12e828c28a13fab7466e83a31eec4fbd29be581e96e20d1f1f34b87b946e3260
BLAKE2b-256 checksum
How to use checksums
366de2e86a7ab83a11f88c1bb300c0847440792531d7cf75d6708aa2f3bb0c85
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.9.30 {"installer":{"name":"uv","version":"0.9.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.8.3 This release

2 release files

0.8.0

2 release files

0.7.34

2 release files

0.7.33

2 release files

0.7.32

2 release files

0.7.31

2 release files

0.7.30

2 release files

0.7.28

2 release files

0.7.27

2 release files

0.7.26

2 release files

0.7.25

2 release files

0.7.24

2 release files

0.7.21

2 release files

0.7.20

2 release files

0.7.9

2 release files

0.7.8

2 release files

0.7.7

2 release files

0.7.6

2 release files

0.7.5

2 release files

0.7.4

2 release files

0.7.3

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.5.6

2 release files

0.5.5

2 release files

0.5.4

2 release files

0.5.3

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.15

2 release files

0.1.14

2 release files

0.1.13

2 release files

0.1.12

2 release files

0.1.11

2 release files

0.1.10

2 release files

0.1.9

2 release files

0.1.8

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page