simplex 1.2.55__tar.gz → 1.2.61__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.55 → simplex-1.2.61}/PKG-INFO +1 -1
- {simplex-1.2.55 → simplex-1.2.61}/setup.py +1 -1
- {simplex-1.2.55 → simplex-1.2.61}/simplex/simplex.py +74 -25
- {simplex-1.2.55 → simplex-1.2.61}/simplex.egg-info/PKG-INFO +1 -1
- {simplex-1.2.55 → simplex-1.2.61}/simplex.egg-info/SOURCES.txt +1 -2
- simplex-1.2.55/tests/test.py +0 -23
- {simplex-1.2.55 → simplex-1.2.61}/LICENSE +0 -0
- {simplex-1.2.55 → simplex-1.2.61}/README.md +0 -0
- {simplex-1.2.55 → simplex-1.2.61}/setup.cfg +0 -0
- {simplex-1.2.55 → simplex-1.2.61}/simplex/__init__.py +0 -0
- {simplex-1.2.55 → simplex-1.2.61}/simplex/cli.py +0 -0
- {simplex-1.2.55 → simplex-1.2.61}/simplex/deploy/__init__.py +0 -0
- {simplex-1.2.55 → simplex-1.2.61}/simplex/deploy/push.py +0 -0
- {simplex-1.2.55 → simplex-1.2.61}/simplex.egg-info/dependency_links.txt +0 -0
- {simplex-1.2.55 → simplex-1.2.61}/simplex.egg-info/entry_points.txt +0 -0
- {simplex-1.2.55 → simplex-1.2.61}/simplex.egg-info/requires.txt +0 -0
- {simplex-1.2.55 → simplex-1.2.61}/simplex.egg-info/top_level.txt +0 -0
|
@@ -4,7 +4,7 @@ from typing import Optional, Union
|
|
|
4
4
|
import os
|
|
5
5
|
import json
|
|
6
6
|
import warnings
|
|
7
|
-
|
|
7
|
+
import time
|
|
8
8
|
# Try to import playwright, but don't fail if it's not available (lite version)
|
|
9
9
|
try:
|
|
10
10
|
from playwright.sync_api import sync_playwright
|
|
@@ -17,8 +17,8 @@ except ImportError:
|
|
|
17
17
|
ImportWarning
|
|
18
18
|
)
|
|
19
19
|
|
|
20
|
+
# BASE_URL = "https://simplex-dev--api-server-fastapi-app.modal.run"
|
|
20
21
|
BASE_URL = "https://api.simplex.sh"
|
|
21
|
-
|
|
22
22
|
class Playwright:
|
|
23
23
|
def __init__(self, simplex_instance):
|
|
24
24
|
self.simplex = simplex_instance
|
|
@@ -61,7 +61,7 @@ class Playwright:
|
|
|
61
61
|
print(response.json())
|
|
62
62
|
raise ValueError(f"It looks like the click action with playwright failed to return a response. Did you set your api_key when creating the Simplex class?")
|
|
63
63
|
|
|
64
|
-
if response.json()
|
|
64
|
+
if "succeeded" in response.json():
|
|
65
65
|
return
|
|
66
66
|
else:
|
|
67
67
|
raise ValueError(f"Failed to click element: {response.json()['error']}")
|
|
@@ -105,12 +105,15 @@ class Simplex:
|
|
|
105
105
|
self.session_id = None
|
|
106
106
|
if 'succeeded' not in response.json():
|
|
107
107
|
raise ValueError(f"It looks like the close_session action failed to return a response. Did you set your api_key when creating the Simplex class?")
|
|
108
|
-
if response.json()
|
|
108
|
+
if "succeeded" in response.json():
|
|
109
109
|
return
|
|
110
110
|
else:
|
|
111
111
|
raise ValueError(f"Failed to close session: {response.json()['error']}")
|
|
112
112
|
|
|
113
|
-
def create_session(self, show_in_console: Optional[bool] = True, proxies: Optional[bool] = True, session_data: Optional[dict | str] = None):
|
|
113
|
+
def create_session(self, show_in_console: Optional[bool] = True, proxies: Optional[bool] = True, workflow_name: Optional[str] = None, session_data: Optional[dict | str] = None):
|
|
114
|
+
if self.session_id:
|
|
115
|
+
raise ValueError("A session is already active. Please close the current session before creating a new one.")
|
|
116
|
+
|
|
114
117
|
if session_data:
|
|
115
118
|
if isinstance(session_data, dict):
|
|
116
119
|
session_data_dict = session_data
|
|
@@ -130,7 +133,7 @@ class Simplex:
|
|
|
130
133
|
headers={
|
|
131
134
|
'x-api-key': self.api_key
|
|
132
135
|
},
|
|
133
|
-
data={'proxies': proxies, 'session_data': json.dumps(session_data_dict)}
|
|
136
|
+
data={'proxies': proxies, 'session_data': json.dumps(session_data_dict), 'workflow_name': workflow_name}
|
|
134
137
|
)
|
|
135
138
|
else:
|
|
136
139
|
response = requests.post(
|
|
@@ -138,7 +141,7 @@ class Simplex:
|
|
|
138
141
|
headers={
|
|
139
142
|
'x-api-key': self.api_key
|
|
140
143
|
},
|
|
141
|
-
data={'proxies': proxies}
|
|
144
|
+
data={'proxies': proxies, "workflow_name": workflow_name}
|
|
142
145
|
)
|
|
143
146
|
# Check for non-200 status code
|
|
144
147
|
if response.status_code != 200:
|
|
@@ -155,7 +158,9 @@ class Simplex:
|
|
|
155
158
|
self.pw = sync_playwright().start()
|
|
156
159
|
self.connect_url = response_json['connect_url']
|
|
157
160
|
# self.pw_browser = self.pw.chromium.connect_over_cdp(response_json['connect_url'])
|
|
158
|
-
|
|
161
|
+
if not "api.simplex.sh" in BASE_URL:
|
|
162
|
+
livestream_url = f"http://localhost:3000/session/{self.session_id}"
|
|
163
|
+
|
|
159
164
|
if show_in_console:
|
|
160
165
|
print(f"Livestream URL: {livestream_url}")
|
|
161
166
|
|
|
@@ -185,12 +190,14 @@ class Simplex:
|
|
|
185
190
|
if 'succeeded' not in response.json():
|
|
186
191
|
raise ValueError(f"It looks like the goto action failed to return a response. Did you set your api_key when creating the Simplex class?")
|
|
187
192
|
|
|
188
|
-
if response.json()
|
|
193
|
+
if "succeeded" in response.json():
|
|
189
194
|
return
|
|
190
195
|
else:
|
|
191
196
|
raise ValueError(f"Failed to goto url: {response.json()['error']}")
|
|
192
197
|
|
|
193
198
|
def click(self, element_description: str, cdp_url: str = None):
|
|
199
|
+
if not element_description or not element_description.strip():
|
|
200
|
+
raise ValueError("element_description cannot be empty")
|
|
194
201
|
if not cdp_url and not self.session_id:
|
|
195
202
|
raise ValueError(f"Must call create_session before calling action click with element_description='{element_description}'")
|
|
196
203
|
|
|
@@ -216,6 +223,8 @@ class Simplex:
|
|
|
216
223
|
raise ValueError(f"Failed to click element: {response.json()['error']}")
|
|
217
224
|
|
|
218
225
|
def type(self, text: str, cdp_url: str = None):
|
|
226
|
+
if not text or not text.strip():
|
|
227
|
+
raise ValueError("text cannot be empty")
|
|
219
228
|
if not cdp_url and not self.session_id:
|
|
220
229
|
raise ValueError(f"Must call create_session before calling action type with text='{text}'")
|
|
221
230
|
|
|
@@ -233,11 +242,38 @@ class Simplex:
|
|
|
233
242
|
},
|
|
234
243
|
data=data
|
|
235
244
|
)
|
|
236
|
-
if response.json()
|
|
245
|
+
if "succeeded" in response.json():
|
|
237
246
|
return
|
|
238
247
|
else:
|
|
248
|
+
print(response.json())
|
|
239
249
|
raise ValueError(f"Failed to type text: {response.json()['error']}")
|
|
250
|
+
|
|
240
251
|
|
|
252
|
+
def reload(self, cdp_url: str = None):
|
|
253
|
+
if not cdp_url and not self.session_id:
|
|
254
|
+
raise ValueError("Must call create_session before calling action reload")
|
|
255
|
+
|
|
256
|
+
data = {}
|
|
257
|
+
|
|
258
|
+
if cdp_url:
|
|
259
|
+
data['cdp_url'] = cdp_url
|
|
260
|
+
else:
|
|
261
|
+
data['session_id'] = self.session_id
|
|
262
|
+
|
|
263
|
+
response = requests.post(
|
|
264
|
+
f"{BASE_URL}/reload",
|
|
265
|
+
headers={
|
|
266
|
+
'x-api-key': self.api_key
|
|
267
|
+
},
|
|
268
|
+
data=data
|
|
269
|
+
)
|
|
270
|
+
if 'succeeded' not in response.json():
|
|
271
|
+
raise ValueError(f"It looks like the reload action failed to return a response. Did you set your api_key when creating the Simplex class?")
|
|
272
|
+
if "succeeded" in response.json():
|
|
273
|
+
return
|
|
274
|
+
else:
|
|
275
|
+
raise ValueError(f"Failed to reload: {response.json()['error']}")
|
|
276
|
+
|
|
241
277
|
def press_enter(self, cdp_url: str = None):
|
|
242
278
|
if not cdp_url and not self.session_id:
|
|
243
279
|
raise ValueError("Must call create_session before calling action press_enter")
|
|
@@ -258,7 +294,7 @@ class Simplex:
|
|
|
258
294
|
)
|
|
259
295
|
if 'succeeded' not in response.json():
|
|
260
296
|
raise ValueError(f"It looks like the press_enter action failed to return a response. Did you set your api_key when creating the Simplex class?")
|
|
261
|
-
if response.json()
|
|
297
|
+
if "succeeded" in response.json():
|
|
262
298
|
return
|
|
263
299
|
else:
|
|
264
300
|
raise ValueError(f"Failed to press enter: {response.json()['error']}")
|
|
@@ -283,7 +319,7 @@ class Simplex:
|
|
|
283
319
|
)
|
|
284
320
|
if 'succeeded' not in response.json():
|
|
285
321
|
raise ValueError(f"It looks like the press_tab action failed to return a response. Did you set your api_key when creating the Simplex class?")
|
|
286
|
-
if response.json()
|
|
322
|
+
if "succeeded" in response.json():
|
|
287
323
|
return
|
|
288
324
|
else:
|
|
289
325
|
raise ValueError(f"Failed to press tab: {response.json()['error']}")
|
|
@@ -308,12 +344,14 @@ class Simplex:
|
|
|
308
344
|
)
|
|
309
345
|
if 'succeeded' not in response.json():
|
|
310
346
|
raise ValueError(f"It looks like the delete_text action failed to return a response. Did you set your api_key when creating the Simplex class?")
|
|
311
|
-
if response.json()
|
|
347
|
+
if "succeeded" in response.json():
|
|
312
348
|
return
|
|
313
349
|
else:
|
|
314
350
|
raise ValueError(f"Failed to delete text: {response.json()['error']}")
|
|
315
351
|
|
|
316
352
|
def extract_bbox(self, element_description: str, cdp_url: str = None):
|
|
353
|
+
if not element_description or not element_description.strip():
|
|
354
|
+
raise ValueError("element_description cannot be empty")
|
|
317
355
|
if not cdp_url and not self.session_id:
|
|
318
356
|
raise ValueError(f"Must call create_session before calling action extract_bbox with element_description='{element_description}'")
|
|
319
357
|
|
|
@@ -333,12 +371,14 @@ class Simplex:
|
|
|
333
371
|
)
|
|
334
372
|
if 'succeeded' not in response.json():
|
|
335
373
|
raise ValueError(f"It looks like the extract_bbox action failed to return a response. Did you set your api_key when creating the Simplex class?")
|
|
336
|
-
if response.json()
|
|
374
|
+
if "succeeded" in response.json():
|
|
337
375
|
return response.json()["bbox"]
|
|
338
376
|
else:
|
|
339
377
|
raise ValueError(f"Failed to extract bbox: {response.json()['error']}")
|
|
340
378
|
|
|
341
379
|
def extract_text(self, element_description: str, cdp_url: str = None):
|
|
380
|
+
if not element_description or not element_description.strip():
|
|
381
|
+
raise ValueError("element_description cannot be empty")
|
|
342
382
|
if not cdp_url and not self.session_id:
|
|
343
383
|
raise ValueError(f"Must call create_session before calling action extract_text with element_description='{element_description}'")
|
|
344
384
|
|
|
@@ -356,14 +396,17 @@ class Simplex:
|
|
|
356
396
|
},
|
|
357
397
|
data=data
|
|
358
398
|
)
|
|
359
|
-
|
|
399
|
+
response_json = response.json()
|
|
400
|
+
if 'succeeded' not in response_json:
|
|
360
401
|
raise ValueError(f"It looks like the extract_text action failed to return a response. Did you set your api_key when creating the Simplex class?")
|
|
361
|
-
if
|
|
362
|
-
return
|
|
402
|
+
if "succeeded" in response_json:
|
|
403
|
+
return response_json["text"]
|
|
363
404
|
else:
|
|
364
|
-
raise ValueError(f"Failed to extract text: {
|
|
405
|
+
raise ValueError(f"Failed to extract text: {response_json['error']}")
|
|
365
406
|
|
|
366
407
|
def extract_image(self, element_description: str, cdp_url: str = None):
|
|
408
|
+
if not element_description or not element_description.strip():
|
|
409
|
+
raise ValueError("element_description cannot be empty")
|
|
367
410
|
if not cdp_url and not self.session_id:
|
|
368
411
|
raise ValueError(f"Must call create_session before calling action extract_image with element_description='{element_description}'")
|
|
369
412
|
|
|
@@ -383,7 +426,7 @@ class Simplex:
|
|
|
383
426
|
)
|
|
384
427
|
if 'succeeded' not in response.json():
|
|
385
428
|
raise ValueError(f"It looks like the extract_image action failed to return a response. Did you set your api_key when creating the Simplex class?")
|
|
386
|
-
if response.json()
|
|
429
|
+
if "succeeded" in response.json():
|
|
387
430
|
return response.json()["image"]
|
|
388
431
|
else:
|
|
389
432
|
raise ValueError(f"Failed to extract image: {response.json()['error']}")
|
|
@@ -408,7 +451,7 @@ class Simplex:
|
|
|
408
451
|
)
|
|
409
452
|
if 'succeeded' not in response.json():
|
|
410
453
|
raise ValueError(f"It looks like the scroll action failed to return a response. Did you set your api_key when creating the Simplex class?")
|
|
411
|
-
if response.json()
|
|
454
|
+
if "succeeded" in response.json():
|
|
412
455
|
return
|
|
413
456
|
else:
|
|
414
457
|
raise ValueError(f"Failed to scroll: {response.json()['error']}")
|
|
@@ -433,7 +476,7 @@ class Simplex:
|
|
|
433
476
|
)
|
|
434
477
|
if 'succeeded' not in response.json():
|
|
435
478
|
raise ValueError(f"It looks like the wait action failed to return a response. Did you set your api_key when creating the Simplex class?")
|
|
436
|
-
if response.json()
|
|
479
|
+
if "succeeded" in response.json():
|
|
437
480
|
return
|
|
438
481
|
else:
|
|
439
482
|
raise ValueError(f"Failed to wait: {response.json()['error']}")
|
|
@@ -550,7 +593,7 @@ class Simplex:
|
|
|
550
593
|
)
|
|
551
594
|
if 'succeeded' not in response.json():
|
|
552
595
|
raise ValueError(f"It looks like the restore_login_session action failed to return a response. Did you set your api_key when creating the Simplex class?")
|
|
553
|
-
if response.json()
|
|
596
|
+
if "succeeded" in response.json():
|
|
554
597
|
return
|
|
555
598
|
else:
|
|
556
599
|
raise ValueError(f"Failed to restore login session: {response.json()['error']}")
|
|
@@ -561,6 +604,8 @@ class Simplex:
|
|
|
561
604
|
element_description: Description of the element to click and upload to
|
|
562
605
|
file_path_or_callable: Either a path to the file to be uploaded or a callable that returns a file-like object in 'rb' mode
|
|
563
606
|
"""
|
|
607
|
+
if not element_description or not element_description.strip():
|
|
608
|
+
raise ValueError("element_description cannot be empty")
|
|
564
609
|
if not self.session_id:
|
|
565
610
|
raise ValueError(f"Must call create_session before calling action click_and_upload with element_description='{element_description}'")
|
|
566
611
|
|
|
@@ -592,12 +637,14 @@ class Simplex:
|
|
|
592
637
|
)
|
|
593
638
|
if 'succeeded' not in response.json():
|
|
594
639
|
raise ValueError(f"It looks like the click_and_upload action failed to return a response. Did you set your api_key when creating the Simplex class?")
|
|
595
|
-
if response.json()
|
|
640
|
+
if "succeeded" in response.json():
|
|
596
641
|
return
|
|
597
642
|
else:
|
|
598
643
|
raise ValueError(f"Failed to click and upload: {response.json()['error']}")
|
|
599
644
|
|
|
600
645
|
def click_and_download(self, element_description: str):
|
|
646
|
+
if not element_description or not element_description.strip():
|
|
647
|
+
raise ValueError("element_description cannot be empty")
|
|
601
648
|
if not self.session_id:
|
|
602
649
|
raise ValueError(f"Must call create_session before calling action click_and_download with element_description='{element_description}'")
|
|
603
650
|
|
|
@@ -616,12 +663,14 @@ class Simplex:
|
|
|
616
663
|
)
|
|
617
664
|
if 'succeeded' not in response.json():
|
|
618
665
|
raise ValueError(f"It looks like the click_and_download action failed to return a response. Did you set your api_key when creating the Simplex class?")
|
|
619
|
-
if response.json()
|
|
666
|
+
if "succeeded" in response.json():
|
|
620
667
|
return response.json()["b64"], response.json()["filename"]
|
|
621
668
|
else:
|
|
622
669
|
raise ValueError(f"Failed to click and download: {response.json()['error']}")
|
|
623
670
|
|
|
624
671
|
def exists(self, element_description: str, cdp_url: str = None):
|
|
672
|
+
if not element_description or not element_description.strip():
|
|
673
|
+
raise ValueError("element_description cannot be empty")
|
|
625
674
|
if not cdp_url and not self.session_id:
|
|
626
675
|
raise ValueError(f"Must call create_session before calling action exists with element_description='{element_description}'")
|
|
627
676
|
|
|
@@ -642,7 +691,7 @@ class Simplex:
|
|
|
642
691
|
if 'succeeded' not in response.json():
|
|
643
692
|
raise ValueError(f"It looks like the exists action failed to return a response. Did you set your api_key when creating the Simplex class?")
|
|
644
693
|
response_json = response.json()
|
|
645
|
-
if response_json
|
|
694
|
+
if "succeeded" in response_json:
|
|
646
695
|
return response_json['exists'], response_json['reasoning']
|
|
647
696
|
else:
|
|
648
697
|
raise ValueError(f"Failed to check if element exists: {response_json['error']}")
|
simplex-1.2.55/tests/test.py
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
from simplex import Simplex
|
|
2
|
-
import os
|
|
3
|
-
from dotenv import load_dotenv
|
|
4
|
-
import time
|
|
5
|
-
from playwright.async_api import Page
|
|
6
|
-
|
|
7
|
-
import asyncio
|
|
8
|
-
import os
|
|
9
|
-
import dotenv
|
|
10
|
-
|
|
11
|
-
dotenv.load_dotenv()
|
|
12
|
-
|
|
13
|
-
async def main():
|
|
14
|
-
simplex = Simplex(os.getenv("SIMPLEX_API_KEY"))
|
|
15
|
-
|
|
16
|
-
simplex.create_session()
|
|
17
|
-
simplex.goto("https://gmail.com")
|
|
18
|
-
simplex.type("test@gmail.com")
|
|
19
|
-
simplex.press_enter()
|
|
20
|
-
simplex.wait(1000000)
|
|
21
|
-
if __name__ == "__main__":
|
|
22
|
-
asyncio.run(main())
|
|
23
|
-
|
|
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
|
|
File without changes
|