simplex 1.2.61__tar.gz → 1.2.63__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.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: simplex
3
- Version: 1.2.61
3
+ Version: 1.2.63
4
4
  Summary: Official Python SDK for Simplex API
5
5
  Home-page: https://simplex.sh
6
6
  Author: Simplex Labs, Inc.
@@ -22,7 +22,7 @@ class PostInstallCommand(install):
22
22
 
23
23
  setup(
24
24
  name="simplex",
25
- version="1.2.61",
25
+ version="1.2.63",
26
26
  packages=find_packages(),
27
27
  package_data={
28
28
  "simplex": ["browser_agent/dom/*.js"], # Include JS files in the dom directory
@@ -7,7 +7,7 @@ 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
- from playwright.sync_api import sync_playwright
10
+ from rebrowser_playwright.sync_api import sync_playwright
11
11
  PLAYWRIGHT_AVAILABLE = True
12
12
  except ImportError:
13
13
  PLAYWRIGHT_AVAILABLE = False
@@ -495,52 +495,71 @@ class Simplex:
495
495
  return netloc.replace(".", "_")
496
496
 
497
497
  with sync_playwright() as p:
498
- browser = p.chromium.launch(
498
+ context = p.chromium.launch_persistent_context(
499
499
  channel="chrome",
500
500
  headless=False,
501
501
  args=[
502
502
  '--disable-blink-features=AutomationControlled',
503
503
  '--disable-automation',
504
504
  ],
505
- ignore_default_args=['--enable-automation']
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}
506
509
  )
507
-
508
- # Create context and pages
509
- context = browser.new_context()
510
- main_page = context.new_page()
511
- main_page.goto(url)
512
-
513
- # Create control page in same context
510
+ main_page = context.pages[0]
511
+ main_page.goto(url, wait_until="networkidle")
512
+
513
+ # # Create control page in same context
514
514
  control_page = context.new_page()
515
- control_page.set_content("""
516
- <html>
517
- <body style="display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background-color: #f5f5f5;">
518
- <button id="capture-btn" style="
519
- padding: 20px 40px;
520
- font-size: 18px;
521
- cursor: pointer;
522
- background-color: #2196F3;
523
- color: white;
524
- border: none;
525
- border-radius: 5px;
526
- box-shadow: 0 2px 4px rgba(0,0,0,0.2);
527
- ">Click here when logged in to capture session</button>
528
- </body>
529
- </html>
530
- """)
531
-
532
- # Wait for button click using Playwright's wait_for_event
533
- control_page.wait_for_selector('#capture-btn')
534
- control_page.evaluate("""
535
- () => {
536
- return new Promise((resolve) => {
537
- document.getElementById('capture-btn').onclick = () => {
538
- resolve(true);
539
- }
540
- });
541
- }
542
- """)
515
+ # Use a simple HTML file instead of set_content
516
+ html_content = """
517
+ <!DOCTYPE html>
518
+ <html>
519
+ <head>
520
+ <title>Capture Session</title>
521
+ </head>
522
+ <body style="display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background-color: #f5f5f5;">
523
+ <button id="capture-btn" style="
524
+ padding: 20px 40px;
525
+ font-size: 18px;
526
+ cursor: pointer;
527
+ background-color: #2196F3;
528
+ color: white;
529
+ border: none;
530
+ border-radius: 5px;
531
+ box-shadow: 0 2px 4px rgba(0,0,0,0.2);
532
+ ">Click here when logged in to capture session</button>
533
+ </body>
534
+ </html>
535
+ """
536
+ import tempfile
537
+ # Write to a temporary file
538
+ with tempfile.NamedTemporaryFile(delete=False, suffix='.html', mode='w') as f:
539
+ f.write(html_content)
540
+ temp_path = f.name
543
541
 
542
+ try:
543
+ # Load from file instead of set_content
544
+ control_page.goto(f"file://{temp_path}")
545
+ control_page.wait_for_selector('#capture-btn', timeout=30000)
546
+
547
+ # Wait for button click
548
+ control_page.evaluate("""
549
+ () => {
550
+ return new Promise((resolve) => {
551
+ document.getElementById('capture-btn').onclick = () => {
552
+ resolve(true);
553
+ }
554
+ });
555
+ }
556
+ """)
557
+ finally:
558
+ # Clean up temp file
559
+ try:
560
+ os.unlink(temp_path)
561
+ except:
562
+ pass
544
563
  # Use context.storage_state() instead of browser.storage_state()
545
564
  storage = context.storage_state()
546
565
  if save_directory:
@@ -553,9 +572,8 @@ class Simplex:
553
572
 
554
573
  print(f"Session data saved to '{filename}'")
555
574
 
556
- browser.close()
557
-
558
- return filename
575
+ context.close()
576
+ # return filename
559
577
 
560
578
  def restore_login_session(self, session_data: str, cdp_url: str = None):
561
579
  """
@@ -661,12 +679,29 @@ class Simplex:
661
679
  },
662
680
  data=data
663
681
  )
664
- if 'succeeded' not in response.json():
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?")
666
- if "succeeded" in response.json():
667
- return response.json()["b64"], response.json()["filename"]
668
- else:
669
- raise ValueError(f"Failed to click and download: {response.json()['error']}")
682
+ # Get filename from Content-Disposition header
683
+ content_disposition = response.headers.get('Content-Disposition')
684
+ if content_disposition:
685
+ try:
686
+ filename = content_disposition.split('filename=')[1].strip('"')
687
+ except:
688
+ try:
689
+ filename_star = content_disposition.split('filename*=')[1].split(';')[0]
690
+ # Parse the RFC 5987 encoded filename
691
+ encoding, _, fname = filename_star.split("'", 2)
692
+ # URL decode the filename
693
+ from urllib.parse import unquote
694
+ filename = unquote(fname)
695
+ except Exception:
696
+ raise ValueError("File failed to be parsed from Content-Disposition header.")
697
+ else:
698
+ raise ValueError("No Content-Disposition header found. File was not downloaded.")
699
+
700
+ # Check if response content is empty
701
+ if len(response.content) == 0:
702
+ raise ValueError("Downloaded file is empty (0 bytes)")
703
+
704
+ return filename, response.content
670
705
 
671
706
  def exists(self, element_description: str, cdp_url: str = None):
672
707
  if not element_description or not element_description.strip():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: simplex
3
- Version: 1.2.61
3
+ Version: 1.2.63
4
4
  Summary: Official Python SDK for Simplex API
5
5
  Home-page: https://simplex.sh
6
6
  Author: Simplex Labs, Inc.
File without changes
File without changes
File without changes
File without changes
File without changes