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 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://api2.circlemind.co/api/"
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
- try:
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,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: smooth-py
3
- Version: 0.2.8.dev20251008
3
+ Version: 0.3.0.dev20251009
4
4
  Summary:
5
5
  Author: Luca Pinchetti
6
6
  Author-email: luca@circlemind.co
@@ -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,,