Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

Identity Hub

CI PyPI Python License

Identity Hub — асинхронная Python-библиотека для управления парком внешних аккаунтов: их состояниями, эксклюзивной арендой, квотами, прокси, зашифрованными сессиями и событиями. Основной читатель этого руководства — разработчик Python 3.12+, который встраивает библиотеку в воркеры или веб-приложение.

Библиотека подходит, когда несколько процессов должны безопасно делить аккаунты Telegram, бирж или других платформ. Она не является клиентом этих платформ: сетевой вызов выполняет код приложения, а Identity Hub решает, какой аккаунт можно взять, и фиксирует результат операции.

Установка через uv

Для PostgreSQL и встроенных миграций Alembic:

uv add "identity-hub[postgres,alembic]"

Дополнительные зависимости подключаются отдельно: telegram для транспорта уведомлений через Telegram Bot API (httpx, без SDK), webhooks для HTTP-вебхуков, structlog для структурированных логов и testing для тестового MemoryStore и pytest-плагина.

Для разработки самого репозитория:

uv sync --all-extras
docker compose up -d postgres
uv run pytest

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

  1. Создайте 32-байтовый мастер-ключ. Не коммитьте его и не выводите в логи:

    uv run identity-hub keygen
    
  2. Сохраните результат в IDENTITY_HUB_KEK. Первый ключ в строке активен; прежние ключи оставляют после запятой на время ротации.

  3. Задайте URL PostgreSQL и примените миграции:

    export IDENTITY_HUB_DATABASE_URL='postgresql+asyncpg://app:password@localhost/app'
    export IDENTITY_HUB_KEK='k1:<base64-ключ>'
    uv run identity-hub migrate
    

    Для разработки и одиночного процесса миграции может применять сам хаб: IdentityHub(..., migrate="auto") — тогда hub.start() доводит схему до нужной ревизии. В рабочей системе с несколькими воркерами оставьте режим по умолчанию ("check") и применяйте миграции отдельным шагом развёртывания.

    Три строки, которые стоит добавить сразу:

    • Своя схема. IdentityHub(..., db_schema="identity_hub") и identity-hub migrate --db-schema identity_hub — таблицы библиотеки лежат отдельно от таблиц приложения.
    • Alembic приложения. В env.py: from identity_hub.alembic import exclude_identity_hub и context.configure(..., include_object=exclude_identity_hub) — autogenerate не трогает ih_*.
    • Пространство. space = await hub.spaces.ensure("main") при старте создаёт его, если нет.
  4. Объявите сервис в коде и создайте один IdentityHub на процесс:

    from datetime import timedelta
    
    from pydantic import BaseModel, SecretStr
    from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine
    
    from identity_hub import EnvSecretsProvider, IdentityHub, OperationRule, Quota, Service
    
    
    class TelegramCredentials(BaseModel):
        phone: str
    
    
    class TelegramSession(BaseModel):
        auth_key: SecretStr
        dc_id: int = 2
    
    
    TELEGRAM = Service(
        name="telegram",
        title="Telegram",
        credentials=TelegramCredentials,
        session=TelegramSession,
        operations={
            "read_channel": OperationRule(
                quotas=(Quota(100, timedelta(hours=1)),),
            ),
        },
    )
    
    engine = create_async_engine(
        "postgresql+asyncpg://app:password@localhost/app",
        pool_pre_ping=True,
        hide_parameters=True,  # параметры запросов не попадают в тексты ошибок и логи
    )
    sessions = async_sessionmaker(engine, expire_on_commit=False)
    hub = IdentityHub(
        sessionmaker=sessions,
        secrets=EnvSecretsProvider(),
        services=[TELEGRAM],
    )
    
  5. На старте приложения синхронизируйте реестр сервисов, затем работайте через пространство и пул:

    from identity_hub import AuthState, IdentityCreate, Lifecycle
    
    await hub.start()
    space = await hub.spaces.ensure("production", "Production")
    
    await space.identities.create(
        IdentityCreate(
            service=TELEGRAM,
            external_ref="+12025550123",
            credentials={"phone": "+12025550123"},
            session={"auth_key": "secret-session"},
            tags=["parser"],
            lifecycle=Lifecycle.READY,
            auth=AuthState.AUTHENTICATED,
        )
    , actor="operator")
    
    parsers = space.pools.define("parsers", service=TELEGRAM, tags=["parser"])
    async with parsers.lease(for_operation="read_channel") as lease:
        session = await lease.session()
        async with lease.operation("read_channel", key="job:42"):
            # Здесь приложение вызывает Telegram-клиент с session и lease.proxy.
            messages = await telegram_client.read_history(session)
    

for_operation отбрасывает аккаунты, которые не удовлетворяют состояниям или верификации. Квоты при выборе не учитываются: контекст operation повторно проверяет состояние и атомарно списывает квоту до внешнего вызова, а при исчерпании бросает QuotaExhausted. Параметр key делает списание конкретной операции идемпотентным.

Полный самодостаточный сценарий находится в examples/telegram_service.py. Он использует память вместо PostgreSQL и имитирует платформенный клиент, поэтому запускается без внешних сервисов:

uv run python examples/telegram_service.py

Руководство

Как добавлять и регистрировать аккаунты, какие бывают состояния и кто ими управляет, как банить, верифицировать и синхронизировать статусы с платформой, какие бывают аренды и лимиты — в руководстве с диаграммами архитектуры и машин состояний. Сценарий из руководства целиком исполняется в examples/account_lifecycle.py.

Эксплуатация и тесты

Для быстрых тестов без БД установите extra testing. Pytest-плагин предоставляет фикстуры с префиксом identity_hub_, а пользовательский пример можно выполнить командой:

uv run pytest examples/test_memory_hub.py

MemoryStore предназначен для тестов и однопроцессных примеров. Конкурентные воркеры, долговечные аренды и эксплуатационный журнал требуют PostgreSQL.

Границы безопасности

  • Сессии, credentials, секреты прокси и токены доставок шифруются отдельными DEK; мастер-ключи предоставляет приложение.
  • Расшифрованные credentials и сессии воркер получает через объект действующей аренды: после освобождения, потери или отзыва он бросает LeaseLost. Вне аренды секрет раскрывают аудируемые команды space.secrets.reveal и space.proxies.url (автор и причина обязательны).
  • Потеря heartbeat отменяет владеющую задачу и вызывает on_lost; сетевой клиент должен быть отключён этим callback.
  • Диспетчер доставляет события как минимум один раз. Обработчики обязаны быть идемпотентными.
  • SpaceHandle.using(db_session) нужен, когда изменение Identity Hub должно участвовать во внешней транзакции приложения; обычные методы используют свои короткие транзакции. Команды записи возвращают результат из этой транзакции; методы чтения (get, find, list, card) и под using читают своей транзакцией и незафиксированных изменений не видят.

Полная спецификация поведения — identity-hub-requirements.md, история реализации — docs/plan/PLAN.md.

In English

Identity Hub is an async Python library (3.12+, PostgreSQL 16) for managing a fleet of external accounts: their states, exclusive leases with heartbeat and fencing, rate limits, proxies, encrypted sessions and an event stream. It does not talk to the platforms itself — your code makes the network calls, the library decides which account may be used and records the outcome.

  • Install: uv add "identity-hub[postgres,alembic]", then identity-hub migrate against your database.
  • Status: alpha (1.0.0aN). The public API may still change between alpha releases; every breaking change is marked in CHANGELOG.md.
  • Language: documentation, error messages and logs are in Russian. Identifiers, error codes, event types and field names are English and stable for programmatic use.

Лицензия

MIT. Код поставляется «как есть», без каких-либо гарантий.

Metadata

Release files for identity-hub 1.0.0a3

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

Source distribution (sdist)

Source distribution for identity-hub 1.0.0a3
File Size Uploaded Provenance
identity_hub-1.0.0a3.tar.gz 869.6 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for identity-hub 1.0.0a3
File Interpreter ABI Platform
identity_hub-1.0.0a3-py3-none-any.whl Python 3 none any Details

Total release size: 1.4 MB

Release files / identity_hub-1.0.0a3.tar.gz

Download URL identity_hub-1.0.0a3.tar.gz
Size 869.6 kB
Tags Source
SHA-256 checksum
How to use checksums
6f20be085393755ec5ac5cc1ff743c71acdaea9ba9679b39b6f896e8563efc5a
BLAKE2b-256 checksum
How to use checksums
19650876fa0181c3faaaa97179ecf57aa33e90e2f6a0f6febd3be2a3465b84e7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.

Transparency log

Release files / identity_hub-1.0.0a3-py3-none-any.whl

Download URL identity_hub-1.0.0a3-py3-none-any.whl
Size 543.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d28d258517e5c0ea729bc4aa2a7dd1df3868e36bf467813d2f50ae18a6376e4e
BLAKE2b-256 checksum
How to use checksums
bd2ff6220bd35021042436af1e9cb1a311132f76e94c4b5fc03079aed6776dd1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.

Transparency log

Security for identity-hub 1.0.0a3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for identity_hub-1.0.0a3.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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