TabSailTabSail

Reuse a login

Complete a human login once and restore it in a separate session.

Install the Python SDK and Playwright. Set TABSAIL_LOGIN_URL, TABSAIL_REPORT_URL, and TABSAIL_LOGGED_IN_SELECTOR for a website you are authorized to use.

import asyncio
import os
from playwright.async_api import async_playwright
from tabsail import AsyncTabSail, HandoffCheckpoint

async def main():
    async with AsyncTabSail() as client, async_playwright() as pw:
        profile = await client.profiles.create("Report login")
        try:
            async with client.with_session(
                timeout_seconds=600,
                profile={"id": profile.id, "persistOnClose": True},
            ) as session:
                browser = await pw.chromium.connect_over_cdp(
                    (await client.sessions.connections.create(session.id)).url
                )
                try:
                    await browser.contexts[0].pages[0].goto(os.environ["TABSAIL_LOGIN_URL"])
                    checkpoint = HandoffCheckpoint.from_session(
                        await client.sessions.get(session.id)
                    )
                    print("Open this session in the console, take control, sign in, "
                          "then return to automation:", session.id, flush=True)
                    await client.sessions.wait_for_handoff(
                        session.id, after=checkpoint, timeout_ms=300000
                    )
                finally:
                    await browser.close()
            ended = await client.sessions.get(session.id)
            if ended.profile["saveStatus"] != "saved":
                raise RuntimeError("Login state was not saved")

            async with client.with_session(profile={"id": profile.id}) as restored:
                browser = await pw.chromium.connect_over_cdp(
                    (await client.sessions.connections.create(restored.id)).url
                )
                try:
                    page = browser.contexts[0].pages[0]
                    await page.goto(os.environ["TABSAIL_REPORT_URL"])
                    await page.locator(os.environ["TABSAIL_LOGGED_IN_SELECTOR"]).wait_for()
                    print("Saved login restored")
                finally:
                    await browser.close()
        finally:
            await client.profiles.delete(profile.id)

asyncio.run(main())

Run with uv run python reuse_login.py. Expected: Saved login restored. Both browser sessions are released; this example then deletes its Profile. Production applications can retain their Profile for later use.