simplex 1.2.10__py3-none-any.whl → 1.2.12__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
@@ -1,6 +1,24 @@
1
1
  import click
2
2
  from .deploy import push_directory, run_directory
3
+ from .simplex import Simplex
3
4
  import os
5
+ from dotenv import load_dotenv
6
+ import webbrowser
7
+ from colorama import init, Fore, Style
8
+ import time
9
+ import sys
10
+
11
+ init() # Initialize colorama
12
+
13
+ load_dotenv()
14
+
15
+ def animated_print(message, color=Fore.CYAN):
16
+ """Print with animated ellipsis"""
17
+ for i in range(3):
18
+ sys.stdout.write(f'\r{color}{message}{"." * (i+1)}{" " * (2-i)}{Style.RESET_ALL}')
19
+ sys.stdout.flush()
20
+ time.sleep(0.5)
21
+ sys.stdout.write('\n')
4
22
 
5
23
  @click.group()
6
24
  def cli():
@@ -13,7 +31,7 @@ def push(directory):
13
31
  try:
14
32
  push_directory(directory)
15
33
  except Exception as e:
16
- print(f"Error running job: {e}")
34
+ print(f"{Fore.RED}[SIMPLEX] Error running job: {e}{Style.RESET_ALL}")
17
35
  raise
18
36
 
19
37
 
@@ -24,8 +42,42 @@ def run(directory):
24
42
  try:
25
43
  run_directory(directory)
26
44
  except Exception as e:
27
- print(f"Error running job: {e}")
45
+ print(f"{Fore.RED}[SIMPLEX] Error running job: {e}{Style.RESET_ALL}")
28
46
  raise
29
47
 
48
+ @cli.command()
49
+ @click.argument('website')
50
+ def login(website):
51
+ """Capture login session for a website"""
52
+ try:
53
+ # Initialize Simplex with API key from environment
54
+ api_key = os.getenv("SIMPLEX_API_KEY")
55
+ if not api_key:
56
+ raise click.ClickException("SIMPLEX_API_KEY environment variable not set")
57
+
58
+ simplex = Simplex(api_key)
59
+
60
+ # Ensure website has proper URL format
61
+ if not website.startswith(('http://', 'https://')):
62
+ website = 'https://' + website
63
+
64
+ animated_print(f"[SIMPLEX] Creating login session for {website}")
65
+ result = simplex.capture_login_session(website)
66
+
67
+ if result.get('succeeded'):
68
+ # Open the login URL in a new browser tab
69
+ login_url = result.get('login_session_url')
70
+ if login_url:
71
+ animated_print("[SIMPLEX] Opening login page in your browser")
72
+ webbrowser.open_new_tab(login_url)
73
+ else:
74
+ print(f"{Fore.YELLOW}[SIMPLEX] Warning: No login URL returned from the server{Style.RESET_ALL}")
75
+ else:
76
+ print(f"{Fore.RED}[SIMPLEX] Failed to capture login session: {result.get('error', 'Unknown error')}{Style.RESET_ALL}")
77
+ except Exception as e:
78
+ raise click.ClickException(str(e))
79
+ finally:
80
+ print(f"{Fore.GREEN}[SIMPLEX] Login session closed.{Style.RESET_ALL}")
81
+
30
82
  def main():
31
83
  cli()
simplex/deploy/push.py CHANGED
@@ -7,8 +7,7 @@ from dotenv import load_dotenv
7
7
  import requests
8
8
  from typing import Optional
9
9
  from datetime import datetime, timedelta
10
-
11
-
10
+ load_dotenv() # This loads the .env file
12
11
 
13
12
  S3_URL = "https://u3mvtbirxf.us-east-1.awsapprunner.com"
14
13
  JOB_URL = "https://simplex--job-scheduler-app-handler.modal.run"
@@ -42,7 +41,6 @@ def create_archive(directory: str, config: dict) -> str:
42
41
 
43
42
  def push_directory(directory: str):
44
43
  """Main function to handle parsing yaml and creating zip archive"""
45
-
46
44
  config = read_config(directory)
47
45
  archive_path = create_archive(directory, config)
48
46
 
@@ -63,7 +61,7 @@ def push_directory(directory: str):
63
61
  os.unlink(archive_path)
64
62
 
65
63
  try:
66
- create_job_scheduled(directory, project_name, cron_schedule, s3_uri)
64
+ create_job_scheduled(project_name, cron_schedule, s3_uri)
67
65
  except Exception as e:
68
66
  print(f"Error creating job: {e}")
69
67
  raise
@@ -72,13 +70,7 @@ def push_directory(directory: str):
72
70
 
73
71
 
74
72
 
75
- def upload_files_to_s3(directory: str, archive_path: str, project_name: str):
76
- """Upload files to S3"""
77
- # Load .env file from the target directory
78
- env_path = Path(directory) / '.env'
79
- if env_path.exists():
80
- load_dotenv(env_path)
81
-
73
+ def upload_files_to_s3(archive_path: str, project_name: str):
82
74
  # Read API key from environment
83
75
  api_key = os.getenv('SIMPLEX_API_KEY')
84
76
  if not api_key:
@@ -115,14 +107,8 @@ def upload_files_to_s3(directory: str, archive_path: str, project_name: str):
115
107
  print(f"Error uploading project: {e}")
116
108
  raise
117
109
 
118
- def create_job_scheduled(directory: str, project_name: str, cron_schedule: str, s3_uri: str):
110
+ def create_job_scheduled(project_name: str, cron_schedule: str, s3_uri: str):
119
111
  """Create a new job via the API"""
120
-
121
- # Load .env file from the target directory
122
- env_path = Path(directory) / '.env'
123
- if env_path.exists():
124
- load_dotenv(env_path)
125
-
126
112
  # Read API key from environment
127
113
  api_key = os.getenv('SIMPLEX_API_KEY')
128
114
  if not api_key:
@@ -159,14 +145,8 @@ def create_job_scheduled(directory: str, project_name: str, cron_schedule: str,
159
145
  raise
160
146
 
161
147
 
162
- def create_job_immediately(directory: str, project_name: str, s3_uri: str):
148
+ def create_job_immediately(project_name: str, s3_uri: str):
163
149
  """Create a new job via the API"""
164
-
165
- # Load .env file from the target directory
166
- env_path = Path(directory) / '.env'
167
- if env_path.exists():
168
- load_dotenv(env_path)
169
-
170
150
  # Read API key from environment
171
151
  api_key = os.getenv('SIMPLEX_API_KEY')
172
152
  if not api_key:
@@ -205,11 +185,6 @@ def create_job_immediately(directory: str, project_name: str, s3_uri: str):
205
185
 
206
186
  def run_directory(directory: str):
207
187
  """Run a directory immediately"""
208
- # Load .env file from the target directory
209
- env_path = Path(directory) / '.env'
210
- if env_path.exists():
211
- load_dotenv(env_path)
212
-
213
188
  config = read_config(directory)
214
189
  archive_path = create_archive(directory, config)
215
190
 
@@ -218,7 +193,7 @@ def run_directory(directory: str):
218
193
  raise ValueError("Project name not specified in simplex.yaml")
219
194
 
220
195
  try:
221
- s3_uri = upload_files_to_s3(directory, archive_path, project_name)
196
+ s3_uri = upload_files_to_s3(archive_path, project_name)
222
197
  except Exception as e:
223
198
  print(f"Error uploading project: {e}")
224
199
  raise
@@ -227,7 +202,7 @@ def run_directory(directory: str):
227
202
  os.unlink(archive_path)
228
203
 
229
204
  try:
230
- create_job_immediately(directory, project_name, s3_uri)
205
+ create_job_immediately(project_name, s3_uri)
231
206
  except Exception as e:
232
207
  print(f"Error creating job: {e}")
233
208
  raise
simplex/simplex.py CHANGED
@@ -3,24 +3,18 @@ import requests
3
3
  import atexit
4
4
 
5
5
  BASE_URL = "https://api.simplex.sh"
6
+
6
7
  import json
7
8
 
8
9
  class Simplex:
9
10
  def __init__(self, api_key: str):
10
11
  self.api_key = api_key
11
12
  self.session_id = None
12
- atexit.register(self.cleanup_session)
13
-
14
- def cleanup_session(self):
15
- if self.session_id:
16
- try:
17
- self.close_session(self.session_id)
18
- except:
19
- pass
13
+ atexit.register(self.close_session)
20
14
 
21
15
  def close_session(self):
22
16
  response = requests.post(
23
- f"{BASE_URL}/close",
17
+ f"{BASE_URL}/close-session",
24
18
  headers={
25
19
  'x-api-key': self.api_key
26
20
  },
@@ -41,10 +35,6 @@ class Simplex:
41
35
  self.session_id = response_json['session_id']
42
36
  livestream_url = response_json['livestream_url']
43
37
 
44
- print(f"\nSession created successfully!")
45
- print(f"Session ID: {self.session_id}")
46
- print(f"Livestream URL: {livestream_url}\n")
47
-
48
38
  return self.session_id, livestream_url
49
39
 
50
40
  def goto(self, url: str, cdp_url: str = None):
@@ -70,7 +60,7 @@ class Simplex:
70
60
  )
71
61
  return response.json()
72
62
 
73
- def click(self, element_description: str, cdp_url: str = None):
63
+ def click(self, element_description: str, cdp_url: str = None, use_vision: bool = False):
74
64
  if not cdp_url and not self.session_id:
75
65
  raise ValueError(f"Must call create_session before calling action click with element_description='{element_description}'")
76
66
 
@@ -81,6 +71,9 @@ class Simplex:
81
71
  else:
82
72
  data['session_id'] = self.session_id
83
73
 
74
+ if use_vision:
75
+ data['use_vision'] = use_vision
76
+
84
77
  response = requests.post(
85
78
  f"{BASE_URL}/click",
86
79
  headers={
@@ -268,11 +261,55 @@ class Simplex:
268
261
  )
269
262
  return response.json()
270
263
 
271
- def run_agent(self, prompt: str, cdp_url: str = None):
264
+ def click_and_upload(self, element_description: str, file_path: str):
265
+ if not self.session_id:
266
+ raise ValueError(f"Must call create_session before calling action click_and_upload with element_description='{element_description}'")
267
+
268
+ files = {
269
+ 'zip_file': open(file_path, 'rb')
270
+ }
271
+
272
+ data = {
273
+ 'element_description': element_description
274
+ }
275
+
276
+ data['session_id'] = self.session_id
277
+
278
+ response = requests.post(
279
+ f"{BASE_URL}/click_and_upload",
280
+ headers={
281
+ 'x-api-key': self.api_key
282
+ },
283
+ files=files,
284
+ data=data
285
+ )
286
+ return response.json()
287
+
288
+ def click_and_download(self, element_description: str):
289
+ if not self.session_id:
290
+ raise ValueError(f"Must call create_session before calling action click_and_download with element_description='{element_description}'")
291
+
292
+ data = {
293
+ 'element_description': element_description
294
+ }
295
+
296
+ data['session_id'] = self.session_id
297
+
298
+ response = requests.post(
299
+ f"{BASE_URL}/click_and_download",
300
+ headers={
301
+ 'x-api-key': self.api_key
302
+ },
303
+ data=data
304
+ )
305
+
306
+ return response.json()
307
+
308
+ def exists(self, element_description: str, cdp_url: str = None):
272
309
  if not cdp_url and not self.session_id:
273
- raise ValueError(f"Must call create_session before calling action run_agent with and prompt='{prompt}'")
310
+ raise ValueError(f"Must call create_session before calling action exists with element_description='{element_description}'")
274
311
 
275
- data = {'prompt': prompt}
312
+ data = {'element_description': element_description}
276
313
 
277
314
  if cdp_url:
278
315
  data['cdp_url'] = cdp_url
@@ -280,7 +317,7 @@ class Simplex:
280
317
  data['session_id'] = self.session_id
281
318
 
282
319
  response = requests.post(
283
- f"{BASE_URL}/run-agent",
320
+ f"{BASE_URL}/exists",
284
321
  headers={
285
322
  'x-api-key': self.api_key
286
323
  },
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: simplex
3
- Version: 1.2.10
3
+ Version: 1.2.12
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=1mbM4XUk0FNW161WOkM4ayC1s_QSsaBEls6PZ0iBScY,74
2
+ simplex/cli.py,sha256=yirCLDIF7u0d6LIDY2WWZ5IJJrlxdNsGv9B3H8nh34U,2643
3
+ simplex/simplex.py,sha256=B6IJ1Ua0wLNXZDmEOkDN-WvXtPZmXS5VOgKb48KLB9I,9784
4
+ simplex/deploy/__init__.py,sha256=_JQ81F_Nu7hSAfMA691gzs6a4-8oZ-buJ9h3Au12BKw,96
5
+ simplex/deploy/push.py,sha256=hRAbtFZaECKnBljaOLQ5nzJ6hk7tZgc1c7QdgxKQFoY,6123
6
+ simplex-1.2.12.dist-info/LICENSE,sha256=Xh0SJjYZfNI71pCNMB40aKlBLLuOB0blx5xkTtufFNQ,1075
7
+ simplex-1.2.12.dist-info/METADATA,sha256=-CnNY6j8ZYWSiPUdvFXnDAkXXxxeDJbdRX1qSl7leH0,1350
8
+ simplex-1.2.12.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
9
+ simplex-1.2.12.dist-info/entry_points.txt,sha256=3veL2w3c5vxb3dm8I_M8Fs-370n1ZnvD8uu1nSsL7z8,45
10
+ simplex-1.2.12.dist-info/top_level.txt,sha256=cbMH1bYpN0A3gP-ecibPRHasHoqB-01T_2BUFS8p0CE,8
11
+ simplex-1.2.12.dist-info/RECORD,,
@@ -1,11 +0,0 @@
1
- simplex/__init__.py,sha256=1mbM4XUk0FNW161WOkM4ayC1s_QSsaBEls6PZ0iBScY,74
2
- simplex/cli.py,sha256=PkHt3sBKYfu0Smil4aCMoZUD-JbPw8xsBewpFcBYDKM,675
3
- simplex/simplex.py,sha256=wXys677gzVGlsPPdILNJi03mjNKo6fOfyGntD4Pa3Gg,8624
4
- simplex/deploy/__init__.py,sha256=_JQ81F_Nu7hSAfMA691gzs6a4-8oZ-buJ9h3Au12BKw,96
5
- simplex/deploy/push.py,sha256=8OkZ8a5vIPiTQ7YJIhxbz88uJDT6lLqyMaodlWqCTnE,6784
6
- simplex-1.2.10.dist-info/LICENSE,sha256=Xh0SJjYZfNI71pCNMB40aKlBLLuOB0blx5xkTtufFNQ,1075
7
- simplex-1.2.10.dist-info/METADATA,sha256=MCHKqhqD05skyOJhHTv0Dc7Jvh9JvX3qzmVKqgBScyc,1350
8
- simplex-1.2.10.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
9
- simplex-1.2.10.dist-info/entry_points.txt,sha256=3veL2w3c5vxb3dm8I_M8Fs-370n1ZnvD8uu1nSsL7z8,45
10
- simplex-1.2.10.dist-info/top_level.txt,sha256=cbMH1bYpN0A3gP-ecibPRHasHoqB-01T_2BUFS8p0CE,8
11
- simplex-1.2.10.dist-info/RECORD,,