smooth-py 0.2.8.dev20251008__py3-none-any.whl → 0.3.0.dev20251009__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 +39 -20
- {smooth_py-0.2.8.dev20251008.dist-info → smooth_py-0.3.0.dev20251009.dist-info}/METADATA +1 -1
- smooth_py-0.3.0.dev20251009.dist-info/RECORD +6 -0
- smooth_py-0.2.8.dev20251008.dist-info/RECORD +0 -6
- {smooth_py-0.2.8.dev20251008.dist-info → smooth_py-0.3.0.dev20251009.dist-info}/WHEEL +0 -0
smooth/__init__.py
CHANGED
|
@@ -13,13 +13,13 @@ from typing import Any, Literal, Type
|
|
|
13
13
|
import httpx
|
|
14
14
|
import requests
|
|
15
15
|
from deprecated import deprecated
|
|
16
|
-
from pydantic import BaseModel, ConfigDict, Field, model_validator
|
|
16
|
+
from pydantic import BaseModel, ConfigDict, Field, computed_field, model_validator
|
|
17
17
|
|
|
18
18
|
# Configure logging
|
|
19
19
|
logger = logging.getLogger("smooth")
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
BASE_URL = "https://
|
|
22
|
+
BASE_URL = "https://api.smooth.sh/api/"
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
# --- Utils ---
|
|
@@ -100,11 +100,12 @@ class TaskRequest(BaseModel):
|
|
|
100
100
|
@model_validator(mode="before")
|
|
101
101
|
@classmethod
|
|
102
102
|
def _handle_deprecated_session_id(cls, data: Any) -> Any:
|
|
103
|
-
if isinstance(data, dict) and "session_id" in data:
|
|
103
|
+
if isinstance(data, dict) and "session_id" in data and "profile_id" not in data:
|
|
104
104
|
warnings.warn("'session_id' is deprecated, use 'profile_id' instead", DeprecationWarning, stacklevel=2)
|
|
105
105
|
data["profile_id"] = data.pop("session_id")
|
|
106
106
|
return data
|
|
107
107
|
|
|
108
|
+
@computed_field(return_type=str | None)
|
|
108
109
|
@property
|
|
109
110
|
def session_id(self):
|
|
110
111
|
"""(Deprecated) Returns the session ID."""
|
|
@@ -137,11 +138,12 @@ class BrowserSessionRequest(BaseModel):
|
|
|
137
138
|
@model_validator(mode="before")
|
|
138
139
|
@classmethod
|
|
139
140
|
def _handle_deprecated_session_id(cls, data: Any) -> Any:
|
|
140
|
-
if isinstance(data, dict) and "session_id" in data:
|
|
141
|
+
if isinstance(data, dict) and "session_id" in data and "profile_id" not in data:
|
|
141
142
|
warnings.warn("'session_id' is deprecated, use 'profile_id' instead", DeprecationWarning, stacklevel=2)
|
|
142
143
|
data["profile_id"] = data.pop("session_id")
|
|
143
144
|
return data
|
|
144
145
|
|
|
146
|
+
@computed_field(return_type=str | None)
|
|
145
147
|
@property
|
|
146
148
|
def session_id(self):
|
|
147
149
|
"""(Deprecated) Returns the session ID."""
|
|
@@ -173,11 +175,12 @@ class BrowserSessionResponse(BaseModel):
|
|
|
173
175
|
@model_validator(mode="before")
|
|
174
176
|
@classmethod
|
|
175
177
|
def _handle_deprecated_session_id(cls, data: Any) -> Any:
|
|
176
|
-
if isinstance(data, dict) and "session_id" in data:
|
|
178
|
+
if isinstance(data, dict) and "session_id" in data and "profile_id" not in data:
|
|
177
179
|
warnings.warn("'session_id' is deprecated, use 'profile_id' instead", DeprecationWarning, stacklevel=2)
|
|
178
180
|
data["profile_id"] = data.pop("session_id")
|
|
179
181
|
return data
|
|
180
182
|
|
|
183
|
+
@computed_field(return_type=str | None)
|
|
181
184
|
@property
|
|
182
185
|
def session_id(self):
|
|
183
186
|
"""(Deprecated) Returns the session ID."""
|
|
@@ -190,14 +193,6 @@ class BrowserSessionResponse(BaseModel):
|
|
|
190
193
|
warnings.warn("'session_id' is deprecated, use 'profile_id' instead", DeprecationWarning, stacklevel=2)
|
|
191
194
|
self.profile_id = value
|
|
192
195
|
|
|
193
|
-
def model_dump(self, **kwargs) -> dict[str, Any]:
|
|
194
|
-
"""Dump model to dict, including deprecated session_id for retrocompatibility."""
|
|
195
|
-
data = super().model_dump(**kwargs)
|
|
196
|
-
# Add deprecated session_id field for retrocompatibility
|
|
197
|
-
if "profile_id" in data:
|
|
198
|
-
data["session_id"] = data["profile_id"]
|
|
199
|
-
return data
|
|
200
|
-
|
|
201
196
|
|
|
202
197
|
class BrowserProfilesResponse(BaseModel):
|
|
203
198
|
"""Response model for listing browser profiles."""
|
|
@@ -207,11 +202,12 @@ class BrowserProfilesResponse(BaseModel):
|
|
|
207
202
|
@model_validator(mode="before")
|
|
208
203
|
@classmethod
|
|
209
204
|
def _handle_deprecated_session_ids(cls, data: Any) -> Any:
|
|
210
|
-
if isinstance(data, dict) and "session_ids" in data:
|
|
205
|
+
if isinstance(data, dict) and "session_ids" in data and "profile_ids" not in data:
|
|
211
206
|
warnings.warn("'session_ids' is deprecated, use 'profile_ids' instead", DeprecationWarning, stacklevel=2)
|
|
212
207
|
data["profile_ids"] = data.pop("session_ids")
|
|
213
208
|
return data
|
|
214
209
|
|
|
210
|
+
@computed_field(return_type=list[str])
|
|
215
211
|
@property
|
|
216
212
|
def session_ids(self):
|
|
217
213
|
"""(Deprecated) Returns the session IDs."""
|
|
@@ -351,12 +347,7 @@ class TaskHandle:
|
|
|
351
347
|
|
|
352
348
|
def stop(self):
|
|
353
349
|
"""Stops the task."""
|
|
354
|
-
|
|
355
|
-
response = self._client._client.delete(f"{self._client.base_url}/task/{self._id}")
|
|
356
|
-
self._handle_response(response)
|
|
357
|
-
except requests.exceptions.RequestException as e:
|
|
358
|
-
logger.error(f"Request failed: {e}")
|
|
359
|
-
raise ApiError(status_code=0, detail=f"Request failed: {str(e)}") from None
|
|
350
|
+
self._client._delete_task(self._id)
|
|
360
351
|
|
|
361
352
|
def result(self, timeout: int | None = None, poll_interval: float = 1) -> TaskResponse:
|
|
362
353
|
"""Waits for the task to complete and returns the result."""
|
|
@@ -452,6 +443,18 @@ class SmoothClient(BaseClient):
|
|
|
452
443
|
logger.error(f"Request failed: {e}")
|
|
453
444
|
raise ApiError(status_code=0, detail=f"Request failed: {str(e)}") from None
|
|
454
445
|
|
|
446
|
+
def _delete_task(self, task_id: str):
|
|
447
|
+
"""Deletes a task."""
|
|
448
|
+
if not task_id:
|
|
449
|
+
raise ValueError("Task ID cannot be empty.")
|
|
450
|
+
|
|
451
|
+
try:
|
|
452
|
+
response = self._session.delete(f"{self.base_url}/task/{task_id}")
|
|
453
|
+
self._handle_response(response)
|
|
454
|
+
except requests.exceptions.RequestException as e:
|
|
455
|
+
logger.error(f"Request failed: {e}")
|
|
456
|
+
raise ApiError(status_code=0, detail=f"Request failed: {str(e)}") from None
|
|
457
|
+
|
|
455
458
|
def run(
|
|
456
459
|
self,
|
|
457
460
|
task: str,
|
|
@@ -660,6 +663,10 @@ class AsyncTaskHandle:
|
|
|
660
663
|
"""Returns the task ID."""
|
|
661
664
|
return self._id
|
|
662
665
|
|
|
666
|
+
async def stop(self):
|
|
667
|
+
"""Stops the task."""
|
|
668
|
+
await self._client._delete_task(self._id)
|
|
669
|
+
|
|
663
670
|
async def result(self, timeout: int | None = None, poll_interval: float = 1) -> TaskResponse:
|
|
664
671
|
"""Waits for the task to complete and returns the result."""
|
|
665
672
|
if self._task_response and self._task_response.status not in ["running", "waiting"]:
|
|
@@ -749,6 +756,18 @@ class SmoothAsyncClient(BaseClient):
|
|
|
749
756
|
logger.error(f"Request failed: {e}")
|
|
750
757
|
raise ApiError(status_code=0, detail=f"Request failed: {str(e)}") from None
|
|
751
758
|
|
|
759
|
+
async def _delete_task(self, task_id: str):
|
|
760
|
+
"""Deletes a task asynchronously."""
|
|
761
|
+
if not task_id:
|
|
762
|
+
raise ValueError("Task ID cannot be empty.")
|
|
763
|
+
|
|
764
|
+
try:
|
|
765
|
+
response = await self._client.delete(f"{self.base_url}/task/{task_id}")
|
|
766
|
+
self._handle_response(response)
|
|
767
|
+
except httpx.RequestError as e:
|
|
768
|
+
logger.error(f"Request failed: {e}")
|
|
769
|
+
raise ApiError(status_code=0, detail=f"Request failed: {str(e)}") from None
|
|
770
|
+
|
|
752
771
|
async def run(
|
|
753
772
|
self,
|
|
754
773
|
task: str,
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
smooth/__init__.py,sha256=0dn5X327eZwSdXklCCV4KN9L9-353GtmzaqjNs9_HeQ,38407
|
|
2
|
+
smooth/mcp/__init__.py,sha256=0aJVFi2a8Ah3-5xtgyZ5UMbaaJsBWu2T8QLWoFQITk8,219
|
|
3
|
+
smooth/mcp/server.py,sha256=9SymTD4NOGTMN8P-LNGlvYNvv81yCIZfZeeuhEcAc6s,20068
|
|
4
|
+
smooth_py-0.3.0.dev20251009.dist-info/METADATA,sha256=cQ0TzuWCfXke3Rf7Zrp01lPUypKpOc2AB2tSQAx-wf8,7529
|
|
5
|
+
smooth_py-0.3.0.dev20251009.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
6
|
+
smooth_py-0.3.0.dev20251009.dist-info/RECORD,,
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
smooth/__init__.py,sha256=UFvVVla_T5EiOYimpxKQs0D24-F0ZZyRnl1hpJ8YohA,37737
|
|
2
|
-
smooth/mcp/__init__.py,sha256=0aJVFi2a8Ah3-5xtgyZ5UMbaaJsBWu2T8QLWoFQITk8,219
|
|
3
|
-
smooth/mcp/server.py,sha256=9SymTD4NOGTMN8P-LNGlvYNvv81yCIZfZeeuhEcAc6s,20068
|
|
4
|
-
smooth_py-0.2.8.dev20251008.dist-info/METADATA,sha256=Ya-GED2N4TX7XU3MF0Cmy4PaWpwEF45-agZY9daW5F0,7529
|
|
5
|
-
smooth_py-0.2.8.dev20251008.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
6
|
-
smooth_py-0.2.8.dev20251008.dist-info/RECORD,,
|
|
File without changes
|