simplex 1.2.36__py3-none-any.whl → 1.2.37__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/cli.py CHANGED
@@ -63,13 +63,14 @@ def login(website, proxies):
63
63
  website = 'https://' + website
64
64
 
65
65
  animated_print(f"[SIMPLEX] Creating login session for {website}")
66
- login_session_url = simplex.create_login_session(website, proxies=proxies)
67
-
68
- if login_session_url:
69
- animated_print("[SIMPLEX] Opening login page in your browser")
70
- webbrowser.open_new_tab(login_session_url)
66
+
67
+ fileName = simplex.create_login_session(website, proxies=proxies)
68
+
69
+ if fileName:
70
+ animated_print(f"[SIMPLEX] Login session created and saved to {fileName}")
71
71
  else:
72
- print(f"{Fore.YELLOW}[SIMPLEX] Warning: No login URL returned from the server{Style.RESET_ALL}")
72
+ print(f"{Fore.YELLOW}[SIMPLEX] Warning: Session data could not be saved{Style.RESET_ALL}")
73
+
73
74
  except Exception as e:
74
75
  raise click.ClickException(str(e))
75
76
 
simplex/simplex.py CHANGED
@@ -1,9 +1,60 @@
1
1
  import requests
2
2
  import atexit
3
3
  from typing import Optional
4
+ from playwright.sync_api import sync_playwright
5
+ import os
6
+ import json
7
+
4
8
  BASE_URL = "https://api.simplex.sh"
5
9
 
6
- import json
10
+ class Playwright:
11
+ def __init__(self, simplex_instance):
12
+ self.simplex = simplex_instance
13
+
14
+ def click(self, locator: str, locator_type: str, exact: Optional[bool] = False,
15
+ element_index: Optional[str] = None, nth_index: Optional[int] = None,
16
+ locator_options: Optional[dict] = None):
17
+
18
+ if element_index and element_index not in ["first", "last", "nth"]:
19
+ raise ValueError("element_index must be 'first', 'last', or 'nth'")
20
+
21
+ if element_index=="nth" and not nth_index:
22
+ raise ValueError("nth_index is required when element_index is 'nth'")
23
+
24
+ data = {
25
+ 'session_id': self.simplex.session_id,
26
+ 'locator': locator,
27
+ 'locator_type': locator_type,
28
+ }
29
+
30
+ if element_index:
31
+ data['element_index'] = element_index
32
+ data['nth_index'] = nth_index
33
+
34
+ if exact:
35
+ data['exact'] = exact
36
+
37
+ if locator_options:
38
+ data['locator_options'] = json.dumps(locator_options)
39
+
40
+ response = requests.post(
41
+ f"{BASE_URL}/playwright/click",
42
+ headers={
43
+ 'x-api-key': self.simplex.api_key
44
+ },
45
+ data=data
46
+ )
47
+
48
+ if 'succeeded' not in response.json():
49
+ print(response.json())
50
+ 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?")
51
+
52
+ if response.json()["succeeded"]:
53
+ return
54
+ else:
55
+ raise ValueError(f"Failed to click element: {response.json()['error']}")
56
+
57
+
7
58
 
8
59
  class Simplex:
9
60
  def __init__(self, api_key: str):
@@ -11,6 +62,8 @@ class Simplex:
11
62
  self.session_id = None
12
63
  atexit.register(self.close_session)
13
64
 
65
+ self.playwright = Playwright(self)
66
+
14
67
  def close_session(self):
15
68
  if not self.session_id:
16
69
  return
@@ -50,7 +103,7 @@ class Simplex:
50
103
  if show_in_console:
51
104
  print(f"Livestream URL: {livestream_url}")
52
105
 
53
- return livestream_url
106
+ return self.session_id, livestream_url
54
107
 
55
108
  def goto(self, url: str, cdp_url: str = None):
56
109
  if not cdp_url and not self.session_id:
@@ -329,20 +382,81 @@ class Simplex:
329
382
  else:
330
383
  raise ValueError(f"Failed to wait: {response.json()['error']}")
331
384
 
332
- def create_login_session(self, url: str, proxies: Optional[bool] = True):
333
- response = requests.post(
334
- f"{BASE_URL}/create_login_session",
335
- headers={
336
- 'x-api-key': self.api_key
337
- },
338
- data={'url': url, 'proxies': proxies}
339
- )
340
- if 'succeeded' not in response.json():
341
- raise ValueError(f"It looks like the create_login_session action failed to return a response. Did you set your api_key when creating the Simplex class?")
342
- if response.json()["succeeded"]:
343
- return response.json()["login_session_url"]
344
- else:
345
- raise ValueError(f"Failed to create login session: {response.json()['error']}")
385
+ def create_login_session(self, url: str, save_directory: Optional[str] = None, proxies: Optional[bool] = True):
386
+ def get_website_name(url: str) -> str:
387
+ """Extract website name from URL"""
388
+ from urllib.parse import urlparse
389
+ netloc = urlparse(url).netloc
390
+ # Remove www. if present
391
+ if netloc.startswith('www.'):
392
+ netloc = netloc[4:]
393
+ return netloc.replace(".", "_")
394
+
395
+ with sync_playwright() as p:
396
+ browser = p.chromium.launch_persistent_context(
397
+ user_data_dir="",
398
+ channel="chrome",
399
+ headless=False,
400
+ args=[
401
+ '--disable-blink-features=AutomationControlled',
402
+ '--disable-automation',
403
+ ],
404
+ ignore_default_args=['--enable-automation']
405
+ )
406
+
407
+ # Close the default about:blank page
408
+ if len(browser.pages) > 0:
409
+ browser.pages[0].close()
410
+
411
+ # Create main page for login
412
+ main_page = browser.new_page()
413
+ main_page.goto(url)
414
+
415
+ # Create control page
416
+ control_page = browser.new_page()
417
+ control_page.set_content("""
418
+ <html>
419
+ <body style="display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background-color: #f5f5f5;">
420
+ <button id="capture-btn" style="
421
+ padding: 20px 40px;
422
+ font-size: 18px;
423
+ cursor: pointer;
424
+ background-color: #2196F3;
425
+ color: white;
426
+ border: none;
427
+ border-radius: 5px;
428
+ box-shadow: 0 2px 4px rgba(0,0,0,0.2);
429
+ ">Click here when logged in to capture session</button>
430
+ </body>
431
+ </html>
432
+ """)
433
+
434
+ # Wait for button click using Playwright's wait_for_event
435
+ control_page.wait_for_selector('#capture-btn')
436
+ control_page.evaluate("""
437
+ () => {
438
+ return new Promise((resolve) => {
439
+ document.getElementById('capture-btn').onclick = () => {
440
+ resolve(true);
441
+ }
442
+ });
443
+ }
444
+ """)
445
+
446
+ storage = browser.storage_state()
447
+ if save_directory:
448
+ filename = os.path.join(save_directory, get_website_name(url) + "_session_data.json")
449
+ else:
450
+ filename = get_website_name(url) + "_session_data.json"
451
+
452
+ with open(filename, 'w') as f:
453
+ json.dump(storage, f, indent=2)
454
+
455
+ print(f"Session data saved to '{filename}'")
456
+
457
+ browser.close()
458
+
459
+ return filename
346
460
 
347
461
  def restore_login_session(self, session_data: str, cdp_url: str = None):
348
462
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: simplex
3
- Version: 1.2.36
3
+ Version: 1.2.37
4
4
  Summary: Official Python SDK for Simplex API
5
5
  Home-page: https://simplex.sh
6
6
  Author: Simplex Labs, Inc.
@@ -0,0 +1,11 @@
1
+ simplex/__init__.py,sha256=L_5i__xt_ZDkr6e-Wx9cr84t9sXpioOT7j01NJYJCTE,75
2
+ simplex/cli.py,sha256=DxZMiX-mqhy1cWJhf75YQs49GfZediueFuxyEhBFpLk,2324
3
+ simplex/simplex.py,sha256=8JcmId0SQ32GamEAQTWQlafQpa8oswmXM6E3Plfn-9k,21853
4
+ simplex/deploy/__init__.py,sha256=_JQ81F_Nu7hSAfMA691gzs6a4-8oZ-buJ9h3Au12BKw,96
5
+ simplex/deploy/push.py,sha256=hRAbtFZaECKnBljaOLQ5nzJ6hk7tZgc1c7QdgxKQFoY,6123
6
+ simplex-1.2.37.dist-info/LICENSE,sha256=Xh0SJjYZfNI71pCNMB40aKlBLLuOB0blx5xkTtufFNQ,1075
7
+ simplex-1.2.37.dist-info/METADATA,sha256=DTpFDlzDtuQsYAjR-2I4CmGUlObOq3MD814DTqCAQSs,964
8
+ simplex-1.2.37.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
9
+ simplex-1.2.37.dist-info/entry_points.txt,sha256=3veL2w3c5vxb3dm8I_M8Fs-370n1ZnvD8uu1nSsL7z8,45
10
+ simplex-1.2.37.dist-info/top_level.txt,sha256=cbMH1bYpN0A3gP-ecibPRHasHoqB-01T_2BUFS8p0CE,8
11
+ simplex-1.2.37.dist-info/RECORD,,
@@ -1,11 +0,0 @@
1
- simplex/__init__.py,sha256=L_5i__xt_ZDkr6e-Wx9cr84t9sXpioOT7j01NJYJCTE,75
2
- simplex/cli.py,sha256=FlZPWx014wpIy3TWYxhv8pANoPG9UWoq-ipkEIaiJAU,2389
3
- simplex/simplex.py,sha256=dVFAW1Q83gSTpn20G6DOsKyvnILQsOIeJqOUYySgwjU,17707
4
- simplex/deploy/__init__.py,sha256=_JQ81F_Nu7hSAfMA691gzs6a4-8oZ-buJ9h3Au12BKw,96
5
- simplex/deploy/push.py,sha256=hRAbtFZaECKnBljaOLQ5nzJ6hk7tZgc1c7QdgxKQFoY,6123
6
- simplex-1.2.36.dist-info/LICENSE,sha256=Xh0SJjYZfNI71pCNMB40aKlBLLuOB0blx5xkTtufFNQ,1075
7
- simplex-1.2.36.dist-info/METADATA,sha256=th6kl09ViBxgKGYrIqgQej82XwrVnieyCgl5BJXtMiw,964
8
- simplex-1.2.36.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
9
- simplex-1.2.36.dist-info/entry_points.txt,sha256=3veL2w3c5vxb3dm8I_M8Fs-370n1ZnvD8uu1nSsL7z8,45
10
- simplex-1.2.36.dist-info/top_level.txt,sha256=cbMH1bYpN0A3gP-ecibPRHasHoqB-01T_2BUFS8p0CE,8
11
- simplex-1.2.36.dist-info/RECORD,,