Repository navigation
Expand file tree
/
Copy pathlocal_proxy_demo.py
More file actions
78 lines (67 loc) · 3.07 KB
/
Copy pathlocal_proxy_demo.py
File metadata and controls
78 lines (67 loc) · 3.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
"""Use the SDK machine's network and DNS from a normal cloud browser."""
import argparse
import os
import sys
from typing import Optional
from urllib.parse import urlsplit
from lexmount import Lexmount
from playwright.sync_api import sync_playwright
from quickstart_auth import prepare_demo
def wait_for_keypress() -> None:
print("Press any key to continue (close browser and tunnel)...", end="", flush=True)
try:
if sys.stdin.isatty() and os.name == "nt":
import msvcrt
if msvcrt.getwch() == "\x03":
raise KeyboardInterrupt
elif sys.stdin.isatty():
import termios
import tty
fd = sys.stdin.fileno()
previous = termios.tcgetattr(fd)
try:
tty.setcbreak(fd)
sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, previous)
else:
sys.stdin.read(1) # EOF also allows cleanup in noninteractive runs.
finally:
print()
def run(target: str, region: Optional[str] = None) -> None:
url = urlsplit(target)
if url.scheme not in ("http", "https") or not url.hostname:
raise ValueError("The local proxy demo requires an HTTP(S) URL.")
with Lexmount(region=region) as client:
# The connector uses local OS/VPN DNS and stays alive through browser work.
with client.tunnels.open() as tunnel:
print(f"Local tunnel ready in region {tunnel.region_id}")
with client.sessions.create(
browser_mode="normal",
proxy={"type": "local", "tunnel_id": tunnel.id},
) as session:
print(f"Session created: {session.id}")
with sync_playwright() as playwright:
browser = playwright.chromium.connect_over_cdp(session.connect_url)
try:
if not browser.contexts:
raise RuntimeError("No browser context available after connecting.")
context = browser.contexts[0]
page = context.pages[0] if context.pages else context.new_page()
page.goto(target, wait_until="domcontentloaded", timeout=60_000)
print(f"Page title: {page.title()}")
page.screenshot(path="local_proxy_demo.png")
print("Saved screenshot to local_proxy_demo.png")
wait_for_keypress()
finally:
browser.close()
# Session context exits before the tunnel context, including on errors.
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--url", required=True, help="HTTP(S) URL reachable from this machine.")
parser.add_argument("--region", help="Catalog region ID; defaults to LEXMOUNT_REGION in .env.")
args = parser.parse_args()
prepare_demo()
run(args.url, args.region or os.getenv("LEXMOUNT_REGION", "").strip() or None)
if __name__ == "__main__":
main()