smooth-py 0.2.4__tar.gz → 0.2.5.dev20250922__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 smooth-py might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: smooth-py
3
- Version: 0.2.4
3
+ Version: 0.2.5.dev20250922
4
4
  Summary:
5
5
  Author: Luca Pinchetti
6
6
  Author-email: luca@circlemind.co
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "smooth-py"
3
- version = "0.2.4"
3
+ version = "0.2.5.dev20250922"
4
4
  description = ""
5
5
  authors = [
6
6
  {name = "Luca Pinchetti",email = "luca@circlemind.co"}
@@ -6,6 +6,7 @@ import logging
6
6
  import os
7
7
  import time
8
8
  import urllib.parse
9
+ from pathlib import Path
9
10
  from typing import Any, Literal, Type
10
11
 
11
12
  import httpx
@@ -60,7 +61,7 @@ class TaskRequest(BaseModel):
60
61
  default=None, description="A dictionary containing variables or parameters that will be passed to the agent."
61
62
  )
62
63
  files: list[str] | None = Field(
63
- default=None, description="A dictionary of file ids to pass to the agent."
64
+ default=None, description="A list of file ids to pass to the agent."
64
65
  )
65
66
  agent: Literal["smooth"] = Field(default="smooth", description="The agent to use for the task.")
66
67
  max_steps: int = Field(default=32, ge=2, le=128, description="Maximum number of steps the agent can take (min 2, max 128).")
@@ -151,7 +152,7 @@ class BaseClient:
151
152
  self.base_url = f"{base_url.rstrip('/')}/{api_version}"
152
153
  self.headers = {
153
154
  "apikey": self.api_key,
154
- "User-Agent": "smooth-python-sdk/0.2.4",
155
+ "User-Agent": "smooth-python-sdk/0.2.5",
155
156
  }
156
157
 
157
158
  def _handle_response(self, response: requests.Response | httpx.Response) -> dict[str, Any]:
@@ -416,12 +417,13 @@ class SmoothClient(BaseClient):
416
417
  logger.error(f"Request failed: {e}")
417
418
  raise ApiError(status_code=0, detail=f"Request failed: {str(e)}") from None
418
419
 
419
- def upload_file(self, file: io.IOBase, name: str) -> UploadFileResponse:
420
+ def upload_file(self, file: io.IOBase, name: str | None = None, purpose: str | None = None) -> UploadFileResponse:
420
421
  """Upload a file and return the file ID.
421
422
 
422
423
  Args:
423
424
  file: File object to be uploaded.
424
- name: The name to assign to the uploaded file.
425
+ name: A custom name to assign to the uploaded file.
426
+ purpose: An optional short description of the file to describe its purpose.
425
427
 
426
428
  Returns:
427
429
  The file ID assigned to the uploaded file.
@@ -431,10 +433,21 @@ class SmoothClient(BaseClient):
431
433
  ApiError: If the API request fails.
432
434
  """
433
435
  try:
436
+ name = name or getattr(file, "name", None)
437
+ if name is None:
438
+ raise ValueError("File name must be provided or the file object must have a 'name' attribute.")
439
+
440
+ if purpose:
441
+ data = {
442
+ "file_purpose": purpose
443
+ }
444
+ else:
445
+ data = None
446
+
434
447
  files = {
435
- "file": (name, file)
448
+ "file": (Path(name).name, file)
436
449
  }
437
- response = self._session.post(f"{self.base_url}/file", files=files)
450
+ response = self._session.post(f"{self.base_url}/file", files=files, data=data)
438
451
  data = self._handle_response(response)
439
452
  return UploadFileResponse(**data["r"])
440
453
  except requests.exceptions.RequestException as e:
@@ -673,12 +686,13 @@ class SmoothAsyncClient(BaseClient):
673
686
  logger.error(f"Request failed: {e}")
674
687
  raise ApiError(status_code=0, detail=f"Request failed: {str(e)}") from None
675
688
 
676
- async def upload_file(self, file: io.IOBase, name: str) -> UploadFileResponse:
689
+ async def upload_file(self, file: io.IOBase, name: str | None = None, purpose: str | None = None) -> UploadFileResponse:
677
690
  """Upload a file and return the file ID.
678
691
 
679
692
  Args:
680
693
  file: File object to be uploaded.
681
- name: The name to assign to the uploaded file.
694
+ name: A custom name to assign to the uploaded file.
695
+ purpose: An optional short description of the file to describe its purpose.
682
696
 
683
697
  Returns:
684
698
  The file ID assigned to the uploaded file.
@@ -688,10 +702,20 @@ class SmoothAsyncClient(BaseClient):
688
702
  ApiError: If the API request fails.
689
703
  """
690
704
  try:
705
+ name = name or getattr(file, "name", None)
706
+ if name is None:
707
+ raise ValueError("File name must be provided or the file object must have a 'name' attribute.")
708
+
691
709
  files = {
692
- "file": (name, file)
710
+ "file": (Path(name).name, file)
693
711
  }
694
- response = await self._client.post(f"{self.base_url}/file", files=files)
712
+ if purpose:
713
+ data = {
714
+ "file_purpose": purpose
715
+ }
716
+ else:
717
+ data = None
718
+ response = await self._client.post(f"{self.base_url}/file", files=files, data=data)
695
719
  data = self._handle_response(response)
696
720
  return UploadFileResponse(**data["r"])
697
721
  except httpx.RequestError as e: