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 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
- PLAYWRIGHT_AVAILABLE = False
14
- warnings.warn(
15
- "Playwright is not available. Some features will be disabled. "
16
- "To enable all features, install with 'pip install simplex[playwright]'",
17
- ImportWarning
18
- )
19
-
20
- # BASE_URL = "https://simplex-dev--api-server-fastapi-app.modal.run"
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
- context = p.chromium.launch_persistent_context(
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
- main_page = context.pages[0]
511
- main_page.goto(url, wait_until="networkidle")
512
-
513
- # # Create control page in same context
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
- # Use a simple HTML file instead of set_content
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
- context.close()
576
- # return filename
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.2
1
+ Metadata-Version: 2.1
2
2
  Name: simplex
3
- Version: 1.2.63
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,,
@@ -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
 
@@ -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,,