simplex 1.2.1__tar.gz → 1.2.2__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.
Potentially problematic release.
This version of simplex might be problematic. Click here for more details.
- {simplex-1.2.1 → simplex-1.2.2}/PKG-INFO +2 -11
- {simplex-1.2.1 → simplex-1.2.2}/setup.py +1 -1
- {simplex-1.2.1 → simplex-1.2.2}/simplex/simplex.py +20 -8
- {simplex-1.2.1 → simplex-1.2.2}/simplex.egg-info/PKG-INFO +2 -11
- {simplex-1.2.1 → simplex-1.2.2}/simplex.egg-info/SOURCES.txt +0 -1
- {simplex-1.2.1 → simplex-1.2.2}/tests/test_local.py +35 -9
- simplex-1.2.1/simplex/constants.py +0 -1
- {simplex-1.2.1 → simplex-1.2.2}/LICENSE +0 -0
- {simplex-1.2.1 → simplex-1.2.2}/README.md +0 -0
- {simplex-1.2.1 → simplex-1.2.2}/pyproject.toml +0 -0
- {simplex-1.2.1 → simplex-1.2.2}/setup.cfg +0 -0
- {simplex-1.2.1 → simplex-1.2.2}/simplex/__init__.py +0 -0
- {simplex-1.2.1 → simplex-1.2.2}/simplex/utils.py +0 -0
- {simplex-1.2.1 → simplex-1.2.2}/simplex.egg-info/dependency_links.txt +0 -0
- {simplex-1.2.1 → simplex-1.2.2}/simplex.egg-info/entry_points.txt +0 -0
- {simplex-1.2.1 → simplex-1.2.2}/simplex.egg-info/requires.txt +0 -0
- {simplex-1.2.1 → simplex-1.2.2}/simplex.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
2
|
Name: simplex
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.2
|
|
4
4
|
Summary: Official Python SDK for Simplex API
|
|
5
5
|
Home-page: https://github.com/shreyka/simplex-python
|
|
6
6
|
Author: Simplex Labs, Inc.
|
|
@@ -21,15 +21,6 @@ Requires-Dist: rich>=13.0.0
|
|
|
21
21
|
Requires-Dist: prompt_toolkit>=3.0.0
|
|
22
22
|
Requires-Dist: playwright>=1.0.0
|
|
23
23
|
Requires-Dist: Pillow>=9.0.0
|
|
24
|
-
Dynamic: author
|
|
25
|
-
Dynamic: author-email
|
|
26
|
-
Dynamic: classifier
|
|
27
|
-
Dynamic: description
|
|
28
|
-
Dynamic: description-content-type
|
|
29
|
-
Dynamic: home-page
|
|
30
|
-
Dynamic: requires-dist
|
|
31
|
-
Dynamic: requires-python
|
|
32
|
-
Dynamic: summary
|
|
33
24
|
|
|
34
25
|
# Simplex AI Python SDK
|
|
35
26
|
|
|
@@ -26,10 +26,9 @@ class Simplex:
|
|
|
26
26
|
self.driver = self.browser.new_page()
|
|
27
27
|
else:
|
|
28
28
|
self.playwright = None
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
self.driver = self.browser.new_page()
|
|
29
|
+
self.driver = self.browser.contexts[0].pages[0]
|
|
30
|
+
self.driver.set_default_navigation_timeout(0)
|
|
31
|
+
self.driver.set_default_timeout(0)
|
|
33
32
|
|
|
34
33
|
def find_element(self, element_description: str, state: Image.Image | None = None, annotate: bool = True) -> List[int]:
|
|
35
34
|
"""
|
|
@@ -42,6 +41,7 @@ class Simplex:
|
|
|
42
41
|
Returns:
|
|
43
42
|
bounding_box (tuple): [x1, y1, x2, y2] bounding box of the found element
|
|
44
43
|
"""
|
|
44
|
+
print(f"Finding element \"{element_description}\"...")
|
|
45
45
|
if state is None:
|
|
46
46
|
state = self.take_stable_screenshot()
|
|
47
47
|
|
|
@@ -58,7 +58,7 @@ class Simplex:
|
|
|
58
58
|
'element_description': (None, element_description),
|
|
59
59
|
'api_key': (None, self.api_key)
|
|
60
60
|
}
|
|
61
|
-
|
|
61
|
+
print("Sending screenshot to server...")
|
|
62
62
|
# Make the request
|
|
63
63
|
response = requests.post(
|
|
64
64
|
endpoint,
|
|
@@ -122,6 +122,7 @@ class Simplex:
|
|
|
122
122
|
}
|
|
123
123
|
""", bbox)
|
|
124
124
|
self.driver.wait_for_selector('#simplex-bbox-overlay')
|
|
125
|
+
print(f"Found element \"{element_description}\" at pixel coordinates {bbox}.")
|
|
125
126
|
return bbox
|
|
126
127
|
else:
|
|
127
128
|
print("Error:", response.text)
|
|
@@ -182,6 +183,8 @@ class Simplex:
|
|
|
182
183
|
"""
|
|
183
184
|
if new_tab:
|
|
184
185
|
self.driver = self.browser.new_page()
|
|
186
|
+
self.driver.wait_for_load_state()
|
|
187
|
+
print(f"Navigating to URL {url}...")
|
|
185
188
|
self.driver.goto(url)
|
|
186
189
|
|
|
187
190
|
def execute_action(self, action: List[List[str]], state: Image.Image | None = None, annotate: bool = True) -> None:
|
|
@@ -191,10 +194,8 @@ class Simplex:
|
|
|
191
194
|
Args:
|
|
192
195
|
action (List[List[str]]): List of actions to perform
|
|
193
196
|
"""
|
|
197
|
+
print(f"Executing action {action}...")
|
|
194
198
|
action_type, description = action
|
|
195
|
-
if state is None:
|
|
196
|
-
state = self.take_stable_screenshot()
|
|
197
|
-
|
|
198
199
|
try:
|
|
199
200
|
if action_type == "CLICK":
|
|
200
201
|
bbox = self.find_element(description, state, annotate=annotate)
|
|
@@ -207,6 +208,7 @@ class Simplex:
|
|
|
207
208
|
self.driver.mouse.move(center_x, center_y)
|
|
208
209
|
|
|
209
210
|
elif action_type == "TYPE":
|
|
211
|
+
print(f"Typing \"{description}\"...")
|
|
210
212
|
self.driver.keyboard.type(description)
|
|
211
213
|
|
|
212
214
|
elif action_type == "ENTER":
|
|
@@ -217,6 +219,7 @@ class Simplex:
|
|
|
217
219
|
|
|
218
220
|
elif action_type == "WAIT":
|
|
219
221
|
self.driver.wait_for_timeout(int(description))
|
|
222
|
+
|
|
220
223
|
|
|
221
224
|
except Exception as e:
|
|
222
225
|
print(f"Error executing action: {e}")
|
|
@@ -230,6 +233,14 @@ class Simplex:
|
|
|
230
233
|
actions = self.step_to_action(step_description, state)
|
|
231
234
|
for action in actions:
|
|
232
235
|
self.execute_action(action, annotate=annotate)
|
|
236
|
+
|
|
237
|
+
def extract(self, step_description: str, annotate: bool = True) -> None:
|
|
238
|
+
"""
|
|
239
|
+
Extract an element from the page
|
|
240
|
+
"""
|
|
241
|
+
state = self.take_stable_screenshot()
|
|
242
|
+
|
|
243
|
+
# self.execute_action(action, annotate=annotate)
|
|
233
244
|
|
|
234
245
|
def take_stable_screenshot(self) -> Image.Image:
|
|
235
246
|
"""
|
|
@@ -238,6 +249,7 @@ class Simplex:
|
|
|
238
249
|
Returns:
|
|
239
250
|
PIL.Image.Image: Screenshot of the current page
|
|
240
251
|
"""
|
|
252
|
+
print("Taking screenshot of the page...")
|
|
241
253
|
self.driver.wait_for_load_state('networkidle')
|
|
242
254
|
return screenshot_to_image(self.driver.screenshot())
|
|
243
255
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
2
|
Name: simplex
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.2
|
|
4
4
|
Summary: Official Python SDK for Simplex API
|
|
5
5
|
Home-page: https://github.com/shreyka/simplex-python
|
|
6
6
|
Author: Simplex Labs, Inc.
|
|
@@ -21,15 +21,6 @@ Requires-Dist: rich>=13.0.0
|
|
|
21
21
|
Requires-Dist: prompt_toolkit>=3.0.0
|
|
22
22
|
Requires-Dist: playwright>=1.0.0
|
|
23
23
|
Requires-Dist: Pillow>=9.0.0
|
|
24
|
-
Dynamic: author
|
|
25
|
-
Dynamic: author-email
|
|
26
|
-
Dynamic: classifier
|
|
27
|
-
Dynamic: description
|
|
28
|
-
Dynamic: description-content-type
|
|
29
|
-
Dynamic: home-page
|
|
30
|
-
Dynamic: requires-dist
|
|
31
|
-
Dynamic: requires-python
|
|
32
|
-
Dynamic: summary
|
|
33
24
|
|
|
34
25
|
# Simplex AI Python SDK
|
|
35
26
|
|
|
@@ -9,6 +9,7 @@ from playwright.sync_api import sync_playwright
|
|
|
9
9
|
from PIL import Image
|
|
10
10
|
import time
|
|
11
11
|
import os
|
|
12
|
+
from browserbase import Browserbase
|
|
12
13
|
from hyperbrowser import Hyperbrowser
|
|
13
14
|
from hyperbrowser.models.session import CreateSessionParams
|
|
14
15
|
|
|
@@ -155,12 +156,20 @@ def test_find_element_2():
|
|
|
155
156
|
simplex = Simplex(api_key=os.getenv("SIMPLEX_API_KEY"))
|
|
156
157
|
simplex.goto("https://www.cgtrader.com/")
|
|
157
158
|
simplex.find_element("search bar")
|
|
158
|
-
|
|
159
|
+
import requests
|
|
159
160
|
def test_hyperbrowser_integration():
|
|
160
161
|
"""Test Simplex integration with Hyperbrowser"""
|
|
162
|
+
import time
|
|
163
|
+
start_time = time.time()
|
|
164
|
+
|
|
165
|
+
bb = Browserbase(api_key=os.getenv("BROWSERBASE_API_KEY"))
|
|
166
|
+
session_start = time.time()
|
|
167
|
+
session = bb.sessions.create(project_id=os.getenv("BROWSERBASE_PROJECT_ID"))
|
|
168
|
+
print(session.id)
|
|
169
|
+
print(f"Session creation took {time.time() - session_start:.2f}s")
|
|
161
170
|
|
|
162
171
|
# Initialize Hyperbrowser client
|
|
163
|
-
client = Hyperbrowser(api_key=os.getenv("HYPERBROWSER_API_KEY"))
|
|
172
|
+
# client = Hyperbrowser(api_key=os.getenv("HYPERBROWSER_API_KEY"))
|
|
164
173
|
|
|
165
174
|
# Create session params with CAPTCHA solving enabled
|
|
166
175
|
session_params = CreateSessionParams(
|
|
@@ -169,28 +178,45 @@ def test_hyperbrowser_integration():
|
|
|
169
178
|
)
|
|
170
179
|
|
|
171
180
|
# Create a new session with params
|
|
172
|
-
session = client.sessions.create(session_params)
|
|
173
|
-
ws_endpoint = session.
|
|
181
|
+
# session = client.sessions.create(session_params)
|
|
182
|
+
ws_endpoint = session.connect_url
|
|
174
183
|
|
|
175
184
|
try:
|
|
176
185
|
with sync_playwright() as p:
|
|
177
186
|
# Connect browser to Hyperbrowser session
|
|
187
|
+
browser_start = time.time()
|
|
178
188
|
browser = p.chromium.connect_over_cdp(ws_endpoint)
|
|
179
|
-
|
|
189
|
+
print(f"Browser connection took {time.time() - browser_start:.2f}s")
|
|
190
|
+
url = f"https://api.browserbase.com/v1/sessions/{session.id}/debug"
|
|
191
|
+
headers = {"X-BB-API-Key": os.getenv("BROWSERBASE_API_KEY")}
|
|
192
|
+
response = requests.get(url, headers=headers)
|
|
193
|
+
print(response.text)
|
|
194
|
+
print(response.json()["pages"][0]["debuggerUrl"])
|
|
195
|
+
|
|
180
196
|
# Initialize Simplex with the Hyperbrowser-connected page
|
|
181
197
|
simplex = Simplex(api_key=os.getenv("SIMPLEX_API_KEY"), browser=browser)
|
|
182
198
|
|
|
183
199
|
# Test basic functionality
|
|
200
|
+
nav_start = time.time()
|
|
184
201
|
simplex.goto("https://www.turbosquid.com/")
|
|
185
|
-
|
|
202
|
+
print(f"Navigation took {time.time() - nav_start:.2f}s")
|
|
203
|
+
|
|
204
|
+
# search_start = time.time()
|
|
205
|
+
# simplex.do("search for iphone")
|
|
206
|
+
# print(f"Search action took {time.time() - search_start:.2f}s")
|
|
186
207
|
|
|
187
208
|
# Verify the search worked by finding the search results
|
|
188
|
-
|
|
209
|
+
find_start = time.time()
|
|
210
|
+
bbox = simplex.find_element("search results", annotate=True)
|
|
211
|
+
print(f"Finding results took {time.time() - find_start:.2f}s")
|
|
189
212
|
assert bbox is not None, "Search results not found"
|
|
190
213
|
|
|
191
214
|
finally:
|
|
192
215
|
# Always stop the Hyperbrowser session
|
|
193
|
-
client.sessions.stop(session.id)
|
|
216
|
+
# client.sessions.stop(session.id)
|
|
217
|
+
browser.close()
|
|
218
|
+
print(f"Total test time: {time.time() - start_time:.2f}s")
|
|
219
|
+
|
|
194
220
|
|
|
195
221
|
|
|
196
222
|
def execute_action_test():
|
|
@@ -217,6 +243,6 @@ def execute_action_test():
|
|
|
217
243
|
playwright.stop()
|
|
218
244
|
|
|
219
245
|
if __name__ == "__main__":
|
|
220
|
-
|
|
246
|
+
test_hyperbrowser_integration()
|
|
221
247
|
|
|
222
248
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
BASE_URL = "https://u3mvtbirxf.us-east-1.awsapprunner.com"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|