slybrowser 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,115 @@
1
+ # Secrets and local configuration
2
+ .env
3
+ .env.*
4
+ !.env.example
5
+ *.key
6
+ *.pem
7
+ *.pfx
8
+ secrets/
9
+
10
+ # Editors and operating systems
11
+ .idea/
12
+ .vscode/
13
+ .DS_Store
14
+ Thumbs.db
15
+
16
+ # Node.js
17
+ node_modules/
18
+ dist/
19
+ coverage/
20
+ *.tsbuildinfo
21
+
22
+ # Python
23
+ .venv/
24
+ venv/
25
+ __pycache__/
26
+ *.py[cod]
27
+ .pytest_cache/
28
+ .ruff_cache/
29
+ *.egg-info/
30
+
31
+ # .NET
32
+ **/bin/
33
+ **/obj/
34
+ TestResults/
35
+
36
+ # Java
37
+ **/target/
38
+ packages/java/$out
39
+
40
+ # Browser binaries, test evidence, and private Chromium source
41
+ artifacts/
42
+ tests/detection/browsers.local.json
43
+ private/
44
+ vendor/chromium/
45
+ /packages/license-service/
46
+ /website/
47
+ /memory/
48
+ /docs/business-model-*.md
49
+ /docs/product-feedback-*.md
50
+ *.exe
51
+ *.dll
52
+ *.pdb
53
+ *.dSYM/
54
+
55
+ # Repository-root Linux runtime bundle used only for local packaged-browser QA.
56
+ # Keep these entries anchored so similarly named SDK/documentation files remain visible.
57
+ /BUILD-INFO.txt
58
+ /MEIPreload/
59
+ /chrome
60
+ /chrome_100_percent.pak
61
+ /chrome_200_percent.pak
62
+ /chrome_crashpad_handler
63
+ /chromedriver
64
+ /headless_command_resources.pak
65
+ /icudtl.dat
66
+ /libEGL.so
67
+ /libGLESv2.so
68
+ /libVkICD_mock_icd.so
69
+ /libVkLayer_khronos_validation.so
70
+ /libqt5_shim.so
71
+ /libqt6_shim.so
72
+ /libvk_swiftshader.so
73
+ /locales/
74
+ /resources.pak
75
+ /resources/
76
+ /slybrowser
77
+ /snapshot_blob.bin
78
+ /v8_context_snapshot.bin
79
+
80
+ # Temporary release files
81
+ .cache/
82
+ tmp/
83
+ release-staging/
84
+
85
+ # Local authorization-service state and generated credentials
86
+ *.sqlite
87
+ *.sqlite-shm
88
+ *.sqlite-wal
89
+ *.authorization.json
90
+
91
+ # Local AI-agent instructions, state, and temporary output.
92
+ /AGENTS.md
93
+ /AGENTS.override.md
94
+ /CLAUDE.md
95
+ /.codex/
96
+ /.claude/
97
+ /.cursor/
98
+ /.continue/
99
+ /.aider/
100
+ /.windsurf/
101
+ /.agent/
102
+ /.agents/
103
+ /.ai/
104
+ /memory/hot-cache.md
105
+ /memory/open-loops.md
106
+ **/codex-clipboard-*
107
+ **/*-ai-scratch.*
108
+ **/*-agent-scratch.*
109
+ **/*-codex-scratch.*
110
+ **/*-ai-transcript.*
111
+ **/*-agent-transcript.*
112
+ **/*-codex-transcript.*
113
+ **/*.ai.tmp
114
+ **/*.agent.tmp
115
+ **/*.codex.tmp
@@ -0,0 +1,154 @@
1
+ Metadata-Version: 2.5
2
+ Name: slybrowser
3
+ Version: 0.1.0
4
+ Summary: Python SDK and CLI for SlyBrowser
5
+ Project-URL: Homepage, https://slybrowser.com
6
+ Project-URL: Repository, https://github.com/virtualfanc/slybrowser
7
+ Project-URL: Issues, https://github.com/virtualfanc/slybrowser/issues
8
+ Project-URL: Documentation, https://github.com/virtualfanc/slybrowser#readme
9
+ Author: SlyBrowser contributors
10
+ License-Expression: MIT
11
+ Keywords: browser-automation,playwright,slybrowser,webdriver
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Requires-Python: >=3.10
16
+ Requires-Dist: cryptography>=44
17
+ Requires-Dist: platformdirs>=4.3
18
+ Provides-Extra: playwright
19
+ Requires-Dist: playwright<1.63,>=1.62; extra == 'playwright'
20
+ Description-Content-Type: text/markdown
21
+
22
+ # SlyBrowser for Python
23
+
24
+ The default `launch()` backend is SlyBrowser's project-built W3C WebDriver. Place
25
+ `chromedriver.exe` (`chromedriver` on Unix) beside the browser, pass
26
+ `driver_executable=...`, or set `SLYBROWSER_WEBDRIVER_PATH`.
27
+
28
+ ```python
29
+ from slybrowser import launch
30
+
31
+ with launch(browser_executable, short_lived_lease, humanize=True) as browser:
32
+ browser.get("https://example.test")
33
+ print(browser.title)
34
+ ```
35
+
36
+ The SDK never downloads or selects another driver. Install the optional Playwright
37
+ adapter with `pip install slybrowser[playwright]` and call `launch_playwright(...)`
38
+ only when that transport is explicitly required. Production packages require the exact
39
+ hash-matched browser and driver as sibling files, and each process consumes a separate
40
+ temporary copy of the short-lived signed lease. Humanize for the default path executes
41
+ natively in Sly WebDriver.
42
+
43
+ ## Playwright adapter
44
+
45
+ ```python
46
+ from playwright.sync_api import sync_playwright
47
+ from slybrowser import launch_playwright
48
+
49
+ with sync_playwright() as playwright:
50
+ browser = launch_playwright(
51
+ playwright,
52
+ browser_executable,
53
+ short_lived_lease,
54
+ framework_version="1.62.0",
55
+ )
56
+ ```
57
+
58
+ The adapter forces the authorized SlyBrowser executable, rejects Playwright's own
59
+ browser path, and validates the binding line. `launch_playwright_async`,
60
+ `launch_playwright_persistent` and its async equivalent follow the same contract.
61
+ When `humanize=True` is set, the SDK writes a short-lived
62
+ `--sly-humanize-config` native control file for the browser process. The Python SDK
63
+ does not install a Playwright-side movement substitute; unsupported browser builds
64
+ must fail closed at the native capability gate.
65
+
66
+ ## Install and launch the latest authorized release
67
+
68
+ Current release archives use 7z. Install `7z` (or `7zz` on Unix-like systems), or set `SLYBROWSER_7Z_PATH` to the executable before using the automatic installer.
69
+
70
+ `launch_latest()` reserves one plan slot, verifies the signed short lease and latest
71
+ compatible Stable manifest, downloads the protected ZIP, validates both runtime
72
+ executables and maintains a heartbeat until the browser closes.
73
+
74
+ ```python
75
+ from playwright.sync_api import sync_playwright
76
+ from slybrowser import launch_latest, launch_latest_playwright
77
+
78
+ with launch_latest(
79
+ "account.authorization.json",
80
+ license_trusted_keys={"license-prod-v1": license_public_key},
81
+ release_trusted_keys={"release-prod-v1": release_public_key},
82
+ humanize=True,
83
+ ) as browser:
84
+ print(browser.license_runtime)
85
+ browser.get("https://example.test")
86
+
87
+ with sync_playwright() as playwright:
88
+ browser = launch_latest_playwright(
89
+ playwright,
90
+ "account.authorization.json",
91
+ license_trusted_keys={"license-prod-v1": license_public_key},
92
+ release_trusted_keys={"release-prod-v1": release_public_key},
93
+ framework_version="1.62.0",
94
+ )
95
+ try:
96
+ print(browser.license_runtime["versionAudit"])
97
+ finally:
98
+ browser.close()
99
+ ```
100
+
101
+ The authorized Playwright launchers reserve and release the same concurrency slot as
102
+ `launch_latest(...)`, expose `license_runtime["versionAudit"]`, and fail closed if
103
+ Playwright reports a launched browser version that does not exactly match the signed
104
+ selected release. Use `launch_latest_playwright_persistent(...)`,
105
+ `launch_latest_playwright_async(...)` or
106
+ `launch_latest_playwright_persistent_async(...)` for the matching profile and runtime
107
+ style.
108
+
109
+ For the CLI, provide base64url raw 32-byte Ed25519 keys through
110
+ `SLYBROWSER_LICENSE_PUBLIC_KEYS_JSON` and `SLYBROWSER_RELEASE_PUBLIC_KEYS_JSON`, then
111
+ run:
112
+
113
+ ```text
114
+ slybrowser install --authorization account.authorization.json [--cache DIR] [--kernel-major 150|latest] [--update-kernel]
115
+ ```
116
+
117
+ ## Import a paid license file on Windows
118
+
119
+ After checkout, import the encrypted v2 license file once on the Windows machine
120
+ that will run SlyBrowser:
121
+
122
+ ```text
123
+ set SLYBROWSER_LICENSE_FILE_PUBLIC_KEYS_JSON={"license-file-prod-v1":"BASE64URL_RAW_ED25519_PUBLIC_KEY"}
124
+ slybrowser license import --input account.slybrowser-license.json --output account.slybrowser-sealed-license.json --passphrase YOUR_PASSPHRASE
125
+ ```
126
+
127
+ The sealed file uses Windows DPAPI current-user protection and can be used anywhere
128
+ an authorization file is accepted, including `launch_latest(...)` and the authorized
129
+ Playwright helpers. You do not need to pass the license-file passphrase again, but
130
+ the sealed file is still a local credential and must not be committed, logged, or
131
+ shared.
132
+
133
+ ## Redacted license diagnostics
134
+
135
+ Use `license info` when a customer needs support without exposing their credential:
136
+
137
+ ```text
138
+ slybrowser license info --authorization account.slybrowser-sealed-license.json [--kernel-major 150|latest] [--update-kernel]
139
+ ```
140
+
141
+ The command contacts the authorization service through `Authorization: License ...`
142
+ and prints only redacted diagnostics: plan, effective plan, paid-through time,
143
+ feature set, active/available browser-process concurrency, selected release state,
144
+ update availability and `stableErrorCode`. It does not print the license key,
145
+ session tokens, download tickets, email, PayNow identifiers, profile paths or service
146
+ access URL.
147
+
148
+ Without `--update-kernel`, the CLI keeps updates closed: it reuses the current
149
+ authorized local candidate when one exists and asks the service for an exact grant.
150
+ Use `--update-kernel` to actively move to the newest authorized Stable release in
151
+ the selected major range.
152
+
153
+ The authorization file is a credential and must not be committed or logged. See
154
+ `docs/authorized-release-service.md` for the public authorization and release flow.
@@ -0,0 +1,133 @@
1
+ # SlyBrowser for Python
2
+
3
+ The default `launch()` backend is SlyBrowser's project-built W3C WebDriver. Place
4
+ `chromedriver.exe` (`chromedriver` on Unix) beside the browser, pass
5
+ `driver_executable=...`, or set `SLYBROWSER_WEBDRIVER_PATH`.
6
+
7
+ ```python
8
+ from slybrowser import launch
9
+
10
+ with launch(browser_executable, short_lived_lease, humanize=True) as browser:
11
+ browser.get("https://example.test")
12
+ print(browser.title)
13
+ ```
14
+
15
+ The SDK never downloads or selects another driver. Install the optional Playwright
16
+ adapter with `pip install slybrowser[playwright]` and call `launch_playwright(...)`
17
+ only when that transport is explicitly required. Production packages require the exact
18
+ hash-matched browser and driver as sibling files, and each process consumes a separate
19
+ temporary copy of the short-lived signed lease. Humanize for the default path executes
20
+ natively in Sly WebDriver.
21
+
22
+ ## Playwright adapter
23
+
24
+ ```python
25
+ from playwright.sync_api import sync_playwright
26
+ from slybrowser import launch_playwright
27
+
28
+ with sync_playwright() as playwright:
29
+ browser = launch_playwright(
30
+ playwright,
31
+ browser_executable,
32
+ short_lived_lease,
33
+ framework_version="1.62.0",
34
+ )
35
+ ```
36
+
37
+ The adapter forces the authorized SlyBrowser executable, rejects Playwright's own
38
+ browser path, and validates the binding line. `launch_playwright_async`,
39
+ `launch_playwright_persistent` and its async equivalent follow the same contract.
40
+ When `humanize=True` is set, the SDK writes a short-lived
41
+ `--sly-humanize-config` native control file for the browser process. The Python SDK
42
+ does not install a Playwright-side movement substitute; unsupported browser builds
43
+ must fail closed at the native capability gate.
44
+
45
+ ## Install and launch the latest authorized release
46
+
47
+ Current release archives use 7z. Install `7z` (or `7zz` on Unix-like systems), or set `SLYBROWSER_7Z_PATH` to the executable before using the automatic installer.
48
+
49
+ `launch_latest()` reserves one plan slot, verifies the signed short lease and latest
50
+ compatible Stable manifest, downloads the protected ZIP, validates both runtime
51
+ executables and maintains a heartbeat until the browser closes.
52
+
53
+ ```python
54
+ from playwright.sync_api import sync_playwright
55
+ from slybrowser import launch_latest, launch_latest_playwright
56
+
57
+ with launch_latest(
58
+ "account.authorization.json",
59
+ license_trusted_keys={"license-prod-v1": license_public_key},
60
+ release_trusted_keys={"release-prod-v1": release_public_key},
61
+ humanize=True,
62
+ ) as browser:
63
+ print(browser.license_runtime)
64
+ browser.get("https://example.test")
65
+
66
+ with sync_playwright() as playwright:
67
+ browser = launch_latest_playwright(
68
+ playwright,
69
+ "account.authorization.json",
70
+ license_trusted_keys={"license-prod-v1": license_public_key},
71
+ release_trusted_keys={"release-prod-v1": release_public_key},
72
+ framework_version="1.62.0",
73
+ )
74
+ try:
75
+ print(browser.license_runtime["versionAudit"])
76
+ finally:
77
+ browser.close()
78
+ ```
79
+
80
+ The authorized Playwright launchers reserve and release the same concurrency slot as
81
+ `launch_latest(...)`, expose `license_runtime["versionAudit"]`, and fail closed if
82
+ Playwright reports a launched browser version that does not exactly match the signed
83
+ selected release. Use `launch_latest_playwright_persistent(...)`,
84
+ `launch_latest_playwright_async(...)` or
85
+ `launch_latest_playwright_persistent_async(...)` for the matching profile and runtime
86
+ style.
87
+
88
+ For the CLI, provide base64url raw 32-byte Ed25519 keys through
89
+ `SLYBROWSER_LICENSE_PUBLIC_KEYS_JSON` and `SLYBROWSER_RELEASE_PUBLIC_KEYS_JSON`, then
90
+ run:
91
+
92
+ ```text
93
+ slybrowser install --authorization account.authorization.json [--cache DIR] [--kernel-major 150|latest] [--update-kernel]
94
+ ```
95
+
96
+ ## Import a paid license file on Windows
97
+
98
+ After checkout, import the encrypted v2 license file once on the Windows machine
99
+ that will run SlyBrowser:
100
+
101
+ ```text
102
+ set SLYBROWSER_LICENSE_FILE_PUBLIC_KEYS_JSON={"license-file-prod-v1":"BASE64URL_RAW_ED25519_PUBLIC_KEY"}
103
+ slybrowser license import --input account.slybrowser-license.json --output account.slybrowser-sealed-license.json --passphrase YOUR_PASSPHRASE
104
+ ```
105
+
106
+ The sealed file uses Windows DPAPI current-user protection and can be used anywhere
107
+ an authorization file is accepted, including `launch_latest(...)` and the authorized
108
+ Playwright helpers. You do not need to pass the license-file passphrase again, but
109
+ the sealed file is still a local credential and must not be committed, logged, or
110
+ shared.
111
+
112
+ ## Redacted license diagnostics
113
+
114
+ Use `license info` when a customer needs support without exposing their credential:
115
+
116
+ ```text
117
+ slybrowser license info --authorization account.slybrowser-sealed-license.json [--kernel-major 150|latest] [--update-kernel]
118
+ ```
119
+
120
+ The command contacts the authorization service through `Authorization: License ...`
121
+ and prints only redacted diagnostics: plan, effective plan, paid-through time,
122
+ feature set, active/available browser-process concurrency, selected release state,
123
+ update availability and `stableErrorCode`. It does not print the license key,
124
+ session tokens, download tickets, email, PayNow identifiers, profile paths or service
125
+ access URL.
126
+
127
+ Without `--update-kernel`, the CLI keeps updates closed: it reuses the current
128
+ authorized local candidate when one exists and asks the service for an exact grant.
129
+ Use `--update-kernel` to actively move to the newest authorized Stable release in
130
+ the selected major range.
131
+
132
+ The authorization file is a credential and must not be committed or logged. See
133
+ `docs/authorized-release-service.md` for the public authorization and release flow.
@@ -0,0 +1,41 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.27"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "slybrowser"
7
+ version = "0.1.0"
8
+ description = "Python SDK and CLI for SlyBrowser"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ authors = [{ name = "SlyBrowser contributors" }]
13
+ keywords = ["slybrowser", "webdriver", "playwright", "browser-automation"]
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Programming Language :: Python :: 3",
17
+ "Programming Language :: Python :: 3 :: Only",
18
+ ]
19
+ dependencies = [
20
+ "cryptography>=44",
21
+ "platformdirs>=4.3",
22
+ ]
23
+
24
+ [project.optional-dependencies]
25
+ playwright = ["playwright>=1.62,<1.63"]
26
+
27
+ [project.urls]
28
+ Homepage = "https://slybrowser.com"
29
+ Repository = "https://github.com/virtualfanc/slybrowser"
30
+ Issues = "https://github.com/virtualfanc/slybrowser/issues"
31
+ Documentation = "https://github.com/virtualfanc/slybrowser#readme"
32
+
33
+ [project.scripts]
34
+ slybrowser = "slybrowser.cli:main"
35
+
36
+ [tool.hatch.build.targets.wheel]
37
+ packages = ["src/slybrowser"]
38
+
39
+ [tool.pytest.ini_options]
40
+ testpaths = ["tests"]
41
+ addopts = "-ra"