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)
| File | Size | Uploaded | |
|---|---|---|---|
| s_librarykit-0.8.3.tar.gz | 566.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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}
|