Разделить вход между вкладками#

BrowserLogin описывает способ входа и признаки живой сессии. Учётные данные и состояние принадлежат BrowserSession, которую получают через login.session(...).

Сервис входа работает на странице того же клиента и возвращает состояние контекста:

# examples/mail/browser/session.py
@dataclass(frozen=True, slots=True)
class MailCredentials:
    email: str
    password: str = field(repr=False)
    otp: str = field(repr=False)


@dataclass(slots=True)
class MailLoginService:
    calls: int = 0

    async def acquire(
        self,
        credentials: MailCredentials,
        context: BrowserLoginContext,
    ) -> BrowserState:
        self.calls += 1
        portal = LoginPortal(context.client)
        password = await portal.identify(email=credentials.email, options=OPTIONS)
        otp = await password.submit(password=credentials.password)
        await otp.submit(code=credentials.otp)
        return await context.export_state()

Один объект сессии можно передать нескольким вкладкам одного контекста:

    # examples/docs/integration_browser_login.py
    logins, tabs, cookie = await one_login_for_two_tabs()
Файл целиком
"""Share one browser session between two tabs."""

from __future__ import annotations

import asyncio

from examples.mail.browser.session import one_login_for_two_tabs


async def main() -> None:
    # docs:integration-browser-login:start
    # examples/docs/integration_browser_login.py
    logins, tabs, cookie = await one_login_for_two_tabs()
    # docs:integration-browser-login:end
    print(f"browser logins: {logins}")
    print(f"tabs in context: {tabs}")
    print(f"session cookie: {cookie}")


if __name__ == "__main__":
    asyncio.run(main())
browser logins: 1
tabs in context: 2
session cookie: session-ada

Первый вызов берёт блокировку сессии и входит. Параллельный вызов ждёт ту же ревизию, поэтому две вкладки выполняют один вход. Объект сессии нельзя переносить в другой контекст; новый контекст получает новый объект и общее хранилище ревизий.

Объект

Владеет

BrowserLogin

сервисом входа, обязательными cookies и типами истечения

BrowserSession

учётными данными, блокировкой, хранилищем и ревизией контекста

AsyncBrowserClient

выполнением операций одной страницы

Если отказ входит в expired=, клиент обновляет сессию и повторяет операцию в пределах auth_retries. HTTP-клиенту та же сессия отдаётся целиком: Identity(cookies=CookieState(state.cookies)) для SDK, объявившего Cookies(...).

Дальше#