optexity-browser-use 0.9.5__py3-none-any.whl

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 (147) hide show
  1. browser_use/__init__.py +157 -0
  2. browser_use/actor/__init__.py +11 -0
  3. browser_use/actor/element.py +1175 -0
  4. browser_use/actor/mouse.py +134 -0
  5. browser_use/actor/page.py +561 -0
  6. browser_use/actor/playground/flights.py +41 -0
  7. browser_use/actor/playground/mixed_automation.py +54 -0
  8. browser_use/actor/playground/playground.py +236 -0
  9. browser_use/actor/utils.py +176 -0
  10. browser_use/agent/cloud_events.py +282 -0
  11. browser_use/agent/gif.py +424 -0
  12. browser_use/agent/judge.py +170 -0
  13. browser_use/agent/message_manager/service.py +473 -0
  14. browser_use/agent/message_manager/utils.py +52 -0
  15. browser_use/agent/message_manager/views.py +98 -0
  16. browser_use/agent/prompts.py +413 -0
  17. browser_use/agent/service.py +2316 -0
  18. browser_use/agent/system_prompt.md +185 -0
  19. browser_use/agent/system_prompt_flash.md +10 -0
  20. browser_use/agent/system_prompt_no_thinking.md +183 -0
  21. browser_use/agent/views.py +743 -0
  22. browser_use/browser/__init__.py +41 -0
  23. browser_use/browser/cloud/cloud.py +203 -0
  24. browser_use/browser/cloud/views.py +89 -0
  25. browser_use/browser/events.py +578 -0
  26. browser_use/browser/profile.py +1158 -0
  27. browser_use/browser/python_highlights.py +548 -0
  28. browser_use/browser/session.py +3225 -0
  29. browser_use/browser/session_manager.py +399 -0
  30. browser_use/browser/video_recorder.py +162 -0
  31. browser_use/browser/views.py +200 -0
  32. browser_use/browser/watchdog_base.py +260 -0
  33. browser_use/browser/watchdogs/__init__.py +0 -0
  34. browser_use/browser/watchdogs/aboutblank_watchdog.py +253 -0
  35. browser_use/browser/watchdogs/crash_watchdog.py +335 -0
  36. browser_use/browser/watchdogs/default_action_watchdog.py +2729 -0
  37. browser_use/browser/watchdogs/dom_watchdog.py +817 -0
  38. browser_use/browser/watchdogs/downloads_watchdog.py +1277 -0
  39. browser_use/browser/watchdogs/local_browser_watchdog.py +461 -0
  40. browser_use/browser/watchdogs/permissions_watchdog.py +43 -0
  41. browser_use/browser/watchdogs/popups_watchdog.py +143 -0
  42. browser_use/browser/watchdogs/recording_watchdog.py +126 -0
  43. browser_use/browser/watchdogs/screenshot_watchdog.py +62 -0
  44. browser_use/browser/watchdogs/security_watchdog.py +280 -0
  45. browser_use/browser/watchdogs/storage_state_watchdog.py +335 -0
  46. browser_use/cli.py +2359 -0
  47. browser_use/code_use/__init__.py +16 -0
  48. browser_use/code_use/formatting.py +192 -0
  49. browser_use/code_use/namespace.py +665 -0
  50. browser_use/code_use/notebook_export.py +276 -0
  51. browser_use/code_use/service.py +1340 -0
  52. browser_use/code_use/system_prompt.md +574 -0
  53. browser_use/code_use/utils.py +150 -0
  54. browser_use/code_use/views.py +171 -0
  55. browser_use/config.py +505 -0
  56. browser_use/controller/__init__.py +3 -0
  57. browser_use/dom/enhanced_snapshot.py +161 -0
  58. browser_use/dom/markdown_extractor.py +169 -0
  59. browser_use/dom/playground/extraction.py +312 -0
  60. browser_use/dom/playground/multi_act.py +32 -0
  61. browser_use/dom/serializer/clickable_elements.py +200 -0
  62. browser_use/dom/serializer/code_use_serializer.py +287 -0
  63. browser_use/dom/serializer/eval_serializer.py +478 -0
  64. browser_use/dom/serializer/html_serializer.py +212 -0
  65. browser_use/dom/serializer/paint_order.py +197 -0
  66. browser_use/dom/serializer/serializer.py +1170 -0
  67. browser_use/dom/service.py +825 -0
  68. browser_use/dom/utils.py +129 -0
  69. browser_use/dom/views.py +906 -0
  70. browser_use/exceptions.py +5 -0
  71. browser_use/filesystem/__init__.py +0 -0
  72. browser_use/filesystem/file_system.py +619 -0
  73. browser_use/init_cmd.py +376 -0
  74. browser_use/integrations/gmail/__init__.py +24 -0
  75. browser_use/integrations/gmail/actions.py +115 -0
  76. browser_use/integrations/gmail/service.py +225 -0
  77. browser_use/llm/__init__.py +155 -0
  78. browser_use/llm/anthropic/chat.py +242 -0
  79. browser_use/llm/anthropic/serializer.py +312 -0
  80. browser_use/llm/aws/__init__.py +36 -0
  81. browser_use/llm/aws/chat_anthropic.py +242 -0
  82. browser_use/llm/aws/chat_bedrock.py +289 -0
  83. browser_use/llm/aws/serializer.py +257 -0
  84. browser_use/llm/azure/chat.py +91 -0
  85. browser_use/llm/base.py +57 -0
  86. browser_use/llm/browser_use/__init__.py +3 -0
  87. browser_use/llm/browser_use/chat.py +201 -0
  88. browser_use/llm/cerebras/chat.py +193 -0
  89. browser_use/llm/cerebras/serializer.py +109 -0
  90. browser_use/llm/deepseek/chat.py +212 -0
  91. browser_use/llm/deepseek/serializer.py +109 -0
  92. browser_use/llm/exceptions.py +29 -0
  93. browser_use/llm/google/__init__.py +3 -0
  94. browser_use/llm/google/chat.py +542 -0
  95. browser_use/llm/google/serializer.py +120 -0
  96. browser_use/llm/groq/chat.py +229 -0
  97. browser_use/llm/groq/parser.py +158 -0
  98. browser_use/llm/groq/serializer.py +159 -0
  99. browser_use/llm/messages.py +238 -0
  100. browser_use/llm/models.py +271 -0
  101. browser_use/llm/oci_raw/__init__.py +10 -0
  102. browser_use/llm/oci_raw/chat.py +443 -0
  103. browser_use/llm/oci_raw/serializer.py +229 -0
  104. browser_use/llm/ollama/chat.py +97 -0
  105. browser_use/llm/ollama/serializer.py +143 -0
  106. browser_use/llm/openai/chat.py +264 -0
  107. browser_use/llm/openai/like.py +15 -0
  108. browser_use/llm/openai/serializer.py +165 -0
  109. browser_use/llm/openrouter/chat.py +211 -0
  110. browser_use/llm/openrouter/serializer.py +26 -0
  111. browser_use/llm/schema.py +176 -0
  112. browser_use/llm/views.py +48 -0
  113. browser_use/logging_config.py +330 -0
  114. browser_use/mcp/__init__.py +18 -0
  115. browser_use/mcp/__main__.py +12 -0
  116. browser_use/mcp/client.py +544 -0
  117. browser_use/mcp/controller.py +264 -0
  118. browser_use/mcp/server.py +1114 -0
  119. browser_use/observability.py +204 -0
  120. browser_use/py.typed +0 -0
  121. browser_use/sandbox/__init__.py +41 -0
  122. browser_use/sandbox/sandbox.py +637 -0
  123. browser_use/sandbox/views.py +132 -0
  124. browser_use/screenshots/__init__.py +1 -0
  125. browser_use/screenshots/service.py +52 -0
  126. browser_use/sync/__init__.py +6 -0
  127. browser_use/sync/auth.py +357 -0
  128. browser_use/sync/service.py +161 -0
  129. browser_use/telemetry/__init__.py +51 -0
  130. browser_use/telemetry/service.py +112 -0
  131. browser_use/telemetry/views.py +101 -0
  132. browser_use/tokens/__init__.py +0 -0
  133. browser_use/tokens/custom_pricing.py +24 -0
  134. browser_use/tokens/mappings.py +4 -0
  135. browser_use/tokens/service.py +580 -0
  136. browser_use/tokens/views.py +108 -0
  137. browser_use/tools/registry/service.py +572 -0
  138. browser_use/tools/registry/views.py +174 -0
  139. browser_use/tools/service.py +1675 -0
  140. browser_use/tools/utils.py +82 -0
  141. browser_use/tools/views.py +100 -0
  142. browser_use/utils.py +670 -0
  143. optexity_browser_use-0.9.5.dist-info/METADATA +344 -0
  144. optexity_browser_use-0.9.5.dist-info/RECORD +147 -0
  145. optexity_browser_use-0.9.5.dist-info/WHEEL +4 -0
  146. optexity_browser_use-0.9.5.dist-info/entry_points.txt +3 -0
  147. optexity_browser_use-0.9.5.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,41 @@
1
+ from typing import TYPE_CHECKING
2
+
3
+ # Type stubs for lazy imports
4
+ if TYPE_CHECKING:
5
+ from .profile import BrowserProfile, ProxySettings
6
+ from .session import BrowserSession
7
+
8
+
9
+ # Lazy imports mapping for heavy browser components
10
+ _LAZY_IMPORTS = {
11
+ 'ProxySettings': ('.profile', 'ProxySettings'),
12
+ 'BrowserProfile': ('.profile', 'BrowserProfile'),
13
+ 'BrowserSession': ('.session', 'BrowserSession'),
14
+ }
15
+
16
+
17
+ def __getattr__(name: str):
18
+ """Lazy import mechanism for heavy browser components."""
19
+ if name in _LAZY_IMPORTS:
20
+ module_path, attr_name = _LAZY_IMPORTS[name]
21
+ try:
22
+ from importlib import import_module
23
+
24
+ # Use relative import for current package
25
+ full_module_path = f'browser_use.browser{module_path}'
26
+ module = import_module(full_module_path)
27
+ attr = getattr(module, attr_name)
28
+ # Cache the imported attribute in the module's globals
29
+ globals()[name] = attr
30
+ return attr
31
+ except ImportError as e:
32
+ raise ImportError(f'Failed to import {name} from {full_module_path}: {e}') from e
33
+
34
+ raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
35
+
36
+
37
+ __all__ = [
38
+ 'BrowserSession',
39
+ 'BrowserProfile',
40
+ 'ProxySettings',
41
+ ]
@@ -0,0 +1,203 @@
1
+ """Cloud browser service integration for browser-use.
2
+
3
+ This module provides integration with the browser-use cloud browser service.
4
+ When cloud_browser=True, it automatically creates a cloud browser instance
5
+ and returns the CDP URL for connection.
6
+ """
7
+
8
+ import logging
9
+ import os
10
+
11
+ import httpx
12
+
13
+ from browser_use.browser.cloud.views import CloudBrowserAuthError, CloudBrowserError, CloudBrowserResponse, CreateBrowserRequest
14
+ from browser_use.sync.auth import CloudAuthConfig
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+
19
+ class CloudBrowserClient:
20
+ """Client for browser-use cloud browser service."""
21
+
22
+ def __init__(self, api_base_url: str = 'https://api.browser-use.com'):
23
+ self.api_base_url = api_base_url
24
+ self.client = httpx.AsyncClient(timeout=30.0)
25
+ self.current_session_id: str | None = None
26
+
27
+ async def create_browser(
28
+ self, request: CreateBrowserRequest, extra_headers: dict[str, str] | None = None
29
+ ) -> CloudBrowserResponse:
30
+ """Create a new cloud browser instance. For full docs refer to https://docs.cloud.browser-use.com/api-reference/v-2-api-current/browsers/create-browser-session-browsers-post
31
+
32
+ Args:
33
+ request: CreateBrowserRequest object containing browser creation parameters
34
+
35
+ Returns:
36
+ CloudBrowserResponse: Contains CDP URL and other browser info
37
+ """
38
+ url = f'{self.api_base_url}/api/v2/browsers'
39
+
40
+ # Try to get API key from environment variable first, then auth config
41
+ api_token = os.getenv('BROWSER_USE_API_KEY')
42
+
43
+ if not api_token:
44
+ # Fallback to auth config file
45
+ try:
46
+ auth_config = CloudAuthConfig.load_from_file()
47
+ api_token = auth_config.api_token
48
+ except Exception:
49
+ pass
50
+
51
+ if not api_token:
52
+ raise CloudBrowserAuthError(
53
+ 'No authentication token found. Please set BROWSER_USE_API_KEY environment variable to authenticate with the cloud service. You can also create an API key at https://cloud.browser-use.com/new-api-key'
54
+ )
55
+
56
+ headers = {'X-Browser-Use-API-Key': api_token, 'Content-Type': 'application/json', **(extra_headers or {})}
57
+
58
+ # Convert request to dictionary and exclude unset fields
59
+ request_body = request.model_dump(exclude_unset=True)
60
+
61
+ try:
62
+ logger.info('🌤️ Creating cloud browser instance...')
63
+
64
+ response = await self.client.post(url, headers=headers, json=request_body)
65
+
66
+ if response.status_code == 401:
67
+ raise CloudBrowserAuthError(
68
+ 'Authentication failed. Please make sure you have set BROWSER_USE_API_KEY environment variable to authenticate with the cloud service. You can also create an API key at https://cloud.browser-use.com/new-api-key'
69
+ )
70
+ elif response.status_code == 403:
71
+ raise CloudBrowserAuthError('Access forbidden. Please check your browser-use cloud subscription status.')
72
+ elif not response.is_success:
73
+ error_msg = f'Failed to create cloud browser: HTTP {response.status_code}'
74
+ try:
75
+ error_data = response.json()
76
+ if 'detail' in error_data:
77
+ error_msg += f' - {error_data["detail"]}'
78
+ except Exception:
79
+ pass
80
+ raise CloudBrowserError(error_msg)
81
+
82
+ browser_data = response.json()
83
+ browser_response = CloudBrowserResponse(**browser_data)
84
+
85
+ # Store session ID for cleanup
86
+ self.current_session_id = browser_response.id
87
+
88
+ logger.info(f'🌤️ Cloud browser created successfully: {browser_response.id}')
89
+ logger.debug(f'🌤️ CDP URL: {browser_response.cdpUrl}')
90
+ # Cyan color for live URL
91
+ logger.info(f'\033[36m🔗 Live URL: {browser_response.liveUrl}\033[0m')
92
+
93
+ return browser_response
94
+
95
+ except httpx.TimeoutException:
96
+ raise CloudBrowserError('Timeout while creating cloud browser. Please try again.')
97
+ except httpx.ConnectError:
98
+ raise CloudBrowserError('Failed to connect to cloud browser service. Please check your internet connection.')
99
+ except Exception as e:
100
+ if isinstance(e, (CloudBrowserError, CloudBrowserAuthError)):
101
+ raise
102
+ raise CloudBrowserError(f'Unexpected error creating cloud browser: {e}')
103
+
104
+ async def stop_browser(
105
+ self, session_id: str | None = None, extra_headers: dict[str, str] | None = None
106
+ ) -> CloudBrowserResponse:
107
+ """Stop a cloud browser session.
108
+
109
+ Args:
110
+ session_id: Session ID to stop. If None, uses current session.
111
+
112
+ Returns:
113
+ CloudBrowserResponse: Updated browser info with stopped status
114
+
115
+ Raises:
116
+ CloudBrowserAuthError: If authentication fails
117
+ CloudBrowserError: If stopping fails
118
+ """
119
+ if session_id is None:
120
+ session_id = self.current_session_id
121
+
122
+ if not session_id:
123
+ raise CloudBrowserError('No session ID provided and no current session available')
124
+
125
+ url = f'{self.api_base_url}/api/v2/browsers/{session_id}'
126
+
127
+ # Try to get API key from environment variable first, then auth config
128
+ api_token = os.getenv('BROWSER_USE_API_KEY')
129
+
130
+ if not api_token:
131
+ # Fallback to auth config file
132
+ try:
133
+ auth_config = CloudAuthConfig.load_from_file()
134
+ api_token = auth_config.api_token
135
+ except Exception:
136
+ pass
137
+
138
+ if not api_token:
139
+ raise CloudBrowserAuthError(
140
+ 'No authentication token found. Please set BROWSER_USE_API_KEY environment variable to authenticate with the cloud service. You can also create an API key at https://cloud.browser-use.com/new-api-key'
141
+ )
142
+
143
+ headers = {'X-Browser-Use-API-Key': api_token, 'Content-Type': 'application/json', **(extra_headers or {})}
144
+
145
+ request_body = {'action': 'stop'}
146
+
147
+ try:
148
+ logger.info(f'🌤️ Stopping cloud browser session: {session_id}')
149
+
150
+ response = await self.client.patch(url, headers=headers, json=request_body)
151
+
152
+ if response.status_code == 401:
153
+ raise CloudBrowserAuthError(
154
+ 'Authentication failed. Please make sure you have set the BROWSER_USE_API_KEY environment variable to authenticate with the cloud service.'
155
+ )
156
+ elif response.status_code == 404:
157
+ # Session already stopped or doesn't exist - treating as error and clearing session
158
+ logger.debug(f'🌤️ Cloud browser session {session_id} not found (already stopped)')
159
+ # Clear current session if it was this one
160
+ if session_id == self.current_session_id:
161
+ self.current_session_id = None
162
+ raise CloudBrowserError(f'Cloud browser session {session_id} not found')
163
+ elif not response.is_success:
164
+ error_msg = f'Failed to stop cloud browser: HTTP {response.status_code}'
165
+ try:
166
+ error_data = response.json()
167
+ if 'detail' in error_data:
168
+ error_msg += f' - {error_data["detail"]}'
169
+ except Exception:
170
+ pass
171
+ raise CloudBrowserError(error_msg)
172
+
173
+ browser_data = response.json()
174
+ browser_response = CloudBrowserResponse(**browser_data)
175
+
176
+ # Clear current session if it was this one
177
+ if session_id == self.current_session_id:
178
+ self.current_session_id = None
179
+
180
+ logger.info(f'🌤️ Cloud browser session stopped: {browser_response.id}')
181
+ logger.debug(f'🌤️ Status: {browser_response.status}')
182
+
183
+ return browser_response
184
+
185
+ except httpx.TimeoutException:
186
+ raise CloudBrowserError('Timeout while stopping cloud browser. Please try again.')
187
+ except httpx.ConnectError:
188
+ raise CloudBrowserError('Failed to connect to cloud browser service. Please check your internet connection.')
189
+ except Exception as e:
190
+ if isinstance(e, (CloudBrowserError, CloudBrowserAuthError)):
191
+ raise
192
+ raise CloudBrowserError(f'Unexpected error stopping cloud browser: {e}')
193
+
194
+ async def close(self):
195
+ """Close the HTTP client and cleanup any active sessions."""
196
+ # Try to stop current session if active
197
+ if self.current_session_id:
198
+ try:
199
+ await self.stop_browser()
200
+ except Exception as e:
201
+ logger.debug(f'Failed to stop cloud browser session during cleanup: {e}')
202
+
203
+ await self.client.aclose()
@@ -0,0 +1,89 @@
1
+ from typing import Literal
2
+ from uuid import UUID
3
+
4
+ from pydantic import BaseModel, ConfigDict, Field
5
+
6
+ ProxyCountryCode = (
7
+ Literal[
8
+ 'us', # United States
9
+ 'uk', # United Kingdom
10
+ 'fr', # France
11
+ 'it', # Italy
12
+ 'jp', # Japan
13
+ 'au', # Australia
14
+ 'de', # Germany
15
+ 'fi', # Finland
16
+ 'ca', # Canada
17
+ 'in', # India
18
+ ]
19
+ | str
20
+ )
21
+
22
+ # Browser session timeout limits (in minutes)
23
+ MAX_FREE_USER_SESSION_TIMEOUT = 15 # Free users limited to 15 minutes
24
+ MAX_PAID_USER_SESSION_TIMEOUT = 240 # Paid users can go up to 4 hours
25
+
26
+
27
+ # Requests
28
+ class CreateBrowserRequest(BaseModel):
29
+ """Request to create a cloud browser instance.
30
+
31
+ Args:
32
+ cloud_profile_id: The ID of the profile to use for the session
33
+ cloud_proxy_country_code: Country code for proxy location
34
+ cloud_timeout: The timeout for the session in minutes
35
+ """
36
+
37
+ model_config = ConfigDict(extra='forbid', populate_by_name=True)
38
+
39
+ profile_id: UUID | str | None = Field(
40
+ default=None,
41
+ alias='cloud_profile_id',
42
+ description='The ID of the profile to use for the session. Can be a UUID or a string of UUID.',
43
+ title='Cloud Profile ID',
44
+ )
45
+
46
+ proxy_country_code: ProxyCountryCode | None = Field(
47
+ default=None,
48
+ alias='cloud_proxy_country_code',
49
+ description='Country code for proxy location.',
50
+ title='Cloud Proxy Country Code',
51
+ )
52
+
53
+ timeout: int | None = Field(
54
+ ge=1,
55
+ le=MAX_PAID_USER_SESSION_TIMEOUT,
56
+ default=None,
57
+ alias='cloud_timeout',
58
+ description=f'The timeout for the session in minutes. Free users are limited to {MAX_FREE_USER_SESSION_TIMEOUT} minutes, paid users can use up to {MAX_PAID_USER_SESSION_TIMEOUT} minutes ({MAX_PAID_USER_SESSION_TIMEOUT // 60} hours).',
59
+ title='Cloud Timeout',
60
+ )
61
+
62
+
63
+ CloudBrowserParams = CreateBrowserRequest # alias for easier readability
64
+
65
+
66
+ # Responses
67
+ class CloudBrowserResponse(BaseModel):
68
+ """Response from cloud browser API."""
69
+
70
+ id: str
71
+ status: str
72
+ liveUrl: str = Field(alias='liveUrl')
73
+ cdpUrl: str = Field(alias='cdpUrl')
74
+ timeoutAt: str = Field(alias='timeoutAt')
75
+ startedAt: str = Field(alias='startedAt')
76
+ finishedAt: str | None = Field(alias='finishedAt', default=None)
77
+
78
+
79
+ # Errors
80
+ class CloudBrowserError(Exception):
81
+ """Exception raised when cloud browser operations fail."""
82
+
83
+ pass
84
+
85
+
86
+ class CloudBrowserAuthError(CloudBrowserError):
87
+ """Exception raised when cloud browser authentication fails."""
88
+
89
+ pass