hyperbrowser 0.93.4__tar.gz → 1.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.
Files changed (114) hide show
  1. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/PKG-INFO +123 -71
  2. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/README.md +121 -70
  3. hyperbrowser-1.1.0/hyperbrowser/client/_request.py +124 -0
  4. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/async_manager/agents/browser_use.py +18 -11
  5. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/async_manager/agents/claude_computer_use.py +16 -3
  6. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/async_manager/agents/cua.py +12 -3
  7. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/async_manager/agents/gemini_computer_use.py +16 -3
  8. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/async_manager/agents/grok_computer_use.py +16 -3
  9. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/async_manager/agents/hyper_agent.py +10 -3
  10. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/async_manager/computer_action.py +57 -8
  11. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/async_manager/crawl.py +20 -5
  12. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/async_manager/extension.py +16 -13
  13. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/async_manager/extract.py +22 -10
  14. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/async_manager/profile.py +22 -14
  15. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/async_manager/sandbox.py +97 -60
  16. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/async_manager/sandboxes/sandbox_files.py +89 -59
  17. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/async_manager/sandboxes/sandbox_processes.py +21 -8
  18. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/async_manager/sandboxes/sandbox_terminal.py +13 -8
  19. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/async_manager/scrape.py +30 -9
  20. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/async_manager/session.py +80 -30
  21. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/async_manager/volume.py +9 -5
  22. hyperbrowser-1.1.0/hyperbrowser/client/managers/async_manager/web/__init__.py +43 -0
  23. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/async_manager/web/batch_fetch.py +26 -19
  24. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/async_manager/web/crawl.py +26 -19
  25. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/sandboxes/shared.py +22 -16
  26. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/sync_manager/agents/browser_use.py +20 -11
  27. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/sync_manager/agents/claude_computer_use.py +16 -3
  28. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/sync_manager/agents/cua.py +12 -3
  29. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/sync_manager/agents/gemini_computer_use.py +16 -3
  30. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/sync_manager/agents/grok_computer_use.py +16 -3
  31. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/sync_manager/agents/hyper_agent.py +12 -3
  32. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/sync_manager/computer_action.py +57 -8
  33. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/sync_manager/crawl.py +20 -6
  34. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/sync_manager/extension.py +16 -13
  35. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/sync_manager/extract.py +22 -10
  36. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/sync_manager/profile.py +24 -14
  37. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/sync_manager/sandbox.py +97 -60
  38. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/sync_manager/sandboxes/sandbox_files.py +89 -59
  39. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/sync_manager/sandboxes/sandbox_processes.py +21 -8
  40. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/sync_manager/sandboxes/sandbox_terminal.py +13 -8
  41. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/sync_manager/scrape.py +32 -9
  42. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/sync_manager/session.py +79 -28
  43. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/sync_manager/volume.py +9 -5
  44. hyperbrowser-1.1.0/hyperbrowser/client/managers/sync_manager/web/__init__.py +43 -0
  45. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/sync_manager/web/batch_fetch.py +28 -19
  46. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/sync_manager/web/crawl.py +26 -19
  47. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/models/agents/browser_use.py +18 -12
  48. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/models/agents/claude_computer_use.py +5 -3
  49. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/models/agents/cua.py +5 -3
  50. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/models/agents/gemini_computer_use.py +6 -3
  51. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/models/agents/grok_computer_use.py +5 -3
  52. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/models/agents/hyper_agent.py +3 -1
  53. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/models/crawl.py +4 -2
  54. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/models/extension.py +1 -1
  55. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/models/scrape.py +7 -5
  56. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/models/session.py +10 -0
  57. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/models/web/branding.py +5 -5
  58. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/models/web/common.py +6 -6
  59. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/models/web/fetch.py +2 -2
  60. hyperbrowser-1.1.0/hyperbrowser/py.typed +1 -0
  61. hyperbrowser-1.1.0/hyperbrowser/tools/__init__.py +145 -0
  62. hyperbrowser-1.1.0/hyperbrowser/types/__init__.py +309 -0
  63. hyperbrowser-1.1.0/hyperbrowser/types/_json.py +33 -0
  64. hyperbrowser-1.1.0/hyperbrowser/types/agents.py +177 -0
  65. hyperbrowser-1.1.0/hyperbrowser/types/computer_action.py +160 -0
  66. hyperbrowser-1.1.0/hyperbrowser/types/crawl.py +29 -0
  67. hyperbrowser-1.1.0/hyperbrowser/types/extension.py +13 -0
  68. hyperbrowser-1.1.0/hyperbrowser/types/extract.py +32 -0
  69. hyperbrowser-1.1.0/hyperbrowser/types/profile.py +26 -0
  70. hyperbrowser-1.1.0/hyperbrowser/types/sandbox.py +438 -0
  71. hyperbrowser-1.1.0/hyperbrowser/types/scrape.py +76 -0
  72. hyperbrowser-1.1.0/hyperbrowser/types/session.py +209 -0
  73. hyperbrowser-1.1.0/hyperbrowser/types/volume.py +10 -0
  74. hyperbrowser-1.1.0/hyperbrowser/types/web.py +246 -0
  75. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/pyproject.toml +6 -2
  76. hyperbrowser-0.93.4/hyperbrowser/client/managers/async_manager/web/__init__.py +0 -41
  77. hyperbrowser-0.93.4/hyperbrowser/client/managers/sync_manager/web/__init__.py +0 -41
  78. hyperbrowser-0.93.4/hyperbrowser/tools/__init__.py +0 -127
  79. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/LICENSE +0 -0
  80. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/__init__.py +0 -0
  81. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/async_client.py +0 -0
  82. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/base.py +0 -0
  83. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/async_manager/agents/__init__.py +0 -0
  84. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/async_manager/sandboxes/__init__.py +0 -0
  85. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/async_manager/sandboxes/sandbox_transport.py +0 -0
  86. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/async_manager/team.py +0 -0
  87. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/sandboxes/__init__.py +0 -0
  88. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/sandboxes/image_build.py +0 -0
  89. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/sync_manager/agents/__init__.py +0 -0
  90. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/sync_manager/sandboxes/__init__.py +0 -0
  91. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/sync_manager/sandboxes/sandbox_transport.py +0 -0
  92. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/managers/sync_manager/team.py +0 -0
  93. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/client/sync.py +0 -0
  94. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/config.py +0 -0
  95. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/exceptions.py +0 -0
  96. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/models/__init__.py +0 -0
  97. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/models/_parsers.py +0 -0
  98. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/models/computer_action.py +0 -0
  99. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/models/consts.py +0 -0
  100. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/models/extract.py +0 -0
  101. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/models/profile.py +0 -0
  102. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/models/sandbox.py +0 -0
  103. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/models/team.py +0 -0
  104. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/models/volume.py +0 -0
  105. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/models/web/batch_fetch.py +0 -0
  106. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/models/web/crawl.py +0 -0
  107. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/models/web/search.py +0 -0
  108. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/sandbox_common.py +0 -0
  109. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/tools/anthropic.py +0 -0
  110. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/tools/openai.py +0 -0
  111. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/tools/schema.py +0 -0
  112. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/transport/async_transport.py +0 -0
  113. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/transport/base.py +0 -0
  114. {hyperbrowser-0.93.4 → hyperbrowser-1.1.0}/hyperbrowser/transport/sync.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hyperbrowser
3
- Version: 0.93.4
3
+ Version: 1.1.0
4
4
  Summary: Python SDK for hyperbrowser
5
5
  License: MIT
6
6
  License-File: LICENSE
@@ -19,6 +19,7 @@ Classifier: Programming Language :: Python :: 3.14
19
19
  Requires-Dist: httpx (>=0.23.0,<1)
20
20
  Requires-Dist: jsonref (>=1.1.0)
21
21
  Requires-Dist: pydantic (>=2.0,<3)
22
+ Requires-Dist: typing-extensions (>=4.0,<5)
22
23
  Requires-Dist: websockets (>=13,<16)
23
24
  Project-URL: Homepage, https://github.com/hyperbrowserai/python-sdk
24
25
  Project-URL: Repository, https://github.com/hyperbrowserai/python-sdk
@@ -41,6 +42,12 @@ It can be installed from `pypi` by running :
41
42
  pip install hyperbrowser
42
43
  ```
43
44
 
45
+ The browser-control examples below also use Playwright:
46
+
47
+ ```shell
48
+ pip install playwright
49
+ ```
50
+
44
51
  ## Configuration
45
52
 
46
53
  Both the sync and async client follow similar configuration params
@@ -56,12 +63,76 @@ Profile names must match `^[A-Za-z0-9._-]+$`.
56
63
 
57
64
  ## Usage
58
65
 
66
+ Hyperbrowser 1.0 accepts plain dictionaries for request parameters. Method
67
+ signatures use `TypedDict` definitions, so editors can autocomplete keys at
68
+ every nested level:
69
+
70
+ ```python
71
+ from hyperbrowser import Hyperbrowser
72
+
73
+ client = Hyperbrowser(api_key="test-key")
74
+
75
+ # Preferred in 1.0: autocomplete works directly in the dictionary.
76
+ session = client.sessions.create(
77
+ {
78
+ "use_stealth": True,
79
+ "screen": {"width": 1920, "height": 1080},
80
+ }
81
+ )
82
+ ```
83
+
84
+ Browser sessions can also use an outbound network policy. Omitting these fields
85
+ keeps the default unrestricted behavior:
86
+
87
+ ```python
88
+ session = client.sessions.create(
89
+ {
90
+ "allow_internet_access": False,
91
+ "allow_out": ["example.com"],
92
+ "deny_out": ["0.0.0.0/0"],
93
+ }
94
+ )
95
+ ```
96
+
97
+ Direct browser policies accept domains, IPv4 addresses, and CIDR ranges in
98
+ `allow_out`; `deny_out` accepts IPv4 addresses and CIDR ranges. With a proxy,
99
+ allow rules must be domains and the only supported deny rule is `0.0.0.0/0`.
100
+
101
+ Existing Pydantic request classes remain accepted, so upgrading does not require
102
+ an immediate rewrite:
103
+
104
+ ```python
105
+ from hyperbrowser.models import CreateSessionParams, ScreenConfig
106
+
107
+ session = client.sessions.create(
108
+ CreateSessionParams(
109
+ use_stealth=True,
110
+ screen=ScreenConfig(width=1920, height=1080),
111
+ )
112
+ )
113
+ ```
114
+
115
+ Import request annotations from `hyperbrowser.types` when a named variable is
116
+ useful. The same names under `hyperbrowser.models` refer to the legacy Pydantic
117
+ request classes. Responses remain Pydantic models.
118
+
119
+ JSON Schema fields accept raw schema values, including object schemas with
120
+ `$defs`, `$ref`, or custom keywords, and boolean schemas where the API supports
121
+ them. Those schemas and other user-owned mappings are preserved as data; only
122
+ SDK-owned request keys are translated to their API aliases. Schema fields
123
+ documented as accepting a model class can also generate a schema from a Pydantic
124
+ model.
125
+
126
+ See the
127
+ [Hyperbrowser Python SDK 1.0 migration guide](https://hyperbrowser.ai/docs/sdks/python-1-0-migration)
128
+ for the complete compatibility details and migration checklist.
129
+
59
130
  ### Async
60
131
 
61
132
  ```python
62
133
  import asyncio
63
- from pyppeteer import connect
64
134
  from hyperbrowser import AsyncHyperbrowser
135
+ from playwright.async_api import async_playwright
65
136
 
66
137
  HYPERBROWSER_API_KEY = "test-key"
67
138
 
@@ -69,29 +140,22 @@ async def main():
69
140
  async with AsyncHyperbrowser(api_key=HYPERBROWSER_API_KEY) as client:
70
141
  session = await client.sessions.create()
71
142
 
72
- ws_endpoint = session.ws_endpoint
73
- browser = await connect(browserWSEndpoint=ws_endpoint, defaultViewport=None)
74
-
75
- # Get pages
76
- pages = await browser.pages()
77
- if not pages:
78
- raise Exception("No pages available")
79
-
80
- page = pages[0]
143
+ try:
144
+ async with async_playwright() as playwright:
145
+ browser = await playwright.chromium.connect_over_cdp(
146
+ session.ws_endpoint
147
+ )
148
+ context = browser.contexts[0]
149
+ page = context.pages[0]
81
150
 
82
- # Navigate to a website
83
- print("Navigating to Hacker News...")
84
- await page.goto("https://news.ycombinator.com/")
85
- page_title = await page.title()
86
- print("Page title:", page_title)
87
-
88
- await page.close()
89
- await browser.disconnect()
90
- await client.sessions.stop(session.id)
91
- print("Session completed!")
151
+ print("Navigating to Hacker News...")
152
+ await page.goto("https://news.ycombinator.com/")
153
+ print("Page title:", await page.title())
154
+ finally:
155
+ await client.sessions.stop(session.id)
92
156
 
93
157
  # Run the asyncio event loop
94
- asyncio.get_event_loop().run_until_complete(main())
158
+ asyncio.run(main())
95
159
  ```
96
160
  ### Sync
97
161
 
@@ -141,17 +205,16 @@ The sync and async clients expose the same sandbox APIs through `client.sandboxe
141
205
 
142
206
  ```python
143
207
  from hyperbrowser import Hyperbrowser
144
- from hyperbrowser.models import CreateSandboxParams, SandboxExposeParams
145
208
 
146
209
  client = Hyperbrowser(api_key="test-key")
147
210
  sandbox = client.sandboxes.create(
148
- CreateSandboxParams(
149
- image_name="node",
150
- cpu=4,
151
- memory_mib=4096,
152
- disk_mib=8192,
153
- exposed_ports=[SandboxExposeParams(port=3000, auth=True)],
154
- )
211
+ {
212
+ "image_name": "node",
213
+ "cpu": 2,
214
+ "memory_mib": 2048,
215
+ "disk_mib": 8192,
216
+ "exposed_ports": [{"port": 3000, "auth": True}],
217
+ }
155
218
  )
156
219
 
157
220
  print(sandbox.exposed_ports[0].browser_url)
@@ -166,25 +229,24 @@ client.close()
166
229
 
167
230
  ```python
168
231
  from hyperbrowser import Hyperbrowser
169
- from hyperbrowser.models import CreateSandboxParams, CreateVolumeParams, SandboxVolumeMount
170
232
 
171
233
  client = Hyperbrowser(api_key="test-key")
172
234
 
173
- volume = client.volumes.create(CreateVolumeParams(name="project-cache"))
235
+ volume = client.volumes.create({"name": "project-cache"})
174
236
  all_volumes = client.volumes.list()
175
237
  same_volume = client.volumes.get(volume.id)
176
238
 
177
239
  sandbox = client.sandboxes.create(
178
- CreateSandboxParams(
179
- image_name="node",
180
- mounts={
181
- "/workspace/cache": SandboxVolumeMount(
182
- id=same_volume.id,
183
- type="rw",
184
- shared=True,
185
- )
240
+ {
241
+ "image_name": "node",
242
+ "mounts": {
243
+ "/workspace/cache": {
244
+ "id": same_volume.id,
245
+ "type": "rw",
246
+ "shared": True,
247
+ }
186
248
  },
187
- )
249
+ }
188
250
  )
189
251
 
190
252
  sandbox.stop()
@@ -195,17 +257,16 @@ client.close()
195
257
 
196
258
  ```python
197
259
  from hyperbrowser import Hyperbrowser
198
- from hyperbrowser.models import SandboxListParams
199
260
 
200
261
  client = Hyperbrowser(api_key="test-key")
201
262
  result = client.sandboxes.list(
202
- SandboxListParams(
203
- status="active",
204
- search="sandbox",
205
- start=1711929600000,
206
- end=1712016000000,
207
- limit=20,
208
- )
263
+ {
264
+ "status": "active",
265
+ "search": "sandbox",
266
+ "start": 1711929600000,
267
+ "end": 1712016000000,
268
+ "limit": 20,
269
+ }
209
270
  )
210
271
 
211
272
  for sandbox in result.sandboxes:
@@ -216,11 +277,10 @@ for sandbox in result.sandboxes:
216
277
 
217
278
  ```python
218
279
  from hyperbrowser import Hyperbrowser
219
- from hyperbrowser.models import SandboxSnapshotListParams
220
280
 
221
281
  client = Hyperbrowser(api_key="test-key")
222
282
  snapshots = client.sandboxes.list_snapshots(
223
- SandboxSnapshotListParams(image_name="node", status="created", limit=10)
283
+ {"image_name": "node", "status": "created", "limit": 10}
224
284
  )
225
285
  ```
226
286
 
@@ -228,16 +288,13 @@ snapshots = client.sandboxes.list_snapshots(
228
288
 
229
289
  ```python
230
290
  from hyperbrowser import Hyperbrowser
231
- from hyperbrowser.models import CreateSandboxParams, SandboxExposeParams
232
291
 
233
292
  client = Hyperbrowser(api_key="test-key")
234
293
  sandbox = client.sandboxes.create(
235
- CreateSandboxParams(
236
- image_name="node", cpu=2, memory_mib=2048, disk_mib=8192
237
- )
294
+ {"image_name": "node", "cpu": 2, "memory_mib": 2048, "disk_mib": 8192}
238
295
  )
239
296
 
240
- result = sandbox.expose(SandboxExposeParams(port=8080, auth=True))
297
+ result = sandbox.expose({"port": 8080, "auth": True})
241
298
  print(result.url, result.browser_url)
242
299
 
243
300
  sandbox.unexpose(8080)
@@ -247,23 +304,19 @@ sandbox.unexpose(8080)
247
304
 
248
305
  ```python
249
306
  from hyperbrowser import Hyperbrowser
250
- from hyperbrowser.models import CreateSandboxParams, SandboxFileWriteEntry
251
307
 
252
308
  client = Hyperbrowser(api_key="test-key")
253
- sandbox = client.sandboxes.create(CreateSandboxParams(image_name="node"))
309
+ sandbox = client.sandboxes.create({"image_name": "node"})
254
310
 
255
311
  sandbox.files.write(
256
312
  [
257
- SandboxFileWriteEntry(
258
- path="/tmp/config.json",
259
- data='{"debug":true}\n',
260
- append=True,
261
- mode="600",
262
- ),
263
- SandboxFileWriteEntry(
264
- path="/tmp/blob.bin",
265
- data=b"\x00\x01\x02",
266
- ),
313
+ {
314
+ "path": "/tmp/config.json",
315
+ "data": '{"debug":true}\n',
316
+ "append": True,
317
+ "mode": "600",
318
+ },
319
+ {"path": "/tmp/blob.bin", "data": b"\x00\x01\x02"},
267
320
  ]
268
321
  )
269
322
  ```
@@ -272,11 +325,10 @@ sandbox.files.write(
272
325
 
273
326
  ```python
274
327
  from hyperbrowser import Hyperbrowser
275
- from hyperbrowser.models import CreateSandboxParams, SandboxTerminalCreateParams
276
328
 
277
329
  client = Hyperbrowser(api_key="test-key")
278
- sandbox = client.sandboxes.create(CreateSandboxParams(image_name="node"))
279
- terminal = sandbox.terminal.create(SandboxTerminalCreateParams(command="bash"))
330
+ sandbox = client.sandboxes.create({"image_name": "node"})
331
+ terminal = sandbox.terminal.create({"command": "bash"})
280
332
 
281
333
  connection = terminal.attach(cursor=10)
282
334
  for event in connection.events():
@@ -15,6 +15,12 @@ It can be installed from `pypi` by running :
15
15
  pip install hyperbrowser
16
16
  ```
17
17
 
18
+ The browser-control examples below also use Playwright:
19
+
20
+ ```shell
21
+ pip install playwright
22
+ ```
23
+
18
24
  ## Configuration
19
25
 
20
26
  Both the sync and async client follow similar configuration params
@@ -30,12 +36,76 @@ Profile names must match `^[A-Za-z0-9._-]+$`.
30
36
 
31
37
  ## Usage
32
38
 
39
+ Hyperbrowser 1.0 accepts plain dictionaries for request parameters. Method
40
+ signatures use `TypedDict` definitions, so editors can autocomplete keys at
41
+ every nested level:
42
+
43
+ ```python
44
+ from hyperbrowser import Hyperbrowser
45
+
46
+ client = Hyperbrowser(api_key="test-key")
47
+
48
+ # Preferred in 1.0: autocomplete works directly in the dictionary.
49
+ session = client.sessions.create(
50
+ {
51
+ "use_stealth": True,
52
+ "screen": {"width": 1920, "height": 1080},
53
+ }
54
+ )
55
+ ```
56
+
57
+ Browser sessions can also use an outbound network policy. Omitting these fields
58
+ keeps the default unrestricted behavior:
59
+
60
+ ```python
61
+ session = client.sessions.create(
62
+ {
63
+ "allow_internet_access": False,
64
+ "allow_out": ["example.com"],
65
+ "deny_out": ["0.0.0.0/0"],
66
+ }
67
+ )
68
+ ```
69
+
70
+ Direct browser policies accept domains, IPv4 addresses, and CIDR ranges in
71
+ `allow_out`; `deny_out` accepts IPv4 addresses and CIDR ranges. With a proxy,
72
+ allow rules must be domains and the only supported deny rule is `0.0.0.0/0`.
73
+
74
+ Existing Pydantic request classes remain accepted, so upgrading does not require
75
+ an immediate rewrite:
76
+
77
+ ```python
78
+ from hyperbrowser.models import CreateSessionParams, ScreenConfig
79
+
80
+ session = client.sessions.create(
81
+ CreateSessionParams(
82
+ use_stealth=True,
83
+ screen=ScreenConfig(width=1920, height=1080),
84
+ )
85
+ )
86
+ ```
87
+
88
+ Import request annotations from `hyperbrowser.types` when a named variable is
89
+ useful. The same names under `hyperbrowser.models` refer to the legacy Pydantic
90
+ request classes. Responses remain Pydantic models.
91
+
92
+ JSON Schema fields accept raw schema values, including object schemas with
93
+ `$defs`, `$ref`, or custom keywords, and boolean schemas where the API supports
94
+ them. Those schemas and other user-owned mappings are preserved as data; only
95
+ SDK-owned request keys are translated to their API aliases. Schema fields
96
+ documented as accepting a model class can also generate a schema from a Pydantic
97
+ model.
98
+
99
+ See the
100
+ [Hyperbrowser Python SDK 1.0 migration guide](https://hyperbrowser.ai/docs/sdks/python-1-0-migration)
101
+ for the complete compatibility details and migration checklist.
102
+
33
103
  ### Async
34
104
 
35
105
  ```python
36
106
  import asyncio
37
- from pyppeteer import connect
38
107
  from hyperbrowser import AsyncHyperbrowser
108
+ from playwright.async_api import async_playwright
39
109
 
40
110
  HYPERBROWSER_API_KEY = "test-key"
41
111
 
@@ -43,29 +113,22 @@ async def main():
43
113
  async with AsyncHyperbrowser(api_key=HYPERBROWSER_API_KEY) as client:
44
114
  session = await client.sessions.create()
45
115
 
46
- ws_endpoint = session.ws_endpoint
47
- browser = await connect(browserWSEndpoint=ws_endpoint, defaultViewport=None)
48
-
49
- # Get pages
50
- pages = await browser.pages()
51
- if not pages:
52
- raise Exception("No pages available")
53
-
54
- page = pages[0]
116
+ try:
117
+ async with async_playwright() as playwright:
118
+ browser = await playwright.chromium.connect_over_cdp(
119
+ session.ws_endpoint
120
+ )
121
+ context = browser.contexts[0]
122
+ page = context.pages[0]
55
123
 
56
- # Navigate to a website
57
- print("Navigating to Hacker News...")
58
- await page.goto("https://news.ycombinator.com/")
59
- page_title = await page.title()
60
- print("Page title:", page_title)
61
-
62
- await page.close()
63
- await browser.disconnect()
64
- await client.sessions.stop(session.id)
65
- print("Session completed!")
124
+ print("Navigating to Hacker News...")
125
+ await page.goto("https://news.ycombinator.com/")
126
+ print("Page title:", await page.title())
127
+ finally:
128
+ await client.sessions.stop(session.id)
66
129
 
67
130
  # Run the asyncio event loop
68
- asyncio.get_event_loop().run_until_complete(main())
131
+ asyncio.run(main())
69
132
  ```
70
133
  ### Sync
71
134
 
@@ -115,17 +178,16 @@ The sync and async clients expose the same sandbox APIs through `client.sandboxe
115
178
 
116
179
  ```python
117
180
  from hyperbrowser import Hyperbrowser
118
- from hyperbrowser.models import CreateSandboxParams, SandboxExposeParams
119
181
 
120
182
  client = Hyperbrowser(api_key="test-key")
121
183
  sandbox = client.sandboxes.create(
122
- CreateSandboxParams(
123
- image_name="node",
124
- cpu=4,
125
- memory_mib=4096,
126
- disk_mib=8192,
127
- exposed_ports=[SandboxExposeParams(port=3000, auth=True)],
128
- )
184
+ {
185
+ "image_name": "node",
186
+ "cpu": 2,
187
+ "memory_mib": 2048,
188
+ "disk_mib": 8192,
189
+ "exposed_ports": [{"port": 3000, "auth": True}],
190
+ }
129
191
  )
130
192
 
131
193
  print(sandbox.exposed_ports[0].browser_url)
@@ -140,25 +202,24 @@ client.close()
140
202
 
141
203
  ```python
142
204
  from hyperbrowser import Hyperbrowser
143
- from hyperbrowser.models import CreateSandboxParams, CreateVolumeParams, SandboxVolumeMount
144
205
 
145
206
  client = Hyperbrowser(api_key="test-key")
146
207
 
147
- volume = client.volumes.create(CreateVolumeParams(name="project-cache"))
208
+ volume = client.volumes.create({"name": "project-cache"})
148
209
  all_volumes = client.volumes.list()
149
210
  same_volume = client.volumes.get(volume.id)
150
211
 
151
212
  sandbox = client.sandboxes.create(
152
- CreateSandboxParams(
153
- image_name="node",
154
- mounts={
155
- "/workspace/cache": SandboxVolumeMount(
156
- id=same_volume.id,
157
- type="rw",
158
- shared=True,
159
- )
213
+ {
214
+ "image_name": "node",
215
+ "mounts": {
216
+ "/workspace/cache": {
217
+ "id": same_volume.id,
218
+ "type": "rw",
219
+ "shared": True,
220
+ }
160
221
  },
161
- )
222
+ }
162
223
  )
163
224
 
164
225
  sandbox.stop()
@@ -169,17 +230,16 @@ client.close()
169
230
 
170
231
  ```python
171
232
  from hyperbrowser import Hyperbrowser
172
- from hyperbrowser.models import SandboxListParams
173
233
 
174
234
  client = Hyperbrowser(api_key="test-key")
175
235
  result = client.sandboxes.list(
176
- SandboxListParams(
177
- status="active",
178
- search="sandbox",
179
- start=1711929600000,
180
- end=1712016000000,
181
- limit=20,
182
- )
236
+ {
237
+ "status": "active",
238
+ "search": "sandbox",
239
+ "start": 1711929600000,
240
+ "end": 1712016000000,
241
+ "limit": 20,
242
+ }
183
243
  )
184
244
 
185
245
  for sandbox in result.sandboxes:
@@ -190,11 +250,10 @@ for sandbox in result.sandboxes:
190
250
 
191
251
  ```python
192
252
  from hyperbrowser import Hyperbrowser
193
- from hyperbrowser.models import SandboxSnapshotListParams
194
253
 
195
254
  client = Hyperbrowser(api_key="test-key")
196
255
  snapshots = client.sandboxes.list_snapshots(
197
- SandboxSnapshotListParams(image_name="node", status="created", limit=10)
256
+ {"image_name": "node", "status": "created", "limit": 10}
198
257
  )
199
258
  ```
200
259
 
@@ -202,16 +261,13 @@ snapshots = client.sandboxes.list_snapshots(
202
261
 
203
262
  ```python
204
263
  from hyperbrowser import Hyperbrowser
205
- from hyperbrowser.models import CreateSandboxParams, SandboxExposeParams
206
264
 
207
265
  client = Hyperbrowser(api_key="test-key")
208
266
  sandbox = client.sandboxes.create(
209
- CreateSandboxParams(
210
- image_name="node", cpu=2, memory_mib=2048, disk_mib=8192
211
- )
267
+ {"image_name": "node", "cpu": 2, "memory_mib": 2048, "disk_mib": 8192}
212
268
  )
213
269
 
214
- result = sandbox.expose(SandboxExposeParams(port=8080, auth=True))
270
+ result = sandbox.expose({"port": 8080, "auth": True})
215
271
  print(result.url, result.browser_url)
216
272
 
217
273
  sandbox.unexpose(8080)
@@ -221,23 +277,19 @@ sandbox.unexpose(8080)
221
277
 
222
278
  ```python
223
279
  from hyperbrowser import Hyperbrowser
224
- from hyperbrowser.models import CreateSandboxParams, SandboxFileWriteEntry
225
280
 
226
281
  client = Hyperbrowser(api_key="test-key")
227
- sandbox = client.sandboxes.create(CreateSandboxParams(image_name="node"))
282
+ sandbox = client.sandboxes.create({"image_name": "node"})
228
283
 
229
284
  sandbox.files.write(
230
285
  [
231
- SandboxFileWriteEntry(
232
- path="/tmp/config.json",
233
- data='{"debug":true}\n',
234
- append=True,
235
- mode="600",
236
- ),
237
- SandboxFileWriteEntry(
238
- path="/tmp/blob.bin",
239
- data=b"\x00\x01\x02",
240
- ),
286
+ {
287
+ "path": "/tmp/config.json",
288
+ "data": '{"debug":true}\n',
289
+ "append": True,
290
+ "mode": "600",
291
+ },
292
+ {"path": "/tmp/blob.bin", "data": b"\x00\x01\x02"},
241
293
  ]
242
294
  )
243
295
  ```
@@ -246,11 +298,10 @@ sandbox.files.write(
246
298
 
247
299
  ```python
248
300
  from hyperbrowser import Hyperbrowser
249
- from hyperbrowser.models import CreateSandboxParams, SandboxTerminalCreateParams
250
301
 
251
302
  client = Hyperbrowser(api_key="test-key")
252
- sandbox = client.sandboxes.create(CreateSandboxParams(image_name="node"))
253
- terminal = sandbox.terminal.create(SandboxTerminalCreateParams(command="bash"))
303
+ sandbox = client.sandboxes.create({"image_name": "node"})
304
+ terminal = sandbox.terminal.create({"command": "bash"})
254
305
 
255
306
  connection = terminal.attach(cursor=10)
256
307
  for event in connection.events():