hyperbrowser 0.41.0__tar.gz → 0.71.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.
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/LICENSE +1 -1
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/PKG-INFO +8 -2
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/README.md +4 -1
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/client/async_client.py +4 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/client/base.py +1 -1
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/client/managers/async_manager/agents/__init__.py +4 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/client/managers/async_manager/agents/browser_use.py +8 -0
- hyperbrowser-0.71.0/hyperbrowser/client/managers/async_manager/agents/gemini_computer_use.py +71 -0
- hyperbrowser-0.71.0/hyperbrowser/client/managers/async_manager/agents/hyper_agent.py +71 -0
- hyperbrowser-0.71.0/hyperbrowser/client/managers/async_manager/computer_action.py +165 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/client/managers/async_manager/crawl.py +1 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/client/managers/async_manager/scrape.py +1 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/client/managers/async_manager/session.py +51 -1
- hyperbrowser-0.71.0/hyperbrowser/client/managers/async_manager/team.py +12 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/client/managers/sync_manager/agents/__init__.py +4 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/client/managers/sync_manager/agents/browser_use.py +8 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/client/managers/sync_manager/agents/claude_computer_use.py +1 -1
- hyperbrowser-0.71.0/hyperbrowser/client/managers/sync_manager/agents/gemini_computer_use.py +71 -0
- hyperbrowser-0.71.0/hyperbrowser/client/managers/sync_manager/agents/hyper_agent.py +69 -0
- hyperbrowser-0.71.0/hyperbrowser/client/managers/sync_manager/computer_action.py +165 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/client/managers/sync_manager/crawl.py +1 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/client/managers/sync_manager/scrape.py +1 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/client/managers/sync_manager/session.py +47 -1
- hyperbrowser-0.71.0/hyperbrowser/client/managers/sync_manager/team.py +12 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/client/sync.py +4 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/config.py +2 -2
- hyperbrowser-0.71.0/hyperbrowser/models/__init__.py +340 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/models/agents/browser_use.py +113 -3
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/models/agents/claude_computer_use.py +38 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/models/agents/cua.py +32 -0
- hyperbrowser-0.71.0/hyperbrowser/models/agents/gemini_computer_use.py +135 -0
- hyperbrowser-0.71.0/hyperbrowser/models/agents/hyper_agent.py +153 -0
- hyperbrowser-0.71.0/hyperbrowser/models/computer_action.py +208 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/models/consts.py +34 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/models/extract.py +11 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/models/scrape.py +15 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/models/session.py +165 -11
- hyperbrowser-0.71.0/hyperbrowser/models/team.py +15 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/pyproject.toml +1 -1
- hyperbrowser-0.41.0/hyperbrowser/models/__init__.py +0 -179
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/__init__.py +0 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/client/managers/async_manager/agents/claude_computer_use.py +0 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/client/managers/async_manager/agents/cua.py +0 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/client/managers/async_manager/extension.py +0 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/client/managers/async_manager/extract.py +0 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/client/managers/async_manager/profile.py +0 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/client/managers/sync_manager/agents/cua.py +0 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/client/managers/sync_manager/extension.py +0 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/client/managers/sync_manager/extract.py +0 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/client/managers/sync_manager/profile.py +0 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/exceptions.py +0 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/models/crawl.py +0 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/models/extension.py +0 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/models/profile.py +0 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/tools/__init__.py +0 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/tools/anthropic.py +0 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/tools/openai.py +0 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/tools/schema.py +0 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/transport/async_transport.py +0 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/transport/base.py +0 -0
- {hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/transport/sync.py +0 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: hyperbrowser
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.71.0
|
|
4
4
|
Summary: Python SDK for hyperbrowser
|
|
5
5
|
License: MIT
|
|
6
|
+
License-File: LICENSE
|
|
6
7
|
Author: Nikhil Shahi
|
|
7
8
|
Author-email: nshahi1998@gmail.com
|
|
8
9
|
Requires-Python: >=3.8,<4.0
|
|
@@ -14,6 +15,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
14
15
|
Classifier: Programming Language :: Python :: 3.11
|
|
15
16
|
Classifier: Programming Language :: Python :: 3.12
|
|
16
17
|
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
17
19
|
Requires-Dist: httpx (>=0.23.0,<1)
|
|
18
20
|
Requires-Dist: jsonref (>=1.1.0)
|
|
19
21
|
Requires-Dist: pydantic (>=2.0,<3)
|
|
@@ -123,3 +125,7 @@ def main():
|
|
|
123
125
|
# Run the asyncio event loop
|
|
124
126
|
main()
|
|
125
127
|
```
|
|
128
|
+
## License
|
|
129
|
+
|
|
130
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
131
|
+
|
|
@@ -10,6 +10,8 @@ from .managers.async_manager.extract import ExtractManager
|
|
|
10
10
|
from .managers.async_manager.profile import ProfileManager
|
|
11
11
|
from .managers.async_manager.scrape import ScrapeManager
|
|
12
12
|
from .managers.async_manager.session import SessionManager
|
|
13
|
+
from .managers.async_manager.team import TeamManager
|
|
14
|
+
from .managers.async_manager.computer_action import ComputerActionManager
|
|
13
15
|
|
|
14
16
|
|
|
15
17
|
class AsyncHyperbrowser(HyperbrowserBase):
|
|
@@ -31,6 +33,8 @@ class AsyncHyperbrowser(HyperbrowserBase):
|
|
|
31
33
|
self.profiles = ProfileManager(self)
|
|
32
34
|
self.extensions = ExtensionManager(self)
|
|
33
35
|
self.agents = Agents(self)
|
|
36
|
+
self.team = TeamManager(self)
|
|
37
|
+
self.computer_action = ComputerActionManager(self)
|
|
34
38
|
|
|
35
39
|
async def close(self) -> None:
|
|
36
40
|
await self.transport.close()
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
from .browser_use import BrowserUseManager
|
|
2
2
|
from .cua import CuaManager
|
|
3
3
|
from .claude_computer_use import ClaudeComputerUseManager
|
|
4
|
+
from .hyper_agent import HyperAgentManager
|
|
5
|
+
from .gemini_computer_use import GeminiComputerUseManager
|
|
4
6
|
|
|
5
7
|
|
|
6
8
|
class Agents:
|
|
@@ -8,3 +10,5 @@ class Agents:
|
|
|
8
10
|
self.browser_use = BrowserUseManager(client)
|
|
9
11
|
self.cua = CuaManager(client)
|
|
10
12
|
self.claude_computer_use = ClaudeComputerUseManager(client)
|
|
13
|
+
self.hyper_agent = HyperAgentManager(client)
|
|
14
|
+
self.gemini_computer_use = GeminiComputerUseManager(client)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
+
import jsonref
|
|
2
3
|
|
|
3
4
|
from hyperbrowser.exceptions import HyperbrowserError
|
|
4
5
|
|
|
@@ -19,6 +20,13 @@ class BrowserUseManager:
|
|
|
19
20
|
async def start(
|
|
20
21
|
self, params: StartBrowserUseTaskParams
|
|
21
22
|
) -> StartBrowserUseTaskResponse:
|
|
23
|
+
if params.output_model_schema:
|
|
24
|
+
if hasattr(params.output_model_schema, "model_json_schema"):
|
|
25
|
+
params.output_model_schema = jsonref.replace_refs(
|
|
26
|
+
params.output_model_schema.model_json_schema(),
|
|
27
|
+
proxies=False,
|
|
28
|
+
lazy_load=False,
|
|
29
|
+
)
|
|
22
30
|
response = await self._client.transport.post(
|
|
23
31
|
self._client._build_url("/task/browser-use"),
|
|
24
32
|
data=params.model_dump(exclude_none=True, by_alias=True),
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
|
|
3
|
+
from hyperbrowser.exceptions import HyperbrowserError
|
|
4
|
+
|
|
5
|
+
from .....models import (
|
|
6
|
+
POLLING_ATTEMPTS,
|
|
7
|
+
BasicResponse,
|
|
8
|
+
GeminiComputerUseTaskResponse,
|
|
9
|
+
GeminiComputerUseTaskStatusResponse,
|
|
10
|
+
StartGeminiComputerUseTaskParams,
|
|
11
|
+
StartGeminiComputerUseTaskResponse,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class GeminiComputerUseManager:
|
|
16
|
+
def __init__(self, client):
|
|
17
|
+
self._client = client
|
|
18
|
+
|
|
19
|
+
async def start(
|
|
20
|
+
self, params: StartGeminiComputerUseTaskParams
|
|
21
|
+
) -> StartGeminiComputerUseTaskResponse:
|
|
22
|
+
response = await self._client.transport.post(
|
|
23
|
+
self._client._build_url("/task/gemini-computer-use"),
|
|
24
|
+
data=params.model_dump(exclude_none=True, by_alias=True),
|
|
25
|
+
)
|
|
26
|
+
return StartGeminiComputerUseTaskResponse(**response.data)
|
|
27
|
+
|
|
28
|
+
async def get(self, job_id: str) -> GeminiComputerUseTaskResponse:
|
|
29
|
+
response = await self._client.transport.get(
|
|
30
|
+
self._client._build_url(f"/task/gemini-computer-use/{job_id}")
|
|
31
|
+
)
|
|
32
|
+
return GeminiComputerUseTaskResponse(**response.data)
|
|
33
|
+
|
|
34
|
+
async def get_status(self, job_id: str) -> GeminiComputerUseTaskStatusResponse:
|
|
35
|
+
response = await self._client.transport.get(
|
|
36
|
+
self._client._build_url(f"/task/gemini-computer-use/{job_id}/status")
|
|
37
|
+
)
|
|
38
|
+
return GeminiComputerUseTaskStatusResponse(**response.data)
|
|
39
|
+
|
|
40
|
+
async def stop(self, job_id: str) -> BasicResponse:
|
|
41
|
+
response = await self._client.transport.put(
|
|
42
|
+
self._client._build_url(f"/task/gemini-computer-use/{job_id}/stop")
|
|
43
|
+
)
|
|
44
|
+
return BasicResponse(**response.data)
|
|
45
|
+
|
|
46
|
+
async def start_and_wait(
|
|
47
|
+
self, params: StartGeminiComputerUseTaskParams
|
|
48
|
+
) -> GeminiComputerUseTaskResponse:
|
|
49
|
+
job_start_resp = await self.start(params)
|
|
50
|
+
job_id = job_start_resp.job_id
|
|
51
|
+
if not job_id:
|
|
52
|
+
raise HyperbrowserError("Failed to start Gemini Computer Use task job")
|
|
53
|
+
|
|
54
|
+
failures = 0
|
|
55
|
+
while True:
|
|
56
|
+
try:
|
|
57
|
+
job_response = await self.get_status(job_id)
|
|
58
|
+
if (
|
|
59
|
+
job_response.status == "completed"
|
|
60
|
+
or job_response.status == "failed"
|
|
61
|
+
or job_response.status == "stopped"
|
|
62
|
+
):
|
|
63
|
+
return await self.get(job_id)
|
|
64
|
+
failures = 0
|
|
65
|
+
except Exception as e:
|
|
66
|
+
failures += 1
|
|
67
|
+
if failures >= POLLING_ATTEMPTS:
|
|
68
|
+
raise HyperbrowserError(
|
|
69
|
+
f"Failed to poll Gemini Computer Use task job {job_id} after {POLLING_ATTEMPTS} attempts: {e}"
|
|
70
|
+
)
|
|
71
|
+
await asyncio.sleep(2)
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
|
|
3
|
+
from hyperbrowser.exceptions import HyperbrowserError
|
|
4
|
+
|
|
5
|
+
from .....models import (
|
|
6
|
+
POLLING_ATTEMPTS,
|
|
7
|
+
BasicResponse,
|
|
8
|
+
HyperAgentTaskResponse,
|
|
9
|
+
HyperAgentTaskStatusResponse,
|
|
10
|
+
StartHyperAgentTaskParams,
|
|
11
|
+
StartHyperAgentTaskResponse,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class HyperAgentManager:
|
|
16
|
+
def __init__(self, client):
|
|
17
|
+
self._client = client
|
|
18
|
+
|
|
19
|
+
async def start(
|
|
20
|
+
self, params: StartHyperAgentTaskParams
|
|
21
|
+
) -> StartHyperAgentTaskResponse:
|
|
22
|
+
response = await self._client.transport.post(
|
|
23
|
+
self._client._build_url("/task/hyper-agent"),
|
|
24
|
+
data=params.model_dump(exclude_none=True, by_alias=True),
|
|
25
|
+
)
|
|
26
|
+
return StartHyperAgentTaskResponse(**response.data)
|
|
27
|
+
|
|
28
|
+
async def get(self, job_id: str) -> HyperAgentTaskResponse:
|
|
29
|
+
response = await self._client.transport.get(
|
|
30
|
+
self._client._build_url(f"/task/hyper-agent/{job_id}")
|
|
31
|
+
)
|
|
32
|
+
return HyperAgentTaskResponse(**response.data)
|
|
33
|
+
|
|
34
|
+
async def get_status(self, job_id: str) -> HyperAgentTaskStatusResponse:
|
|
35
|
+
response = await self._client.transport.get(
|
|
36
|
+
self._client._build_url(f"/task/hyper-agent/{job_id}/status")
|
|
37
|
+
)
|
|
38
|
+
return HyperAgentTaskStatusResponse(**response.data)
|
|
39
|
+
|
|
40
|
+
async def stop(self, job_id: str) -> BasicResponse:
|
|
41
|
+
response = await self._client.transport.put(
|
|
42
|
+
self._client._build_url(f"/task/hyper-agent/{job_id}/stop")
|
|
43
|
+
)
|
|
44
|
+
return BasicResponse(**response.data)
|
|
45
|
+
|
|
46
|
+
async def start_and_wait(
|
|
47
|
+
self, params: StartHyperAgentTaskParams
|
|
48
|
+
) -> HyperAgentTaskResponse:
|
|
49
|
+
job_start_resp = await self.start(params)
|
|
50
|
+
job_id = job_start_resp.job_id
|
|
51
|
+
if not job_id:
|
|
52
|
+
raise HyperbrowserError("Failed to start HyperAgent task")
|
|
53
|
+
|
|
54
|
+
failures = 0
|
|
55
|
+
while True:
|
|
56
|
+
try:
|
|
57
|
+
job_response = await self.get_status(job_id)
|
|
58
|
+
if (
|
|
59
|
+
job_response.status == "completed"
|
|
60
|
+
or job_response.status == "failed"
|
|
61
|
+
or job_response.status == "stopped"
|
|
62
|
+
):
|
|
63
|
+
return await self.get(job_id)
|
|
64
|
+
failures = 0
|
|
65
|
+
except Exception as e:
|
|
66
|
+
failures += 1
|
|
67
|
+
if failures >= POLLING_ATTEMPTS:
|
|
68
|
+
raise HyperbrowserError(
|
|
69
|
+
f"Failed to poll HyperAgent task {job_id} after {POLLING_ATTEMPTS} attempts: {e}"
|
|
70
|
+
)
|
|
71
|
+
await asyncio.sleep(2)
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
from pydantic import BaseModel
|
|
2
|
+
from typing import Union, List, Optional
|
|
3
|
+
from hyperbrowser.models import (
|
|
4
|
+
SessionDetail,
|
|
5
|
+
ComputerActionParams,
|
|
6
|
+
ComputerActionResponse,
|
|
7
|
+
ClickActionParams,
|
|
8
|
+
DragActionParams,
|
|
9
|
+
PressKeysActionParams,
|
|
10
|
+
MoveMouseActionParams,
|
|
11
|
+
ScreenshotActionParams,
|
|
12
|
+
ScrollActionParams,
|
|
13
|
+
TypeTextActionParams,
|
|
14
|
+
Coordinate,
|
|
15
|
+
HoldKeyActionParams,
|
|
16
|
+
MouseDownActionParams,
|
|
17
|
+
MouseUpActionParams,
|
|
18
|
+
ComputerActionMouseButton,
|
|
19
|
+
GetClipboardTextActionParams,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ComputerActionManager:
|
|
24
|
+
def __init__(self, client):
|
|
25
|
+
self._client = client
|
|
26
|
+
|
|
27
|
+
async def _execute_request(
|
|
28
|
+
self, session: Union[SessionDetail, str], params: ComputerActionParams
|
|
29
|
+
) -> ComputerActionResponse:
|
|
30
|
+
if isinstance(session, str):
|
|
31
|
+
session = await self._client.sessions.get(session)
|
|
32
|
+
|
|
33
|
+
if not session.computer_action_endpoint:
|
|
34
|
+
raise ValueError("Computer action endpoint not available for this session")
|
|
35
|
+
|
|
36
|
+
if isinstance(params, BaseModel):
|
|
37
|
+
payload = params.model_dump(by_alias=True, exclude_none=True)
|
|
38
|
+
else:
|
|
39
|
+
payload = params
|
|
40
|
+
|
|
41
|
+
response = await self._client.transport.post(
|
|
42
|
+
session.computer_action_endpoint,
|
|
43
|
+
data=payload,
|
|
44
|
+
)
|
|
45
|
+
return ComputerActionResponse(**response.data)
|
|
46
|
+
|
|
47
|
+
async def click(
|
|
48
|
+
self,
|
|
49
|
+
session: Union[SessionDetail, str],
|
|
50
|
+
x: Optional[int] = None,
|
|
51
|
+
y: Optional[int] = None,
|
|
52
|
+
button: ComputerActionMouseButton = "left",
|
|
53
|
+
num_clicks: int = 1,
|
|
54
|
+
return_screenshot: bool = False,
|
|
55
|
+
) -> ComputerActionResponse:
|
|
56
|
+
params = ClickActionParams(
|
|
57
|
+
x=x,
|
|
58
|
+
y=y,
|
|
59
|
+
button=button,
|
|
60
|
+
num_clicks=num_clicks,
|
|
61
|
+
return_screenshot=return_screenshot,
|
|
62
|
+
)
|
|
63
|
+
return await self._execute_request(session, params)
|
|
64
|
+
|
|
65
|
+
async def type_text(
|
|
66
|
+
self,
|
|
67
|
+
session: Union[SessionDetail, str],
|
|
68
|
+
text: str,
|
|
69
|
+
return_screenshot: bool = False,
|
|
70
|
+
) -> ComputerActionResponse:
|
|
71
|
+
params = TypeTextActionParams(text=text, return_screenshot=return_screenshot)
|
|
72
|
+
return await self._execute_request(session, params)
|
|
73
|
+
|
|
74
|
+
async def screenshot(
|
|
75
|
+
self,
|
|
76
|
+
session: Union[SessionDetail, str],
|
|
77
|
+
) -> ComputerActionResponse:
|
|
78
|
+
params = ScreenshotActionParams()
|
|
79
|
+
return await self._execute_request(session, params)
|
|
80
|
+
|
|
81
|
+
async def press_keys(
|
|
82
|
+
self,
|
|
83
|
+
session: Union[SessionDetail, str],
|
|
84
|
+
keys: List[str],
|
|
85
|
+
return_screenshot: bool = False,
|
|
86
|
+
) -> ComputerActionResponse:
|
|
87
|
+
params = PressKeysActionParams(keys=keys, return_screenshot=return_screenshot)
|
|
88
|
+
return await self._execute_request(session, params)
|
|
89
|
+
|
|
90
|
+
async def hold_key(
|
|
91
|
+
self,
|
|
92
|
+
session: Union[SessionDetail, str],
|
|
93
|
+
key: str,
|
|
94
|
+
duration: int,
|
|
95
|
+
return_screenshot: bool = False,
|
|
96
|
+
) -> ComputerActionResponse:
|
|
97
|
+
params = HoldKeyActionParams(
|
|
98
|
+
key=key, duration=duration, return_screenshot=return_screenshot
|
|
99
|
+
)
|
|
100
|
+
return await self._execute_request(session, params)
|
|
101
|
+
|
|
102
|
+
async def mouse_down(
|
|
103
|
+
self,
|
|
104
|
+
session: Union[SessionDetail, str],
|
|
105
|
+
button: ComputerActionMouseButton = "left",
|
|
106
|
+
return_screenshot: bool = False,
|
|
107
|
+
) -> ComputerActionResponse:
|
|
108
|
+
params = MouseDownActionParams(
|
|
109
|
+
button=button, return_screenshot=return_screenshot
|
|
110
|
+
)
|
|
111
|
+
return await self._execute_request(session, params)
|
|
112
|
+
|
|
113
|
+
async def mouse_up(
|
|
114
|
+
self,
|
|
115
|
+
session: Union[SessionDetail, str],
|
|
116
|
+
button: ComputerActionMouseButton = "left",
|
|
117
|
+
return_screenshot: bool = False,
|
|
118
|
+
) -> ComputerActionResponse:
|
|
119
|
+
params = MouseUpActionParams(button=button, return_screenshot=return_screenshot)
|
|
120
|
+
return await self._execute_request(session, params)
|
|
121
|
+
|
|
122
|
+
async def drag(
|
|
123
|
+
self,
|
|
124
|
+
session: Union[SessionDetail, str],
|
|
125
|
+
path: List[Coordinate],
|
|
126
|
+
return_screenshot: bool = False,
|
|
127
|
+
) -> ComputerActionResponse:
|
|
128
|
+
params = DragActionParams(path=path, return_screenshot=return_screenshot)
|
|
129
|
+
return await self._execute_request(session, params)
|
|
130
|
+
|
|
131
|
+
async def move_mouse(
|
|
132
|
+
self,
|
|
133
|
+
session: Union[SessionDetail, str],
|
|
134
|
+
x: int,
|
|
135
|
+
y: int,
|
|
136
|
+
return_screenshot: bool = False,
|
|
137
|
+
) -> ComputerActionResponse:
|
|
138
|
+
params = MoveMouseActionParams(x=x, y=y, return_screenshot=return_screenshot)
|
|
139
|
+
return await self._execute_request(session, params)
|
|
140
|
+
|
|
141
|
+
async def scroll(
|
|
142
|
+
self,
|
|
143
|
+
session: Union[SessionDetail, str],
|
|
144
|
+
x: int,
|
|
145
|
+
y: int,
|
|
146
|
+
scroll_x: int,
|
|
147
|
+
scroll_y: int,
|
|
148
|
+
return_screenshot: bool = False,
|
|
149
|
+
) -> ComputerActionResponse:
|
|
150
|
+
params = ScrollActionParams(
|
|
151
|
+
x=x,
|
|
152
|
+
y=y,
|
|
153
|
+
scroll_x=scroll_x,
|
|
154
|
+
scroll_y=scroll_y,
|
|
155
|
+
return_screenshot=return_screenshot,
|
|
156
|
+
)
|
|
157
|
+
return await self._execute_request(session, params)
|
|
158
|
+
|
|
159
|
+
async def get_clipboard_text(
|
|
160
|
+
self,
|
|
161
|
+
session: Union[SessionDetail, str],
|
|
162
|
+
return_screenshot: bool = False,
|
|
163
|
+
) -> ComputerActionResponse:
|
|
164
|
+
params = GetClipboardTextActionParams(return_screenshot=return_screenshot)
|
|
165
|
+
return await self._execute_request(session, params)
|
{hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/client/managers/async_manager/crawl.py
RENAMED
|
@@ -103,6 +103,7 @@ class CrawlManager:
|
|
|
103
103
|
job_response.total_crawled_pages = tmp_job_response.total_crawled_pages
|
|
104
104
|
job_response.total_page_batches = tmp_job_response.total_page_batches
|
|
105
105
|
job_response.batch_size = tmp_job_response.batch_size
|
|
106
|
+
job_response.error = tmp_job_response.error
|
|
106
107
|
failures = 0
|
|
107
108
|
first_check = False
|
|
108
109
|
except Exception as e:
|
{hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/client/managers/async_manager/scrape.py
RENAMED
|
@@ -111,6 +111,7 @@ class BatchScrapeManager:
|
|
|
111
111
|
job_response.total_scraped_pages = tmp_job_response.total_scraped_pages
|
|
112
112
|
job_response.total_page_batches = tmp_job_response.total_page_batches
|
|
113
113
|
job_response.batch_size = tmp_job_response.batch_size
|
|
114
|
+
job_response.error = tmp_job_response.error
|
|
114
115
|
failures = 0
|
|
115
116
|
first_check = False
|
|
116
117
|
except Exception as e:
|
{hyperbrowser-0.41.0 → hyperbrowser-0.71.0}/hyperbrowser/client/managers/async_manager/session.py
RENAMED
|
@@ -1,19 +1,41 @@
|
|
|
1
|
-
from typing import List
|
|
1
|
+
from typing import List, Union, IO
|
|
2
2
|
from ....models.session import (
|
|
3
3
|
BasicResponse,
|
|
4
4
|
CreateSessionParams,
|
|
5
5
|
GetSessionDownloadsUrlResponse,
|
|
6
6
|
GetSessionRecordingUrlResponse,
|
|
7
|
+
GetSessionVideoRecordingUrlResponse,
|
|
7
8
|
SessionDetail,
|
|
8
9
|
SessionListParams,
|
|
9
10
|
SessionListResponse,
|
|
10
11
|
SessionRecording,
|
|
12
|
+
UploadFileResponse,
|
|
13
|
+
SessionEventLogListParams,
|
|
14
|
+
SessionEventLogListResponse,
|
|
15
|
+
SessionEventLog,
|
|
11
16
|
)
|
|
12
17
|
|
|
13
18
|
|
|
19
|
+
class SessionEventLogsManager:
|
|
20
|
+
def __init__(self, client):
|
|
21
|
+
self._client = client
|
|
22
|
+
|
|
23
|
+
async def list(
|
|
24
|
+
self,
|
|
25
|
+
session_id: str,
|
|
26
|
+
params: SessionEventLogListParams = SessionEventLogListParams(),
|
|
27
|
+
) -> List[SessionEventLog]:
|
|
28
|
+
response = await self._client.transport.get(
|
|
29
|
+
self._client._build_url(f"/session/{session_id}/event-logs"),
|
|
30
|
+
params=params.model_dump(exclude_none=True, by_alias=True),
|
|
31
|
+
)
|
|
32
|
+
return SessionEventLogListResponse(**response.data)
|
|
33
|
+
|
|
34
|
+
|
|
14
35
|
class SessionManager:
|
|
15
36
|
def __init__(self, client):
|
|
16
37
|
self._client = client
|
|
38
|
+
self.event_logs = SessionEventLogsManager(client)
|
|
17
39
|
|
|
18
40
|
async def create(self, params: CreateSessionParams = None) -> SessionDetail:
|
|
19
41
|
response = await self._client.transport.post(
|
|
@@ -59,8 +81,36 @@ class SessionManager:
|
|
|
59
81
|
)
|
|
60
82
|
return GetSessionRecordingUrlResponse(**response.data)
|
|
61
83
|
|
|
84
|
+
async def get_video_recording_url(
|
|
85
|
+
self, id: str
|
|
86
|
+
) -> GetSessionVideoRecordingUrlResponse:
|
|
87
|
+
response = await self._client.transport.get(
|
|
88
|
+
self._client._build_url(f"/session/{id}/video-recording-url")
|
|
89
|
+
)
|
|
90
|
+
return GetSessionVideoRecordingUrlResponse(**response.data)
|
|
91
|
+
|
|
62
92
|
async def get_downloads_url(self, id: str) -> GetSessionDownloadsUrlResponse:
|
|
63
93
|
response = await self._client.transport.get(
|
|
64
94
|
self._client._build_url(f"/session/{id}/downloads-url")
|
|
65
95
|
)
|
|
66
96
|
return GetSessionDownloadsUrlResponse(**response.data)
|
|
97
|
+
|
|
98
|
+
async def upload_file(
|
|
99
|
+
self, id: str, file_input: Union[str, IO]
|
|
100
|
+
) -> UploadFileResponse:
|
|
101
|
+
response = None
|
|
102
|
+
if isinstance(file_input, str):
|
|
103
|
+
with open(file_input, "rb") as file_obj:
|
|
104
|
+
files = {"file": file_obj}
|
|
105
|
+
response = await self._client.transport.post(
|
|
106
|
+
self._client._build_url(f"/session/{id}/uploads"),
|
|
107
|
+
files=files,
|
|
108
|
+
)
|
|
109
|
+
else:
|
|
110
|
+
files = {"file": file_input}
|
|
111
|
+
response = await self._client.transport.post(
|
|
112
|
+
self._client._build_url(f"/session/{id}/uploads"),
|
|
113
|
+
files=files,
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
return UploadFileResponse(**response.data)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from hyperbrowser.models import TeamCreditInfo
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class TeamManager:
|
|
5
|
+
def __init__(self, client):
|
|
6
|
+
self._client = client
|
|
7
|
+
|
|
8
|
+
async def get_credit_info(self) -> TeamCreditInfo:
|
|
9
|
+
response = await self._client.transport.get(
|
|
10
|
+
self._client._build_url("/team/credit-info")
|
|
11
|
+
)
|
|
12
|
+
return TeamCreditInfo(**response.data)
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
from .browser_use import BrowserUseManager
|
|
2
2
|
from .cua import CuaManager
|
|
3
3
|
from .claude_computer_use import ClaudeComputerUseManager
|
|
4
|
+
from .hyper_agent import HyperAgentManager
|
|
5
|
+
from .gemini_computer_use import GeminiComputerUseManager
|
|
4
6
|
|
|
5
7
|
|
|
6
8
|
class Agents:
|
|
@@ -8,3 +10,5 @@ class Agents:
|
|
|
8
10
|
self.browser_use = BrowserUseManager(client)
|
|
9
11
|
self.cua = CuaManager(client)
|
|
10
12
|
self.claude_computer_use = ClaudeComputerUseManager(client)
|
|
13
|
+
self.hyper_agent = HyperAgentManager(client)
|
|
14
|
+
self.gemini_computer_use = GeminiComputerUseManager(client)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import time
|
|
2
|
+
import jsonref
|
|
2
3
|
|
|
3
4
|
from hyperbrowser.exceptions import HyperbrowserError
|
|
4
5
|
|
|
@@ -17,6 +18,13 @@ class BrowserUseManager:
|
|
|
17
18
|
self._client = client
|
|
18
19
|
|
|
19
20
|
def start(self, params: StartBrowserUseTaskParams) -> StartBrowserUseTaskResponse:
|
|
21
|
+
if params.output_model_schema:
|
|
22
|
+
if hasattr(params.output_model_schema, "model_json_schema"):
|
|
23
|
+
params.output_model_schema = jsonref.replace_refs(
|
|
24
|
+
params.output_model_schema.model_json_schema(),
|
|
25
|
+
proxies=False,
|
|
26
|
+
lazy_load=False,
|
|
27
|
+
)
|
|
20
28
|
response = self._client.transport.post(
|
|
21
29
|
self._client._build_url("/task/browser-use"),
|
|
22
30
|
data=params.model_dump(exclude_none=True, by_alias=True),
|
|
@@ -49,7 +49,7 @@ class ClaudeComputerUseManager:
|
|
|
49
49
|
job_start_resp = self.start(params)
|
|
50
50
|
job_id = job_start_resp.job_id
|
|
51
51
|
if not job_id:
|
|
52
|
-
raise HyperbrowserError("Failed to start
|
|
52
|
+
raise HyperbrowserError("Failed to start Claude Computer Use task job")
|
|
53
53
|
|
|
54
54
|
failures = 0
|
|
55
55
|
while True:
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import time
|
|
2
|
+
|
|
3
|
+
from hyperbrowser.exceptions import HyperbrowserError
|
|
4
|
+
|
|
5
|
+
from .....models import (
|
|
6
|
+
POLLING_ATTEMPTS,
|
|
7
|
+
BasicResponse,
|
|
8
|
+
GeminiComputerUseTaskResponse,
|
|
9
|
+
GeminiComputerUseTaskStatusResponse,
|
|
10
|
+
StartGeminiComputerUseTaskParams,
|
|
11
|
+
StartGeminiComputerUseTaskResponse,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class GeminiComputerUseManager:
|
|
16
|
+
def __init__(self, client):
|
|
17
|
+
self._client = client
|
|
18
|
+
|
|
19
|
+
def start(
|
|
20
|
+
self, params: StartGeminiComputerUseTaskParams
|
|
21
|
+
) -> StartGeminiComputerUseTaskResponse:
|
|
22
|
+
response = self._client.transport.post(
|
|
23
|
+
self._client._build_url("/task/gemini-computer-use"),
|
|
24
|
+
data=params.model_dump(exclude_none=True, by_alias=True),
|
|
25
|
+
)
|
|
26
|
+
return StartGeminiComputerUseTaskResponse(**response.data)
|
|
27
|
+
|
|
28
|
+
def get(self, job_id: str) -> GeminiComputerUseTaskResponse:
|
|
29
|
+
response = self._client.transport.get(
|
|
30
|
+
self._client._build_url(f"/task/gemini-computer-use/{job_id}")
|
|
31
|
+
)
|
|
32
|
+
return GeminiComputerUseTaskResponse(**response.data)
|
|
33
|
+
|
|
34
|
+
def get_status(self, job_id: str) -> GeminiComputerUseTaskStatusResponse:
|
|
35
|
+
response = self._client.transport.get(
|
|
36
|
+
self._client._build_url(f"/task/gemini-computer-use/{job_id}/status")
|
|
37
|
+
)
|
|
38
|
+
return GeminiComputerUseTaskStatusResponse(**response.data)
|
|
39
|
+
|
|
40
|
+
def stop(self, job_id: str) -> BasicResponse:
|
|
41
|
+
response = self._client.transport.put(
|
|
42
|
+
self._client._build_url(f"/task/gemini-computer-use/{job_id}/stop")
|
|
43
|
+
)
|
|
44
|
+
return BasicResponse(**response.data)
|
|
45
|
+
|
|
46
|
+
def start_and_wait(
|
|
47
|
+
self, params: StartGeminiComputerUseTaskParams
|
|
48
|
+
) -> GeminiComputerUseTaskResponse:
|
|
49
|
+
job_start_resp = self.start(params)
|
|
50
|
+
job_id = job_start_resp.job_id
|
|
51
|
+
if not job_id:
|
|
52
|
+
raise HyperbrowserError("Failed to start Gemini Computer Use task job")
|
|
53
|
+
|
|
54
|
+
failures = 0
|
|
55
|
+
while True:
|
|
56
|
+
try:
|
|
57
|
+
job_response = self.get_status(job_id)
|
|
58
|
+
if (
|
|
59
|
+
job_response.status == "completed"
|
|
60
|
+
or job_response.status == "failed"
|
|
61
|
+
or job_response.status == "stopped"
|
|
62
|
+
):
|
|
63
|
+
return self.get(job_id)
|
|
64
|
+
failures = 0
|
|
65
|
+
except Exception as e:
|
|
66
|
+
failures += 1
|
|
67
|
+
if failures >= POLLING_ATTEMPTS:
|
|
68
|
+
raise HyperbrowserError(
|
|
69
|
+
f"Failed to poll Gemini Computer Use task job {job_id} after {POLLING_ATTEMPTS} attempts: {e}"
|
|
70
|
+
)
|
|
71
|
+
time.sleep(2)
|