simplex 1.2.0__py3-none-any.whl → 1.2.2__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.

Potentially problematic release.


This version of simplex might be problematic. Click here for more details.

simplex/simplex.py CHANGED
@@ -3,7 +3,6 @@ from PIL import Image
3
3
  import requests
4
4
  from typing import List
5
5
  import io
6
- import time
7
6
 
8
7
  from .utils import center_bbox, screenshot_to_image
9
8
 
@@ -24,10 +23,12 @@ class Simplex:
24
23
  if browser is None:
25
24
  self.playwright = sync_playwright().start()
26
25
  self.browser = self.playwright.chromium.launch(headless=True)
26
+ self.driver = self.browser.new_page()
27
27
  else:
28
28
  self.playwright = None
29
-
30
- self.driver = self.browser.new_page(viewport={"width": 1280, "height": 720})
29
+ self.driver = self.browser.contexts[0].pages[0]
30
+ self.driver.set_default_navigation_timeout(0)
31
+ self.driver.set_default_timeout(0)
31
32
 
32
33
  def find_element(self, element_description: str, state: Image.Image | None = None, annotate: bool = True) -> List[int]:
33
34
  """
@@ -40,6 +41,7 @@ class Simplex:
40
41
  Returns:
41
42
  bounding_box (tuple): [x1, y1, x2, y2] bounding box of the found element
42
43
  """
44
+ print(f"Finding element \"{element_description}\"...")
43
45
  if state is None:
44
46
  state = self.take_stable_screenshot()
45
47
 
@@ -56,6 +58,7 @@ class Simplex:
56
58
  'element_description': (None, element_description),
57
59
  'api_key': (None, self.api_key)
58
60
  }
61
+ print("Sending screenshot to server...")
59
62
  # Make the request
60
63
  response = requests.post(
61
64
  endpoint,
@@ -83,20 +86,43 @@ class Simplex:
83
86
  // Create new overlay
84
87
  const overlay = document.createElement('div');
85
88
  overlay.id = 'simplex-bbox-overlay';
86
- overlay.style.position = 'absolute';
87
- overlay.style.border = '2px solid red';
89
+ overlay.style.position = 'fixed';
90
+ overlay.style.border = '2px dashed rgba(74, 144, 226, 1)';
91
+ overlay.style.background = 'rgba(74, 144, 226, 0.1)';
92
+ overlay.style.animation = 'marching-ants 0.5s linear infinite';
88
93
  overlay.style.left = bbox[0] + 'px';
89
94
  overlay.style.top = bbox[1] + 'px';
90
95
  overlay.style.width = (bbox[2] - bbox[0]) + 'px';
91
96
  overlay.style.height = (bbox[3] - bbox[1]) + 'px';
92
97
  overlay.style.pointerEvents = 'none';
93
98
  overlay.style.zIndex = '10000';
99
+ overlay.style.margin = '0';
100
+ overlay.style.padding = '0';
101
+
102
+ // Add marching ants animation keyframes
103
+ if (!document.querySelector('#marching-ants-keyframes')) {
104
+ const style = document.createElement('style');
105
+ style.id = 'marching-ants-keyframes';
106
+ style.textContent = `
107
+ @keyframes marching-ants {
108
+ 0% { border-style: dashed; }
109
+ 50% { border-style: solid; }
110
+ 100% { border-style: dashed; }
111
+ }
112
+ `;
113
+ document.head.appendChild(style);
114
+ }
94
115
 
95
116
  document.body.appendChild(overlay);
117
+
118
+ // Remove overlay after 3 second
119
+ setTimeout(() => {
120
+ overlay.remove();
121
+ }, 2000);
96
122
  }
97
123
  """, bbox)
98
124
  self.driver.wait_for_selector('#simplex-bbox-overlay')
99
- time.sleep(5)
125
+ print(f"Found element \"{element_description}\" at pixel coordinates {bbox}.")
100
126
  return bbox
101
127
  else:
102
128
  print("Error:", response.text)
@@ -147,10 +173,18 @@ class Simplex:
147
173
  print(response.text)
148
174
  return []
149
175
 
150
- def goto(self, url: str) -> None:
176
+ def goto(self, url: str, new_tab: bool = False) -> None:
151
177
  """
152
178
  Navigate to a URL
179
+
180
+ Args:
181
+ url (str): URL to navigate to
182
+ new_tab (bool): Whether to open a new tab or use the current tab
153
183
  """
184
+ if new_tab:
185
+ self.driver = self.browser.new_page()
186
+ self.driver.wait_for_load_state()
187
+ print(f"Navigating to URL {url}...")
154
188
  self.driver.goto(url)
155
189
 
156
190
  def execute_action(self, action: List[List[str]], state: Image.Image | None = None, annotate: bool = True) -> None:
@@ -160,10 +194,8 @@ class Simplex:
160
194
  Args:
161
195
  action (List[List[str]]): List of actions to perform
162
196
  """
197
+ print(f"Executing action {action}...")
163
198
  action_type, description = action
164
- if state is None:
165
- state = self.take_stable_screenshot()
166
-
167
199
  try:
168
200
  if action_type == "CLICK":
169
201
  bbox = self.find_element(description, state, annotate=annotate)
@@ -176,13 +208,18 @@ class Simplex:
176
208
  self.driver.mouse.move(center_x, center_y)
177
209
 
178
210
  elif action_type == "TYPE":
211
+ print(f"Typing \"{description}\"...")
179
212
  self.driver.keyboard.type(description)
180
213
 
214
+ elif action_type == "ENTER":
215
+ self.driver.keyboard.press("Enter")
216
+
181
217
  elif action_type == "SCROLL":
182
218
  self.driver.mouse.wheel(0, int(description))
183
219
 
184
220
  elif action_type == "WAIT":
185
221
  self.driver.wait_for_timeout(int(description))
222
+
186
223
 
187
224
  except Exception as e:
188
225
  print(f"Error executing action: {e}")
@@ -196,6 +233,14 @@ class Simplex:
196
233
  actions = self.step_to_action(step_description, state)
197
234
  for action in actions:
198
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)
199
244
 
200
245
  def take_stable_screenshot(self) -> Image.Image:
201
246
  """
@@ -204,6 +249,7 @@ class Simplex:
204
249
  Returns:
205
250
  PIL.Image.Image: Screenshot of the current page
206
251
  """
252
+ print("Taking screenshot of the page...")
207
253
  self.driver.wait_for_load_state('networkidle')
208
254
  return screenshot_to_image(self.driver.screenshot())
209
255
 
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.1
2
2
  Name: simplex
3
- Version: 1.2.0
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.
@@ -18,18 +18,9 @@ Requires-Dist: python-dotenv>=0.19.0
18
18
  Requires-Dist: tiktoken>=0.5.0
19
19
  Requires-Dist: click>=8.0.0
20
20
  Requires-Dist: rich>=13.0.0
21
- Requires-Dist: prompt_toolkit>=3.0.0
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
 
@@ -0,0 +1,9 @@
1
+ simplex/__init__.py,sha256=1mbM4XUk0FNW161WOkM4ayC1s_QSsaBEls6PZ0iBScY,74
2
+ simplex/simplex.py,sha256=___oQuVrlTYR3BJDxb0INKHQO74aSqeNZyCkj8NzdYQ,9856
3
+ simplex/utils.py,sha256=UrD4Ena3yk0POmxxyiqMszzPbTscTCJpMP4xZFDAuOc,339
4
+ simplex-1.2.2.dist-info/LICENSE,sha256=Xh0SJjYZfNI71pCNMB40aKlBLLuOB0blx5xkTtufFNQ,1075
5
+ simplex-1.2.2.dist-info/METADATA,sha256=cRRdYjOEPq-fkUDokBgx8Sas49liFjB6BLo4Ypv1dG0,917
6
+ simplex-1.2.2.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
7
+ simplex-1.2.2.dist-info/entry_points.txt,sha256=3veL2w3c5vxb3dm8I_M8Fs-370n1ZnvD8uu1nSsL7z8,45
8
+ simplex-1.2.2.dist-info/top_level.txt,sha256=cbMH1bYpN0A3gP-ecibPRHasHoqB-01T_2BUFS8p0CE,8
9
+ simplex-1.2.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.0)
2
+ Generator: setuptools (75.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
simplex/constants.py DELETED
@@ -1 +0,0 @@
1
- BASE_URL = "https://u3mvtbirxf.us-east-1.awsapprunner.com"
@@ -1,10 +0,0 @@
1
- simplex/__init__.py,sha256=1mbM4XUk0FNW161WOkM4ayC1s_QSsaBEls6PZ0iBScY,74
2
- simplex/constants.py,sha256=nIXF2oVNNNknXweXAlmE-KBM9QjJtYw9osXVYjvloN0,59
3
- simplex/simplex.py,sha256=ZdsdhapVsj9CfsjXO2_etKQOK7KYP1qSREf9A4xQ4fc,7575
4
- simplex/utils.py,sha256=UrD4Ena3yk0POmxxyiqMszzPbTscTCJpMP4xZFDAuOc,339
5
- simplex-1.2.0.dist-info/LICENSE,sha256=Xh0SJjYZfNI71pCNMB40aKlBLLuOB0blx5xkTtufFNQ,1075
6
- simplex-1.2.0.dist-info/METADATA,sha256=ZvRVsPpmWNnb1UAb5TED4Rs3S512lyKDXzapjQ6OyyI,1114
7
- simplex-1.2.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
8
- simplex-1.2.0.dist-info/entry_points.txt,sha256=3veL2w3c5vxb3dm8I_M8Fs-370n1ZnvD8uu1nSsL7z8,45
9
- simplex-1.2.0.dist-info/top_level.txt,sha256=cbMH1bYpN0A3gP-ecibPRHasHoqB-01T_2BUFS8p0CE,8
10
- simplex-1.2.0.dist-info/RECORD,,