simplex 1.2.63__py3-none-any.whl → 1.2.64__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 +120 -24
- {simplex-1.2.63.dist-info → simplex-1.2.64.dist-info}/METADATA +2 -12
- simplex-1.2.64.dist-info/RECORD +11 -0
- {simplex-1.2.63.dist-info → simplex-1.2.64.dist-info}/WHEEL +1 -1
- simplex-1.2.63.dist-info/RECORD +0 -11
- {simplex-1.2.63.dist-info → simplex-1.2.64.dist-info}/LICENSE +0 -0
- {simplex-1.2.63.dist-info → simplex-1.2.64.dist-info}/entry_points.txt +0 -0
- {simplex-1.2.63.dist-info → simplex-1.2.64.dist-info}/top_level.txt +0 -0
simplex/simplex.py
CHANGED
|
@@ -5,20 +5,30 @@ import os
|
|
|
5
5
|
import json
|
|
6
6
|
import warnings
|
|
7
7
|
import time
|
|
8
|
+
import tempfile
|
|
8
9
|
# Try to import playwright, but don't fail if it's not available (lite version)
|
|
9
10
|
try:
|
|
10
11
|
from rebrowser_playwright.sync_api import sync_playwright
|
|
11
12
|
PLAYWRIGHT_AVAILABLE = True
|
|
12
13
|
except ImportError:
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
14
|
+
try:
|
|
15
|
+
from playwright.sync_api import sync_playwright
|
|
16
|
+
PLAYWRIGHT_AVAILABLE = True
|
|
17
|
+
warnings.warn(
|
|
18
|
+
"Using standard playwright instead of rebrowser-patches. Some anti-bot systems may detect automation. "
|
|
19
|
+
"To improve stealth, install with 'pip install rebrowser-playwright'",
|
|
20
|
+
ImportWarning
|
|
21
|
+
)
|
|
22
|
+
except ImportError:
|
|
23
|
+
PLAYWRIGHT_AVAILABLE = False
|
|
24
|
+
warnings.warn(
|
|
25
|
+
"Playwright is not available. Some features will be disabled. "
|
|
26
|
+
"To enable all features, install with 'pip install simplex[playwright]'",
|
|
27
|
+
ImportWarning
|
|
28
|
+
)
|
|
29
|
+
|
|
21
30
|
BASE_URL = "https://api.simplex.sh"
|
|
31
|
+
|
|
22
32
|
class Playwright:
|
|
23
33
|
def __init__(self, simplex_instance):
|
|
24
34
|
self.simplex = simplex_instance
|
|
@@ -58,7 +68,6 @@ class Playwright:
|
|
|
58
68
|
)
|
|
59
69
|
|
|
60
70
|
if 'succeeded' not in response.json():
|
|
61
|
-
print(response.json())
|
|
62
71
|
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
72
|
|
|
64
73
|
if "succeeded" in response.json():
|
|
@@ -111,6 +120,7 @@ class Simplex:
|
|
|
111
120
|
raise ValueError(f"Failed to close session: {response.json()['error']}")
|
|
112
121
|
|
|
113
122
|
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):
|
|
123
|
+
print("CREATING SESSION")
|
|
114
124
|
if self.session_id:
|
|
115
125
|
raise ValueError("A session is already active. Please close the current session before creating a new one.")
|
|
116
126
|
|
|
@@ -187,6 +197,7 @@ class Simplex:
|
|
|
187
197
|
},
|
|
188
198
|
data=data
|
|
189
199
|
)
|
|
200
|
+
|
|
190
201
|
if 'succeeded' not in response.json():
|
|
191
202
|
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?")
|
|
192
203
|
|
|
@@ -222,6 +233,65 @@ class Simplex:
|
|
|
222
233
|
else:
|
|
223
234
|
raise ValueError(f"Failed to click element: {response.json()['error']}")
|
|
224
235
|
|
|
236
|
+
|
|
237
|
+
def scroll_to_element(self, element_description: str, cdp_url: str = None):
|
|
238
|
+
if not element_description or not element_description.strip():
|
|
239
|
+
raise ValueError("element_description cannot be empty")
|
|
240
|
+
if not cdp_url and not self.session_id:
|
|
241
|
+
raise ValueError(f"Must call create_session before calling action scroll_to_element with element_description='{element_description}'")
|
|
242
|
+
|
|
243
|
+
data = {'element_description': element_description}
|
|
244
|
+
|
|
245
|
+
if cdp_url:
|
|
246
|
+
data['cdp_url'] = cdp_url
|
|
247
|
+
else:
|
|
248
|
+
data['session_id'] = self.session_id
|
|
249
|
+
|
|
250
|
+
response = requests.post(
|
|
251
|
+
f"{BASE_URL}/scroll_to_element",
|
|
252
|
+
headers={
|
|
253
|
+
'x-api-key': self.api_key
|
|
254
|
+
},
|
|
255
|
+
data=data
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
if 'succeeded' not in response.json():
|
|
259
|
+
raise ValueError(f"It looks like the scroll_to_element action failed to return a response. Did you set your api_key when creating the Simplex class?")
|
|
260
|
+
if response.json()["succeeded"]:
|
|
261
|
+
return
|
|
262
|
+
else:
|
|
263
|
+
raise ValueError(f"Failed to scroll element into view: {response.json()['error']}")
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def hover(self, element_description: str, cdp_url: str = None):
|
|
268
|
+
if not element_description or not element_description.strip():
|
|
269
|
+
raise ValueError("element_description cannot be empty")
|
|
270
|
+
if not cdp_url and not self.session_id:
|
|
271
|
+
raise ValueError(f"Must call create_session before calling action hover with element_description='{element_description}'")
|
|
272
|
+
|
|
273
|
+
data = {'element_description': element_description}
|
|
274
|
+
|
|
275
|
+
if cdp_url:
|
|
276
|
+
data['cdp_url'] = cdp_url
|
|
277
|
+
else:
|
|
278
|
+
data['session_id'] = self.session_id
|
|
279
|
+
|
|
280
|
+
response = requests.post(
|
|
281
|
+
f"{BASE_URL}/hover",
|
|
282
|
+
headers={
|
|
283
|
+
'x-api-key': self.api_key
|
|
284
|
+
},
|
|
285
|
+
data=data
|
|
286
|
+
)
|
|
287
|
+
if 'succeeded' not in response.json():
|
|
288
|
+
raise ValueError(f"It looks like the hover action failed to return a response. Did you set your api_key when creating the Simplex class?")
|
|
289
|
+
|
|
290
|
+
if response.json()["succeeded"]:
|
|
291
|
+
return
|
|
292
|
+
else:
|
|
293
|
+
raise ValueError(f"Failed to hover: {response.json()['error']}")
|
|
294
|
+
|
|
225
295
|
def type(self, text: str, cdp_url: str = None):
|
|
226
296
|
if not text or not text.strip():
|
|
227
297
|
raise ValueError("text cannot be empty")
|
|
@@ -245,7 +315,6 @@ class Simplex:
|
|
|
245
315
|
if "succeeded" in response.json():
|
|
246
316
|
return
|
|
247
317
|
else:
|
|
248
|
-
print(response.json())
|
|
249
318
|
raise ValueError(f"Failed to type text: {response.json()['error']}")
|
|
250
319
|
|
|
251
320
|
|
|
@@ -495,24 +564,23 @@ class Simplex:
|
|
|
495
564
|
return netloc.replace(".", "_")
|
|
496
565
|
|
|
497
566
|
with sync_playwright() as p:
|
|
498
|
-
|
|
567
|
+
browser = p.chromium.launch(
|
|
499
568
|
channel="chrome",
|
|
500
569
|
headless=False,
|
|
501
570
|
args=[
|
|
502
571
|
'--disable-blink-features=AutomationControlled',
|
|
503
572
|
'--disable-automation',
|
|
504
573
|
],
|
|
505
|
-
ignore_default_args=['--enable-automation']
|
|
506
|
-
user_data_dir="/home/simplex/.config/google-chrome/Profile 1/",
|
|
507
|
-
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
|
|
508
|
-
viewport={"width": 1243, "height": 681}
|
|
574
|
+
ignore_default_args=['--enable-automation']
|
|
509
575
|
)
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
576
|
+
# Create context and pages
|
|
577
|
+
context = browser.new_context(viewport=None)
|
|
578
|
+
main_page = context.new_page()
|
|
579
|
+
main_page.goto(url)
|
|
580
|
+
|
|
581
|
+
# Create control page in same context
|
|
514
582
|
control_page = context.new_page()
|
|
515
|
-
|
|
583
|
+
# Use a simple HTML file instead of set_content
|
|
516
584
|
html_content = """
|
|
517
585
|
<!DOCTYPE html>
|
|
518
586
|
<html>
|
|
@@ -533,7 +601,6 @@ class Simplex:
|
|
|
533
601
|
</body>
|
|
534
602
|
</html>
|
|
535
603
|
"""
|
|
536
|
-
import tempfile
|
|
537
604
|
# Write to a temporary file
|
|
538
605
|
with tempfile.NamedTemporaryFile(delete=False, suffix='.html', mode='w') as f:
|
|
539
606
|
f.write(html_content)
|
|
@@ -560,6 +627,7 @@ class Simplex:
|
|
|
560
627
|
os.unlink(temp_path)
|
|
561
628
|
except:
|
|
562
629
|
pass
|
|
630
|
+
|
|
563
631
|
# Use context.storage_state() instead of browser.storage_state()
|
|
564
632
|
storage = context.storage_state()
|
|
565
633
|
if save_directory:
|
|
@@ -572,9 +640,37 @@ class Simplex:
|
|
|
572
640
|
|
|
573
641
|
print(f"Session data saved to '{filename}'")
|
|
574
642
|
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
643
|
+
browser.close()
|
|
644
|
+
|
|
645
|
+
return filename
|
|
646
|
+
|
|
647
|
+
def get_network_response(self, url: str, cdp_url: str = None):
|
|
648
|
+
print(f"Getting network response for {url}")
|
|
649
|
+
if not cdp_url and not self.session_id:
|
|
650
|
+
raise ValueError(f"Must call create_session before calling action get_network_response with url='{url}'")
|
|
651
|
+
|
|
652
|
+
data = {'url': url}
|
|
653
|
+
|
|
654
|
+
if cdp_url:
|
|
655
|
+
data['cdp_url'] = cdp_url
|
|
656
|
+
else:
|
|
657
|
+
data['session_id'] = self.session_id
|
|
658
|
+
|
|
659
|
+
response = requests.post(
|
|
660
|
+
f"{BASE_URL}/get_network_response",
|
|
661
|
+
headers={
|
|
662
|
+
'x-api-key': self.api_key
|
|
663
|
+
},
|
|
664
|
+
data=data
|
|
665
|
+
)
|
|
666
|
+
|
|
667
|
+
if 'status' not in response.json():
|
|
668
|
+
raise ValueError(f"It looks like the get_network_response action failed to return a response. Did you set your api_key when creating the Simplex class?")
|
|
669
|
+
if response.json()['status'] == 'success':
|
|
670
|
+
return response.json()['response']
|
|
671
|
+
else:
|
|
672
|
+
raise ValueError(f"Failed to get network response: {response.json()['error']}")
|
|
673
|
+
|
|
578
674
|
def restore_login_session(self, session_data: str, cdp_url: str = None):
|
|
579
675
|
"""
|
|
580
676
|
Restore a login session from either a file path or a JSON string.
|
|
@@ -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.64
|
|
4
4
|
Summary: Official Python SDK for Simplex API
|
|
5
5
|
Home-page: https://simplex.sh
|
|
6
6
|
Author: Simplex Labs, Inc.
|
|
@@ -19,16 +19,6 @@ Requires-Dist: python-dotenv
|
|
|
19
19
|
Requires-Dist: click
|
|
20
20
|
Provides-Extra: playwright
|
|
21
21
|
Requires-Dist: playwright>=1.0.0; extra == "playwright"
|
|
22
|
-
Dynamic: author
|
|
23
|
-
Dynamic: author-email
|
|
24
|
-
Dynamic: classifier
|
|
25
|
-
Dynamic: description
|
|
26
|
-
Dynamic: description-content-type
|
|
27
|
-
Dynamic: home-page
|
|
28
|
-
Dynamic: provides-extra
|
|
29
|
-
Dynamic: requires-dist
|
|
30
|
-
Dynamic: requires-python
|
|
31
|
-
Dynamic: summary
|
|
32
22
|
|
|
33
23
|
# Simplex AI Python SDK
|
|
34
24
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
simplex/__init__.py,sha256=L_5i__xt_ZDkr6e-Wx9cr84t9sXpioOT7j01NJYJCTE,75
|
|
2
|
+
simplex/cli.py,sha256=0K_pzoVdF7vfTJPUONhFzzTvjZk2M7FZPpEONjZWJC8,2268
|
|
3
|
+
simplex/simplex.py,sha256=Qz64Q1fUhgssSswlyFMa1j6Kqml_Q43Bbxl5izlkIQs,32688
|
|
4
|
+
simplex/deploy/__init__.py,sha256=_JQ81F_Nu7hSAfMA691gzs6a4-8oZ-buJ9h3Au12BKw,96
|
|
5
|
+
simplex/deploy/push.py,sha256=hRAbtFZaECKnBljaOLQ5nzJ6hk7tZgc1c7QdgxKQFoY,6123
|
|
6
|
+
simplex-1.2.64.dist-info/LICENSE,sha256=Xh0SJjYZfNI71pCNMB40aKlBLLuOB0blx5xkTtufFNQ,1075
|
|
7
|
+
simplex-1.2.64.dist-info/METADATA,sha256=DKPy2BYY6neMwiFgOMK9lIc92V1-qK1uCwUAXu-2Spk,824
|
|
8
|
+
simplex-1.2.64.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
|
9
|
+
simplex-1.2.64.dist-info/entry_points.txt,sha256=3veL2w3c5vxb3dm8I_M8Fs-370n1ZnvD8uu1nSsL7z8,45
|
|
10
|
+
simplex-1.2.64.dist-info/top_level.txt,sha256=cbMH1bYpN0A3gP-ecibPRHasHoqB-01T_2BUFS8p0CE,8
|
|
11
|
+
simplex-1.2.64.dist-info/RECORD,,
|
simplex-1.2.63.dist-info/RECORD
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
simplex/__init__.py,sha256=L_5i__xt_ZDkr6e-Wx9cr84t9sXpioOT7j01NJYJCTE,75
|
|
2
|
-
simplex/cli.py,sha256=0K_pzoVdF7vfTJPUONhFzzTvjZk2M7FZPpEONjZWJC8,2268
|
|
3
|
-
simplex/simplex.py,sha256=iY_zM02VwS6ru2eHUTz1sNnnZ9pdf4Y7XnT6FQJKKgE,29206
|
|
4
|
-
simplex/deploy/__init__.py,sha256=_JQ81F_Nu7hSAfMA691gzs6a4-8oZ-buJ9h3Au12BKw,96
|
|
5
|
-
simplex/deploy/push.py,sha256=hRAbtFZaECKnBljaOLQ5nzJ6hk7tZgc1c7QdgxKQFoY,6123
|
|
6
|
-
simplex-1.2.63.dist-info/LICENSE,sha256=Xh0SJjYZfNI71pCNMB40aKlBLLuOB0blx5xkTtufFNQ,1075
|
|
7
|
-
simplex-1.2.63.dist-info/METADATA,sha256=gQZ7RVjUwC8Yk6SsxkuvLl4v9ijC3PfuC3Uky8mUmeA,1045
|
|
8
|
-
simplex-1.2.63.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
9
|
-
simplex-1.2.63.dist-info/entry_points.txt,sha256=3veL2w3c5vxb3dm8I_M8Fs-370n1ZnvD8uu1nSsL7z8,45
|
|
10
|
-
simplex-1.2.63.dist-info/top_level.txt,sha256=cbMH1bYpN0A3gP-ecibPRHasHoqB-01T_2BUFS8p0CE,8
|
|
11
|
-
simplex-1.2.63.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|