Skip to main content

sessionkit

Владение сессией аккаунта: дверь, адрес, порт хранилища, окно записи, четыре раскладки как слои, порт селектора. Один дом вместо четырёх — где сессия лежит, решает кит, а не потребитель.

Зачем

«Сессия аккаунта» физически живёт сразу в нескольких местах: файловым деревом (s-authkit-client, envelope KEK/DEK), строкой в общей базе (s-accountpoolkit, документ хранится запечатанным целиком) и профилем браузера как кэшем узнавания устройства. Какое из них главное, до сих пор решала переменная окружения, прочитанная посторонним китом.

У этого две цены. Первая: одна команда пишет туда, где другая ничего не находит. Вторая, дороже: у сессии нет владельца — спросить «где она на самом деле» не у кого, и спор «почему навык не видит вход» решается догадками.

Этот кит — владелец. Носители объявляют себя ему сами (entry-points), он находит общую базу сам, выбирает носитель и говорит, кого выбрал и почему. Здоровье аккаунта пишется одним словом (authkit_contracts.status.Status) и только под окном записи.

Как спрашивают

import sessionkit

address = sessionkit.SessionAddress(service="gemini", account="me@example.com")
try:
    state = sessionkit.load_state(address)          # None — входа ещё не было
    sessionkit.save_state(address, state or {"cookies": []})
    with sessionkit.write_window(address) as window:   # здоровье — только под окном
        sessionkit.mark(address, status=sessionkit.Status.LIVE, window=window)

    choice = sessionkit.where()                     # КТО ответил и ПОЧЕМУ
    print(choice.name, choice.reason)
    for verdict in choice.verdicts:
        print(" ", verdict)                         # включая тех, кто отказался
except sessionkit.StoreUnavailable as refusal:
    print(refusal)  # носителей в установке нет — отказ называет, какой пакет ставить

mark без окна — WriteWindowRequired, а не молчаливая запись: статус в индексе расходился с телом сессии ровно потому, что его писали полтора десятка мест мимо единой отметки.

Разбор полётов «почему выбрали не то» — sessionkit.explain(): опрашивает всех кандидатов, а не останавливается на первом согласившемся.

Что умеет выбранное хранилище сверх обязательного минимума (аренда на минт, набор аккаунтов, запись без слияния) — sessionkit.capabilities(). Способность спрашивают, а не предполагают: предположение оборачивается тишиной на месте защиты.

Адрес

Шесть координат, ровно те же, которыми адресует хранилище (corekit.dto.SessionRef):

координата вопрос умолчание
tenant чья сессия в общем хосте local
profile чей это набор входов (рабочий, личный) default
service к какому сервису обязательна
instance какой ИМЕННО вход сервиса (портал, национальный домен) пусто
account под каким аккаунтом default
stage боевая сессия или черновик записи трафика live

instance — не украшение: без него два разных портала Битрикса одного аккаунта получают одно имя, а хранилище считает уникальность по шести координатам — и запись уходит не туда, откуда читали.

Где что лежит

sessionkit.locate отвечает на вопрос «где» один раз на всех:

  • корень сессий — SESSIONS_HOME, иначе ~/.sessions;
  • общая база находится сама в <корень>/sessions.db; SESSIONS_DB_URL — переопределение (другой сервер, другой тенант), а не условие работы;
  • ключ шифрования имеет три состояния: файл (SESSIONS_DB_KEY_FILE или <корень>/.session-db.key), явное «хранить открыто» (SESSIONS_DB_PLAINTEXT=1) и «не задан» — последнее НЕ равно «открыто».

Порядок опроса: сначала база, потом дерево. Если общая база заведена, то она и есть сессия; читать в этот момент дерево значит завести второй носитель — обе копии выглядят рабочими, а ротацию получает только та, через которую сходили.

Носители: объявляются сами

Кит не называет ни одной реализации по имени — это держит .importlinter. Пакет, умеющий хранить сессии, записывается в группу entry-points sessionkit.stores:

[project.entry-points."sessionkit.stores"]
file = "authkit_client.sessions:store_provider"    # s-authkit-client
db   = "accountpoolkit.session_db:store_provider"  # s-accountpoolkit

Провайдер — функция dsn -> хранилище | StoreOffer | None. Носителя нет — StoreProviderMissing с рецептом установки (pip install s-authkit-client / s-accountpoolkit) и перечнем объявленных. Явная register_provider под тем же именем сильнее объявленной пакетом: подмена в тесте остаётся подменой.

Окно записи

sessionkit.write_window(address) — окно записи на два слоя (лок внутри процесса + файл между процессами) со сроком и держателем; ждёт не дольше 5 с. Всё, что меняет тело или здоровье сессии, идёт внутри. Нужно там, где вход ВЫПУСКАЮТ: у сервисов вида Google одна сессия на аккаунт, и второй одновременный вход инвалидирует первый. Слово «аренда» (lease) отсюда ушло — в портфеле оно означало ещё аренду на минт в базе и JWS-пропуск leasekit; sessionkit.lease живёт один релиз как алиас с DeprecationWarning.

Четыре раскладки — слои одной двери

sessionkit.layouts (переезд librarykit.session_layers): общая база, шифрованное дерево, снимок рядом с профилем движка, файл в папке навыка — опрашиваются по старшинству. read() возвращает тело вместе с уликой, кто ответил; write() пишет в канон, а без канона — обратно в тот же слой (нового носителя не заводит); migration_plan()/migrate(confirm=True) — перенос только с показанной дельтой. python -m sessionkit.layouts [--plan] — всё одним перечнем.

Селектор — порт

sessionkit.select: Candidate, Policy, Choice, протокол Selector (pick/candidates/report/release) и чистая choose(candidates, policy, cursor=, rng=) — фильтр → каскад приоритета → Power-of-Two-Choices. Ядро (priority_key, power_of_two_choices, health_from, ratio, reset_epoch, is_dead_health) переехало из accountpoolkit.selection_core с теми же сигнатурами; пулы librarykit/accountpoolkit становятся адаптерами.

Что живёт МИМО двери

Честный список (подробности — в CHANGELOG.md): отпечаток выхода egress_fingerprint.json, персона устройства (corekit.persona), секреты, профиль браузера, а также координаты instance/stage, которые файловое дерево пока игнорирует. Дверь отдаёт тело сессии; всё перечисленное адресуется своими способами и ждёт своей очереди.

Разработка

uv sync --extra live
uv run --extra live pytest -q
uv run ruff check sessionkit tests

Набор live ставит НАСТОЯЩИЕ хранилища: утверждение «обе реализации доступны через дверь» подделкой не доказывается — она подтверждает лишь то, что мы её так и написали. Без набора живые тесты пропускаются с внятной причиной.

Статус

  • Type: kit
  • Status: active
  • Priority: P0
  • Slug: sessionkit · Prefix: ses
atlas project get sessionkit

Физический layout:

  • Storage: _storage/sessionkit/
  • Junction: Products\sessionkit → _storage/sessionkit

Metadata

Release files for s-sessionkit 0.1.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-sessionkit 0.1.3
File Size Uploaded
s_sessionkit-0.1.3.tar.gz 201.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for s-sessionkit 0.1.3
File Interpreter ABI Platform
s_sessionkit-0.1.3-py3-none-any.whl Python 3 none any Details

Total release size: 291.5 kB

Release files / s_sessionkit-0.1.3.tar.gz

Download URL s_sessionkit-0.1.3.tar.gz
Size 201.2 kB
Tags Source
SHA-256 checksum
How to use checksums
3a784e85a52cb577f166caa92ff2d3dc64c11885a831cade253827bdd59f8193
BLAKE2b-256 checksum
How to use checksums
c9824bf97dea0ab7a0812788425e30b93f87dfb61ae4f18f54ade767ba243df3
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_sessionkit-0.1.3-py3-none-any.whl

Download URL s_sessionkit-0.1.3-py3-none-any.whl
Size 90.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0da50f235cbd97c9f842a980f1cf219d273495addd938b6fabce0d65ca1b3fd9
BLAKE2b-256 checksum
How to use checksums
4144d470edef0a234fbd62ed9cde41583b48612d4f423f5ea162797251815b3d
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.1.3 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.2

2 release files

0.0.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