simile 0.4.5__tar.gz → 0.5.4__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: simile
3
- Version: 0.4.5
3
+ Version: 0.5.4
4
4
  Summary: Package for interfacing with Simile AI agents for simulation
5
5
  Author-email: Simile AI <cqz@simile.ai>
6
6
  License: MIT
@@ -49,15 +49,11 @@ client = Simile(api_key="your_api_key")
49
49
 
50
50
  ## Publishing
51
51
 
52
- First, bump the version in `pyproject.toml`. Then, create the distribution files:
53
- ```bash
54
- python3 -m build
55
- ```
56
-
57
- Afterwards, use [Twine](https://pypi.org/project/twine/) to upload the package:
58
- ```bash
59
- pip install twine
60
- twine upload dist/*
61
- ```
52
+ 1. Bump the version in `pyproject.toml`
53
+ 2. Commit and push your changes
54
+ 3. Go to the **Actions** tab in GitHub
55
+ 4. Select **Build and Publish to PyPI** workflow
56
+ 5. Click **Run workflow** and select the branch to run from
57
+ 6. The workflow will automatically build and publish to PyPI
62
58
 
63
- If you need the PyPI credentials, please ask Carolyn or Chris.
59
+ The workflow uses the `PYPI_API_TOKEN` secret configured in the repository settings.
simile-0.5.4/README.md ADDED
@@ -0,0 +1,33 @@
1
+ # Simile API Python Client
2
+
3
+ A Python client for interacting with the Simile API server.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install simile
9
+ ```
10
+
11
+ ## Dependencies
12
+
13
+ - `httpx>=0.20.0`
14
+ - `pydantic>=2.0.0`
15
+
16
+ ## Usage
17
+
18
+ ```python
19
+ from simile import Simile
20
+
21
+ client = Simile(api_key="your_api_key")
22
+ ```
23
+
24
+ ## Publishing
25
+
26
+ 1. Bump the version in `pyproject.toml`
27
+ 2. Commit and push your changes
28
+ 3. Go to the **Actions** tab in GitHub
29
+ 4. Select **Build and Publish to PyPI** workflow
30
+ 5. Click **Run workflow** and select the branch to run from
31
+ 6. The workflow will automatically build and publish to PyPI
32
+
33
+ The workflow uses the `PYPI_API_TOKEN` secret configured in the repository settings.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "simile"
7
- version = "0.4.5"
7
+ version = "0.5.4"
8
8
  authors = [
9
9
  { name="Simile AI", email="cqz@simile.ai" },
10
10
  ]
@@ -34,3 +34,37 @@ dependencies = [
34
34
 
35
35
  [project.urls]
36
36
  "Homepage" = "https://github.com/simile-team/simile-sdk"
37
+
38
+ [tool.ruff]
39
+ # Set the maximum line length to 100 (default is 88)
40
+ line-length = 100
41
+ target-version = "py311"
42
+
43
+ [tool.ruff.lint]
44
+ # Enable a comprehensive set of rules
45
+ select = [
46
+ "E", # pycodestyle errors
47
+ "W", # pycodestyle warnings
48
+ "F", # pyflakes
49
+ "I", # isort
50
+ "B", # flake8-bugbear
51
+ "C4", # flake8-comprehensions
52
+ "UP", # pyupgrade
53
+ "ARG", # flake8-unused-arguments
54
+ "SIM", # flake8-simplify
55
+ ]
56
+ ignore = [
57
+ "E501", # line too long (handled by formatter)
58
+ "B008", # do not perform function calls in argument defaults
59
+ "B006", # do not use mutable data structures for argument defaults
60
+ ]
61
+
62
+ [tool.ruff.lint.per-file-ignores]
63
+ "__init__.py" = ["F401"] # Allow unused imports in __init__.py
64
+ "examples/*" = ["E501"] # Allow long lines in examples
65
+
66
+ [tool.ruff.format]
67
+ # Use double quotes for strings
68
+ quote-style = "double"
69
+ # Indent with spaces
70
+ indent-style = "space"
@@ -1,32 +1,32 @@
1
- from .client import Simile
2
1
  from .auth_client import SimileAuth
2
+ from .client import Simile
3
+ from .exceptions import (
4
+ SimileAPIError,
5
+ SimileAuthenticationError,
6
+ SimileBadRequestError,
7
+ SimileNotFoundError,
8
+ )
3
9
  from .models import (
4
- Population,
5
10
  Agent,
6
- DataItem,
7
- PopulationInfo,
8
- CreatePopulationPayload,
11
+ ClosedGenerationRequest,
12
+ ClosedGenerationResponse,
13
+ ClosedQuestionMemoryTurn,
14
+ ContextMemoryTurn,
9
15
  CreateAgentPayload,
10
16
  CreateDataItemPayload,
11
- UpdateDataItemPayload,
17
+ CreatePopulationPayload,
18
+ DataItem,
12
19
  DeletionResponse,
13
- OpenGenerationRequest,
14
- OpenGenerationResponse,
15
- ClosedGenerationRequest,
16
- ClosedGenerationResponse,
20
+ ImageMemoryTurn,
17
21
  MemoryStream,
18
22
  MemoryTurn,
19
23
  MemoryTurnType,
20
- ContextMemoryTurn,
21
- ImageMemoryTurn,
24
+ OpenGenerationRequest,
25
+ OpenGenerationResponse,
22
26
  OpenQuestionMemoryTurn,
23
- ClosedQuestionMemoryTurn,
24
- )
25
- from .exceptions import (
26
- SimileAPIError,
27
- SimileAuthenticationError,
28
- SimileNotFoundError,
29
- SimileBadRequestError,
27
+ Population,
28
+ PopulationInfo,
29
+ UpdateDataItemPayload,
30
30
  )
31
31
 
32
32
  __all__ = [
@@ -58,4 +58,4 @@ __all__ = [
58
58
  "SimileBadRequestError",
59
59
  ]
60
60
 
61
- __version__ = "0.2.15"
61
+ __version__ = "0.5.5"
@@ -5,19 +5,19 @@ This client handles authentication-related operations using Google OAuth tokens
5
5
  rather than API keys.
6
6
  """
7
7
 
8
- import httpx
9
- from httpx import AsyncClient
10
- from typing import List, Optional, Union
11
8
  import uuid
12
9
  from datetime import datetime
13
10
 
14
- from .models import BaseModel
11
+ import httpx
12
+ from httpx import AsyncClient
13
+
15
14
  from .exceptions import (
16
15
  SimileAPIError,
17
16
  SimileAuthenticationError,
18
- SimileNotFoundError,
19
17
  SimileBadRequestError,
18
+ SimileNotFoundError,
20
19
  )
20
+ from .models import BaseModel
21
21
 
22
22
 
23
23
  # Import the models from auth_api_endpoints
@@ -28,7 +28,7 @@ class UserInfo(BaseModel):
28
28
  user_id: str
29
29
  email: str
30
30
  name: str
31
- picture: Optional[str] = None
31
+ picture: str | None = None
32
32
  created_at: datetime
33
33
  last_login: datetime
34
34
 
@@ -40,8 +40,8 @@ class APIKey(BaseModel):
40
40
  name: str
41
41
  key_prefix: str
42
42
  created_at: datetime
43
- last_used: Optional[datetime] = None
44
- expires_at: Optional[datetime] = None
43
+ last_used: datetime | None = None
44
+ expires_at: datetime | None = None
45
45
  is_active: bool = True
46
46
 
47
47
 
@@ -53,7 +53,7 @@ class APIKeyCreateResponse(BaseModel):
53
53
  key: str
54
54
  key_prefix: str
55
55
  created_at: datetime
56
- expires_at: Optional[datetime] = None
56
+ expires_at: datetime | None = None
57
57
 
58
58
 
59
59
  class PopulationAccess(BaseModel):
@@ -61,7 +61,7 @@ class PopulationAccess(BaseModel):
61
61
 
62
62
  population_id: uuid.UUID
63
63
  name: str
64
- description: Optional[str] = None
64
+ description: str | None = None
65
65
  role: str
66
66
  created_at: datetime
67
67
  member_count: int
@@ -75,7 +75,7 @@ class PopulationShareResponse(BaseModel):
75
75
  population_id: uuid.UUID
76
76
  role: str
77
77
  expires_at: datetime
78
- max_uses: Optional[int] = None
78
+ max_uses: int | None = None
79
79
  created_at: datetime
80
80
 
81
81
 
@@ -84,7 +84,7 @@ class PopulationJoinResponse(BaseModel):
84
84
 
85
85
  population_id: uuid.UUID
86
86
  name: str
87
- description: Optional[str] = None
87
+ description: str | None = None
88
88
  role: str
89
89
  message: str = "Successfully joined population"
90
90
 
@@ -118,9 +118,7 @@ class SimileAuth:
118
118
  timeout=TIMEOUT_CONFIG,
119
119
  )
120
120
 
121
- async def _request(
122
- self, method: str, endpoint: str, **kwargs
123
- ) -> Union[httpx.Response, BaseModel]:
121
+ async def _request(self, method: str, endpoint: str, **kwargs) -> httpx.Response | BaseModel:
124
122
  """Make an HTTP request to the API."""
125
123
  url = f"{self.base_url}/{endpoint.lstrip('/')}"
126
124
  response_model_cls = kwargs.pop("response_model", None)
@@ -142,30 +140,30 @@ class SimileAuth:
142
140
  detail = e.response.text
143
141
 
144
142
  if status_code == 401:
145
- raise SimileAuthenticationError(detail=detail)
143
+ raise SimileAuthenticationError(detail=detail) from e
146
144
  elif status_code == 404:
147
- raise SimileNotFoundError(detail=detail)
145
+ raise SimileNotFoundError(detail=detail) from e
148
146
  elif status_code == 400:
149
- raise SimileBadRequestError(detail=detail)
147
+ raise SimileBadRequestError(detail=detail) from e
150
148
  else:
151
149
  raise SimileAPIError(
152
150
  f"API request failed: {e}", status_code=status_code, detail=detail
153
- )
151
+ ) from e
154
152
  except httpx.RequestError as e:
155
- raise SimileAPIError(f"Request error: {type(e).__name__}: {e}")
153
+ raise SimileAPIError(f"Request error: {type(e).__name__}: {e}") from e
156
154
 
157
155
  async def get_current_user(self) -> UserInfo:
158
156
  """Get current user information."""
159
157
  response = await self._request("GET", "auth/me", response_model=UserInfo)
160
158
  return response
161
159
 
162
- async def list_api_keys(self) -> List[APIKey]:
160
+ async def list_api_keys(self) -> list[APIKey]:
163
161
  """List all API keys for the current user."""
164
162
  response = await self._request("GET", "auth/api-keys")
165
163
  return [APIKey(**key_data) for key_data in response.json()]
166
164
 
167
165
  async def create_api_key(
168
- self, name: str, expires_in_days: Optional[int] = None
166
+ self, name: str, expires_in_days: int | None = None
169
167
  ) -> APIKeyCreateResponse:
170
168
  """
171
169
  Create a new API key.
@@ -186,7 +184,7 @@ class SimileAuth:
186
184
  )
187
185
  return response
188
186
 
189
- async def delete_api_key(self, key_id: Union[str, uuid.UUID]) -> dict:
187
+ async def delete_api_key(self, key_id: str | uuid.UUID) -> dict:
190
188
  """
191
189
  Delete an API key.
192
190
 
@@ -199,17 +197,17 @@ class SimileAuth:
199
197
  response = await self._request("DELETE", f"auth/api-keys/{str(key_id)}")
200
198
  return response.json()
201
199
 
202
- async def list_accessible_populations(self) -> List[PopulationAccess]:
200
+ async def list_accessible_populations(self) -> list[PopulationAccess]:
203
201
  """List all populations the current user has access to."""
204
202
  response = await self._request("GET", "auth/populations")
205
203
  return [PopulationAccess(**pop_data) for pop_data in response.json()]
206
204
 
207
205
  async def create_population_share_code(
208
206
  self,
209
- population_id: Union[str, uuid.UUID],
207
+ population_id: str | uuid.UUID,
210
208
  role: str = "viewer",
211
- expires_in_hours: Optional[int] = 24,
212
- max_uses: Optional[int] = None,
209
+ expires_in_hours: int | None = 24,
210
+ max_uses: int | None = None,
213
211
  ) -> PopulationShareResponse:
214
212
  """
215
213
  Create a share code for a population.
@@ -239,9 +237,7 @@ class SimileAuth:
239
237
  )
240
238
  return response
241
239
 
242
- async def join_population_with_share_code(
243
- self, share_code: str
244
- ) -> PopulationJoinResponse:
240
+ async def join_population_with_share_code(self, share_code: str) -> PopulationJoinResponse:
245
241
  """
246
242
  Join a population using a share code.
247
243