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 dev --extra live
uv run --extra dev --extra live pytest -q
uv run --extra dev 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.0

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.0
File Size Uploaded
s_sessionkit-0.1.0.tar.gz 85.6 kB Details

Built distribution (wheel)

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

Total release size: 142.8 kB

Release files / s_sessionkit-0.1.0.tar.gz

Download URL s_sessionkit-0.1.0.tar.gz
Size 85.6 kB
Tags Source
SHA-256 checksum
How to use checksums
010d48aabaa7baf26ec19dc5116d82910b1491e196bf88f566fd645a280a29a3
BLAKE2b-256 checksum
How to use checksums
3fe07ff592a9acccab5012b93fa92c85d6e3a7122fa6075d77e2a53df3c5d7fc
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.0-py3-none-any.whl

Download URL s_sessionkit-0.1.0-py3-none-any.whl
Size 57.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2019c44e3270ccf1b345c825830fca92b62a9daaa449bee9bfea304ea090fe60
BLAKE2b-256 checksum
How to use checksums
d8b5f7e98f811c5c304d09c68d1e99c709e61d4e5d2005f863503c96d466e057
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

0.1.3

2 release files

0.1.1

2 release files

This release

0.1.0 This release

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