smooth-py 0.1.3__py3-none-any.whl → 0.1.3.post0__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 smooth-py might be problematic. Click here for more details.
smooth/__init__.py
CHANGED
|
@@ -154,51 +154,65 @@ class BaseClient:
|
|
|
154
154
|
class TaskHandle:
|
|
155
155
|
"""A handle to a running task."""
|
|
156
156
|
|
|
157
|
-
def __init__(self, task_id: str, client: "SmoothClient"
|
|
157
|
+
def __init__(self, task_id: str, client: "SmoothClient"):
|
|
158
158
|
"""Initializes the task handle."""
|
|
159
159
|
self._client = client
|
|
160
|
-
self._poll_interval = poll_interval
|
|
161
|
-
self._timeout = timeout
|
|
162
160
|
self._task_response: TaskResponse | None = None
|
|
163
|
-
self._live_url = live_url
|
|
164
161
|
|
|
165
162
|
self.id = task_id
|
|
166
163
|
|
|
167
|
-
def result(self) -> TaskResponse:
|
|
164
|
+
def result(self, timeout: int | None = None, poll_interval: float = 1) -> TaskResponse:
|
|
168
165
|
"""Waits for the task to complete and returns the result."""
|
|
169
166
|
if self._task_response and self._task_response.status not in ["running", "waiting"]:
|
|
170
167
|
return self._task_response
|
|
171
168
|
|
|
169
|
+
if timeout is not None and timeout < 1:
|
|
170
|
+
raise ValueError("Timeout must be at least 1 second.")
|
|
171
|
+
if poll_interval < 0.1:
|
|
172
|
+
raise ValueError("Poll interval must be at least 100 milliseconds.")
|
|
173
|
+
|
|
172
174
|
start_time = time.time()
|
|
173
|
-
while
|
|
175
|
+
while timeout is None or (time.time() - start_time) < timeout:
|
|
174
176
|
task_response = self._client._get_task(self.id) # pyright: ignore [reportPrivateUsage]
|
|
177
|
+
self._task_response = task_response
|
|
175
178
|
if task_response.status not in ["running", "waiting"]:
|
|
176
|
-
self._task_response = task_response
|
|
177
179
|
return task_response
|
|
178
|
-
time.sleep(
|
|
179
|
-
raise TimeoutError(f"Task {self.id} did not complete within {
|
|
180
|
+
time.sleep(poll_interval)
|
|
181
|
+
raise TimeoutError(f"Task {self.id} did not complete within {timeout} seconds.")
|
|
180
182
|
|
|
181
|
-
def live_url(self, interactive: bool = True, embed: bool = False
|
|
183
|
+
def live_url(self, interactive: bool = True, embed: bool = False, timeout: int | None = None):
|
|
182
184
|
"""Returns the live URL for the task."""
|
|
183
185
|
params = {
|
|
184
186
|
"interactive": interactive,
|
|
185
187
|
"embed": embed
|
|
186
188
|
}
|
|
187
|
-
return f"{self._live_url}?{urlencode(params)}"
|
|
188
189
|
|
|
189
|
-
|
|
190
|
+
if self._task_response and self._task_response.live_url:
|
|
191
|
+
return f"{self._task_response.live_url}?{urlencode(params)}"
|
|
192
|
+
|
|
193
|
+
start_time = time.time()
|
|
194
|
+
while timeout is None or (time.time() - start_time) < timeout:
|
|
195
|
+
task_response = self._client._get_task(self.id) # pyright: ignore [reportPrivateUsage]
|
|
196
|
+
self._task_response = task_response
|
|
197
|
+
if self._task_response.live_url:
|
|
198
|
+
return f"{self._task_response.live_url}?{urlencode(params)}"
|
|
199
|
+
time.sleep(1)
|
|
200
|
+
|
|
201
|
+
raise TimeoutError(f"Live URL not available for task {self.id}.")
|
|
202
|
+
|
|
203
|
+
def recording_url(self, timeout: int | None = None) -> str:
|
|
190
204
|
"""Returns the recording URL for the task."""
|
|
191
205
|
if self._task_response and self._task_response.recording_url is not None:
|
|
192
206
|
return self._task_response.recording_url
|
|
193
207
|
|
|
194
208
|
start_time = time.time()
|
|
195
|
-
while (time.time() - start_time) <
|
|
209
|
+
while timeout is None or (time.time() - start_time) < timeout:
|
|
196
210
|
task_response = self._client._get_task(self.id) # pyright: ignore [reportPrivateUsage]
|
|
197
211
|
self._task_response = task_response
|
|
198
212
|
if task_response.recording_url is not None:
|
|
199
213
|
return task_response.recording_url
|
|
200
214
|
time.sleep(1)
|
|
201
|
-
raise TimeoutError(f"Recording not available for task {self.id}.")
|
|
215
|
+
raise TimeoutError(f"Recording URL not available for task {self.id}.")
|
|
202
216
|
|
|
203
217
|
|
|
204
218
|
class SmoothClient(BaseClient):
|
|
@@ -249,8 +263,6 @@ class SmoothClient(BaseClient):
|
|
|
249
263
|
def run(
|
|
250
264
|
self,
|
|
251
265
|
task: str,
|
|
252
|
-
poll_interval: int = 1,
|
|
253
|
-
timeout: int = 60 * 15,
|
|
254
266
|
agent: Literal["smooth"] = "smooth",
|
|
255
267
|
max_steps: int = 32,
|
|
256
268
|
device: Literal["desktop", "mobile"] = "mobile",
|
|
@@ -268,8 +280,6 @@ class SmoothClient(BaseClient):
|
|
|
268
280
|
|
|
269
281
|
Args:
|
|
270
282
|
task: The task to run.
|
|
271
|
-
poll_interval: The time in seconds to wait between polling for status.
|
|
272
|
-
timeout: The maximum time in seconds to wait for the task to complete.
|
|
273
283
|
agent: The agent to use for the task.
|
|
274
284
|
max_steps: Maximum number of steps the agent can take (max 64).
|
|
275
285
|
device: Device type for the task. Default is mobile.
|
|
@@ -286,11 +296,6 @@ class SmoothClient(BaseClient):
|
|
|
286
296
|
Raises:
|
|
287
297
|
ApiException: If the API request fails.
|
|
288
298
|
"""
|
|
289
|
-
if poll_interval < 0.1:
|
|
290
|
-
raise ValueError("Poll interval must be at least 100 milliseconds.")
|
|
291
|
-
if timeout < 1:
|
|
292
|
-
raise ValueError("Timeout must be at least 1 second.")
|
|
293
|
-
|
|
294
299
|
payload = TaskRequest(
|
|
295
300
|
task=task,
|
|
296
301
|
agent=agent,
|
|
@@ -304,12 +309,8 @@ class SmoothClient(BaseClient):
|
|
|
304
309
|
proxy_password=proxy_password,
|
|
305
310
|
)
|
|
306
311
|
initial_response = self._submit_task(payload)
|
|
307
|
-
start_time = time.time()
|
|
308
|
-
while time.time() - start_time < 16 and initial_response.live_url is None:
|
|
309
|
-
initial_response = self._get_task(initial_response.id)
|
|
310
|
-
time.sleep(poll_interval)
|
|
311
312
|
|
|
312
|
-
return TaskHandle(initial_response.id, self
|
|
313
|
+
return TaskHandle(initial_response.id, self)
|
|
313
314
|
|
|
314
315
|
def open_session(self, session_id: str | None = None) -> BrowserSessionResponse:
|
|
315
316
|
"""Gets an interactive browser instance.
|
|
@@ -367,51 +368,65 @@ class SmoothClient(BaseClient):
|
|
|
367
368
|
class AsyncTaskHandle:
|
|
368
369
|
"""An asynchronous handle to a running task."""
|
|
369
370
|
|
|
370
|
-
def __init__(self, task_id: str, client: "SmoothAsyncClient"
|
|
371
|
+
def __init__(self, task_id: str, client: "SmoothAsyncClient"):
|
|
371
372
|
"""Initializes the asynchronous task handle."""
|
|
372
373
|
self._client = client
|
|
373
|
-
self._poll_interval = poll_interval
|
|
374
|
-
self._timeout = timeout
|
|
375
|
-
self._live_url = live_url
|
|
376
374
|
self._task_response: TaskResponse | None = None
|
|
377
375
|
|
|
378
376
|
self.id = task_id
|
|
379
377
|
|
|
380
|
-
async def result(self) -> TaskResponse:
|
|
378
|
+
async def result(self, timeout: int | None = None, poll_interval: float = 1) -> TaskResponse:
|
|
381
379
|
"""Waits for the task to complete and returns the result."""
|
|
382
380
|
if self._task_response and self._task_response.status not in ["running", "waiting"]:
|
|
383
381
|
return self._task_response
|
|
384
382
|
|
|
383
|
+
if timeout is not None and timeout < 1:
|
|
384
|
+
raise ValueError("Timeout must be at least 1 second.")
|
|
385
|
+
if poll_interval < 0.1:
|
|
386
|
+
raise ValueError("Poll interval must be at least 100 milliseconds.")
|
|
387
|
+
|
|
385
388
|
start_time = time.time()
|
|
386
|
-
while
|
|
389
|
+
while timeout is None or (time.time() - start_time) < timeout:
|
|
387
390
|
task_response = await self._client._get_task(self.id) # pyright: ignore [reportPrivateUsage]
|
|
388
391
|
self._task_response = task_response
|
|
389
392
|
if task_response.status not in ["running", "waiting"]:
|
|
390
393
|
return task_response
|
|
391
|
-
await asyncio.sleep(
|
|
392
|
-
raise TimeoutError(f"Task {self.id} did not complete within {
|
|
394
|
+
await asyncio.sleep(poll_interval)
|
|
395
|
+
raise TimeoutError(f"Task {self.id} did not complete within {timeout} seconds.")
|
|
393
396
|
|
|
394
|
-
def live_url(self, interactive: bool = True, embed: bool = False
|
|
397
|
+
async def live_url(self, interactive: bool = True, embed: bool = False, timeout: int | None = None):
|
|
395
398
|
"""Returns the live URL for the task."""
|
|
396
399
|
params = {
|
|
397
400
|
"interactive": interactive,
|
|
398
401
|
"embed": embed
|
|
399
402
|
}
|
|
400
|
-
|
|
403
|
+
if self._task_response and self._task_response.live_url:
|
|
404
|
+
return f"{self._task_response.live_url}?{urlencode(params)}"
|
|
401
405
|
|
|
402
|
-
|
|
406
|
+
start_time = time.time()
|
|
407
|
+
while timeout is None or (time.time() - start_time) < timeout:
|
|
408
|
+
task_response = await self._client._get_task(self.id) # pyright: ignore [reportPrivateUsage]
|
|
409
|
+
self._task_response = task_response
|
|
410
|
+
if task_response.live_url is not None:
|
|
411
|
+
return f"{task_response.live_url}?{urlencode(params)}"
|
|
412
|
+
await asyncio.sleep(1)
|
|
413
|
+
|
|
414
|
+
raise TimeoutError(f"Live URL not available for task {self.id}.")
|
|
415
|
+
|
|
416
|
+
async def recording_url(self, timeout: int | None = None):
|
|
403
417
|
"""Returns the recording URL for the task."""
|
|
404
418
|
if self._task_response and self._task_response.recording_url is not None:
|
|
405
419
|
return self._task_response.recording_url
|
|
406
420
|
|
|
407
421
|
start_time = time.time()
|
|
408
|
-
while (time.time() - start_time) <
|
|
422
|
+
while timeout is None or (time.time() - start_time) < timeout:
|
|
409
423
|
task_response = await self._client._get_task(self.id) # pyright: ignore [reportPrivateUsage]
|
|
410
424
|
self._task_response = task_response
|
|
411
425
|
if task_response.recording_url is not None:
|
|
412
426
|
return task_response.recording_url
|
|
413
427
|
await asyncio.sleep(1)
|
|
414
|
-
|
|
428
|
+
|
|
429
|
+
raise TimeoutError(f"Recording URL not available for task {self.id}.")
|
|
415
430
|
|
|
416
431
|
class SmoothAsyncClient(BaseClient):
|
|
417
432
|
"""An asynchronous client for the API."""
|
|
@@ -464,8 +479,6 @@ class SmoothAsyncClient(BaseClient):
|
|
|
464
479
|
proxy_server: str | None = None,
|
|
465
480
|
proxy_username: str | None = None,
|
|
466
481
|
proxy_password: str | None = None,
|
|
467
|
-
poll_interval: int = 1,
|
|
468
|
-
timeout: int = 60 * 15,
|
|
469
482
|
) -> AsyncTaskHandle:
|
|
470
483
|
"""Runs a task and returns a handle to the task asynchronously.
|
|
471
484
|
|
|
@@ -492,11 +505,6 @@ class SmoothAsyncClient(BaseClient):
|
|
|
492
505
|
Raises:
|
|
493
506
|
ApiException: If the API request fails.
|
|
494
507
|
"""
|
|
495
|
-
if poll_interval < 0.1:
|
|
496
|
-
raise ValueError("Poll interval must be at least 100 milliseconds.")
|
|
497
|
-
if timeout < 1:
|
|
498
|
-
raise ValueError("Timeout must be at least 1 second.")
|
|
499
|
-
|
|
500
508
|
payload = TaskRequest(
|
|
501
509
|
task=task,
|
|
502
510
|
agent=agent,
|
|
@@ -511,11 +519,7 @@ class SmoothAsyncClient(BaseClient):
|
|
|
511
519
|
)
|
|
512
520
|
|
|
513
521
|
initial_response = await self._submit_task(payload)
|
|
514
|
-
|
|
515
|
-
while time.time() - start_time < 16 and initial_response.live_url is None:
|
|
516
|
-
initial_response = await self._get_task(initial_response.id)
|
|
517
|
-
await asyncio.sleep(poll_interval)
|
|
518
|
-
return AsyncTaskHandle(initial_response.id, self, initial_response.live_url, poll_interval, timeout)
|
|
522
|
+
return AsyncTaskHandle(initial_response.id, self)
|
|
519
523
|
|
|
520
524
|
async def open_session(self, session_id: str | None = None) -> BrowserSessionResponse:
|
|
521
525
|
"""Opens an interactive browser instance asynchronously.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
smooth/__init__.py,sha256=jIEM1usuwrZWq-m1YgsUsLCkvUkhS9BNqgFc3HUPEvw,21263
|
|
2
|
+
smooth_py-0.1.3.post0.dist-info/METADATA,sha256=x4u365t5CvrRvMPsrCrLy2sVNT4ojf8nK8pdntodEdw,5394
|
|
3
|
+
smooth_py-0.1.3.post0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
4
|
+
smooth_py-0.1.3.post0.dist-info/RECORD,,
|
smooth_py-0.1.3.dist-info/RECORD
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
smooth/__init__.py,sha256=dmofDTp_gE9sHBG3ZrCgApWQKtJn7a4MTOWuzxG6f_A,21078
|
|
2
|
-
smooth_py-0.1.3.dist-info/METADATA,sha256=DiTe2Cg4TNmJGCGX_qHOhrKYzwHzvKWIxYIq3Yrqi9w,5388
|
|
3
|
-
smooth_py-0.1.3.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
4
|
-
smooth_py-0.1.3.dist-info/RECORD,,
|
|
File without changes
|