simile 0.2.6__py3-none-any.whl → 0.2.8__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 simile might be problematic. Click here for more details.

simile/client.py CHANGED
@@ -5,21 +5,34 @@ import uuid
5
5
  from pydantic import BaseModel
6
6
 
7
7
  from .models import (
8
- Population, Agent as AgentModel, DataItem, DeletionResponse,
9
- QualGenerationRequest, QualGenerationResponse,
10
- MCGenerationRequest, MCGenerationResponse,
11
- CreatePopulationPayload, CreateAgentPayload, CreateDataItemPayload, UpdateDataItemPayload,
8
+ Population,
9
+ Agent as AgentModel,
10
+ DataItem,
11
+ DeletionResponse,
12
+ QualGenerationRequest,
13
+ QualGenerationResponse,
14
+ MCGenerationRequest,
15
+ MCGenerationResponse,
16
+ CreatePopulationPayload,
17
+ CreateAgentPayload,
18
+ CreateDataItemPayload,
19
+ UpdateDataItemPayload,
12
20
  InitialDataItemPayload,
13
- SurveySessionCreateResponse
21
+ SurveySessionCreateResponse,
22
+ SurveySessionDetailResponse,
14
23
  )
15
24
  from .resources import Agent, SurveySession
16
25
  from .exceptions import (
17
- SimileAPIError, SimileAuthenticationError, SimileNotFoundError, SimileBadRequestError
26
+ SimileAPIError,
27
+ SimileAuthenticationError,
28
+ SimileNotFoundError,
29
+ SimileBadRequestError,
18
30
  )
19
31
 
20
32
  DEFAULT_BASE_URL = "https://simile-api-3a83be7adae0.herokuapp.com/api/v1"
21
33
  TIMEOUT_CONFIG = httpx.Timeout(5.0, read=30.0, write=30.0, pool=30.0)
22
34
 
35
+
23
36
  class Simile:
24
37
  APIError = SimileAPIError
25
38
  AuthenticationError = SimileAuthenticationError
@@ -30,16 +43,19 @@ class Simile:
30
43
  if not api_key:
31
44
  raise ValueError("API key is required.")
32
45
  self.api_key = api_key
33
- self.base_url = base_url.rstrip('/')
46
+ self.base_url = base_url.rstrip("/")
34
47
  self._client = AsyncClient(
35
- headers={"X-API-Key": self.api_key},
36
- timeout=TIMEOUT_CONFIG
48
+ headers={"X-API-Key": self.api_key}, timeout=TIMEOUT_CONFIG
37
49
  )
38
50
 
39
- async def _request(self, method: str, endpoint: str, **kwargs) -> Union[httpx.Response, BaseModel]:
51
+ async def _request(
52
+ self, method: str, endpoint: str, **kwargs
53
+ ) -> Union[httpx.Response, BaseModel]:
40
54
  url = f"{self.base_url}/{endpoint.lstrip('/')}"
41
- response_model_cls: Optional[Type[BaseModel]] = kwargs.pop("response_model", None)
42
-
55
+ response_model_cls: Optional[Type[BaseModel]] = kwargs.pop(
56
+ "response_model", None
57
+ )
58
+
43
59
  try:
44
60
  response = await self._client.request(method, url, **kwargs)
45
61
  response.raise_for_status()
@@ -63,7 +79,9 @@ class Simile:
63
79
  elif status_code == 400:
64
80
  raise SimileBadRequestError(detail=detail)
65
81
  else:
66
- raise SimileAPIError(f"API request failed: {e}", status_code=status_code, detail=detail)
82
+ raise SimileAPIError(
83
+ f"API request failed: {e}", status_code=status_code, detail=detail
84
+ )
67
85
  except httpx.ConnectTimeout:
68
86
  raise SimileAPIError("Connection timed out while trying to connect.")
69
87
  except httpx.ReadTimeout:
@@ -79,7 +97,9 @@ class Simile:
79
97
  except httpx.DecodingError:
80
98
  raise SimileAPIError("Failed to decode the response.")
81
99
  except httpx.RequestError as e:
82
- raise SimileAPIError(f"An unknown request error occurred: {type(e).__name__}: {e}")
100
+ raise SimileAPIError(
101
+ f"An unknown request error occurred: {type(e).__name__}: {e}"
102
+ )
83
103
 
84
104
  def agent(self, agent_id: uuid.UUID) -> Agent:
85
105
  """Returns an Agent object to interact with a specific agent."""
@@ -92,108 +112,209 @@ class Simile:
92
112
  "POST",
93
113
  endpoint,
94
114
  json={"agent_id": str(agent_id)},
95
- response_model=SurveySessionCreateResponse
115
+ response_model=SurveySessionCreateResponse,
96
116
  )
117
+
118
+ # Create and return a SurveySession object
97
119
  return SurveySession(
98
- id=response_data.id,
99
- agent_id=response_data.agent_id,
120
+ id=response_data.id,
121
+ agent_id=response_data.agent_id,
100
122
  status=response_data.status,
101
- client=self
123
+ client=self,
124
+ )
125
+
126
+ async def get_survey_session_details(
127
+ self, session_id: Union[str, uuid.UUID]
128
+ ) -> SurveySessionDetailResponse:
129
+ """Retrieves detailed information about a survey session including typed conversation history."""
130
+ endpoint = f"sessions/{str(session_id)}"
131
+ response_data = await self._request(
132
+ "GET", endpoint, response_model=SurveySessionDetailResponse
102
133
  )
134
+ return response_data
135
+
136
+ async def get_survey_session(
137
+ self, session_id: Union[str, uuid.UUID]
138
+ ) -> SurveySession:
139
+ """Resume an existing survey session by ID and return a SurveySession object."""
140
+ session_details = await self.get_survey_session(session_id)
103
141
 
104
- async def create_population(self, name: str, description: Optional[str] = None) -> Population:
142
+ if session_details.status == "closed":
143
+ raise ValueError(f"Session {session_id} is already closed")
144
+
145
+ return SurveySession(
146
+ id=session_details.id,
147
+ agent_id=session_details.agent_id,
148
+ status=session_details.status,
149
+ client=self,
150
+ )
151
+
152
+ async def create_population(
153
+ self, name: str, description: Optional[str] = None
154
+ ) -> Population:
105
155
  """Creates a new population."""
106
156
  payload = CreatePopulationPayload(name=name, description=description)
107
- response_data = await self._request("POST", "populations/create", json=payload.model_dump(mode='json', exclude_none=True), response_model=Population)
157
+ response_data = await self._request(
158
+ "POST",
159
+ "populations/create",
160
+ json=payload.model_dump(mode="json", exclude_none=True),
161
+ response_model=Population,
162
+ )
108
163
  return response_data
109
164
 
110
165
  async def get_population(self, population_id: Union[str, uuid.UUID]) -> Population:
111
- response_data = await self._request("GET", f"populations/get/{str(population_id)}", response_model=Population)
166
+ response_data = await self._request(
167
+ "GET", f"populations/get/{str(population_id)}", response_model=Population
168
+ )
112
169
  return response_data
113
170
 
114
- async def delete_population(self, population_id: Union[str, uuid.UUID]) -> DeletionResponse:
115
- response_data = await self._request("DELETE", f"populations/delete/{str(population_id)}", response_model=DeletionResponse)
171
+ async def delete_population(
172
+ self, population_id: Union[str, uuid.UUID]
173
+ ) -> DeletionResponse:
174
+ response_data = await self._request(
175
+ "DELETE",
176
+ f"populations/delete/{str(population_id)}",
177
+ response_model=DeletionResponse,
178
+ )
116
179
  return response_data
117
180
 
118
- async def get_agents_in_population(self, population_id: Union[str, uuid.UUID]) -> List[AgentModel]:
181
+ async def get_agents_in_population(
182
+ self, population_id: Union[str, uuid.UUID]
183
+ ) -> List[AgentModel]:
119
184
  """Retrieves all agents belonging to a specific population."""
120
185
  endpoint = f"populations/{str(population_id)}/agents"
121
186
  raw_response = await self._request("GET", endpoint)
122
187
  agents_data_list = raw_response.json()
123
188
  return [AgentModel(**data) for data in agents_data_list]
124
189
 
125
- async def create_agent(self, name: str, population_id: Optional[Union[str, uuid.UUID]] = None, agent_data: Optional[List[Dict[str, Any]]] = None) -> AgentModel:
190
+ async def create_agent(
191
+ self,
192
+ name: str,
193
+ population_id: Optional[Union[str, uuid.UUID]] = None,
194
+ agent_data: Optional[List[Dict[str, Any]]] = None,
195
+ ) -> AgentModel:
126
196
  """Creates a new agent, optionally within a population and with initial data items."""
127
197
  pop_id_uuid: Optional[uuid.UUID] = None
128
198
  if population_id:
129
- pop_id_uuid = uuid.UUID(str(population_id)) if not isinstance(population_id, uuid.UUID) else population_id
130
-
131
- payload = CreateAgentPayload(name=name, population_id=pop_id_uuid, agent_data=agent_data)
132
- response_data = await self._request("POST", "agents/create", json=payload.model_dump(mode='json', exclude_none=True), response_model=AgentModel)
199
+ pop_id_uuid = (
200
+ uuid.UUID(str(population_id))
201
+ if not isinstance(population_id, uuid.UUID)
202
+ else population_id
203
+ )
204
+
205
+ payload = CreateAgentPayload(
206
+ name=name, population_id=pop_id_uuid, agent_data=agent_data
207
+ )
208
+ response_data = await self._request(
209
+ "POST",
210
+ "agents/create",
211
+ json=payload.model_dump(mode="json", exclude_none=True),
212
+ response_model=AgentModel,
213
+ )
133
214
  return response_data
134
215
 
135
216
  async def get_agent(self, agent_id: Union[str, uuid.UUID]) -> AgentModel:
136
- response_data = await self._request("GET", f"agents/get/{str(agent_id)}", response_model=AgentModel)
217
+ response_data = await self._request(
218
+ "GET", f"agents/get/{str(agent_id)}", response_model=AgentModel
219
+ )
137
220
  return response_data
138
221
 
139
222
  async def delete_agent(self, agent_id: Union[str, uuid.UUID]) -> DeletionResponse:
140
- response_data = await self._request("DELETE", f"agents/delete/{str(agent_id)}", response_model=DeletionResponse)
223
+ response_data = await self._request(
224
+ "DELETE", f"agents/delete/{str(agent_id)}", response_model=DeletionResponse
225
+ )
141
226
  return response_data
142
227
 
143
- async def create_data_item(self, agent_id: Union[str, uuid.UUID], data_type: str, content: Any) -> DataItem:
228
+ async def create_data_item(
229
+ self, agent_id: Union[str, uuid.UUID], data_type: str, content: Any
230
+ ) -> DataItem:
144
231
  """Creates a new data item for a specific agent."""
145
232
  payload = CreateDataItemPayload(data_type=data_type, content=content)
146
- response_data = await self._request("POST", f"data_item/create/{str(agent_id)}", json=payload.model_dump(mode='json'), response_model=DataItem)
233
+ response_data = await self._request(
234
+ "POST",
235
+ f"data_item/create/{str(agent_id)}",
236
+ json=payload.model_dump(mode="json"),
237
+ response_model=DataItem,
238
+ )
147
239
  return response_data
148
240
 
149
241
  async def get_data_item(self, data_item_id: Union[str, uuid.UUID]) -> DataItem:
150
- response_data = await self._request("GET", f"data_item/get/{str(data_item_id)}", response_model=DataItem)
242
+ response_data = await self._request(
243
+ "GET", f"data_item/get/{str(data_item_id)}", response_model=DataItem
244
+ )
151
245
  return response_data
152
246
 
153
- async def list_data_items(self, agent_id: Union[str, uuid.UUID], data_type: Optional[str] = None) -> List[DataItem]:
247
+ async def list_data_items(
248
+ self, agent_id: Union[str, uuid.UUID], data_type: Optional[str] = None
249
+ ) -> List[DataItem]:
154
250
  params = {}
155
251
  if data_type:
156
252
  params["data_type"] = data_type
157
253
  agent_id_str = str(agent_id)
158
- raw_response = await self._request("GET", f"data_item/list/{agent_id_str}", params=params)
159
- return [DataItem(**item) for item in raw_response.json()]
254
+ raw_response = await self._request(
255
+ "GET", f"data_item/list/{agent_id_str}", params=params
256
+ )
257
+ return [DataItem(**item) for item in raw_response.json()]
160
258
 
161
- async def update_data_item(self, data_item_id: Union[str, uuid.UUID], content: Any) -> DataItem:
259
+ async def update_data_item(
260
+ self, data_item_id: Union[str, uuid.UUID], content: Any
261
+ ) -> DataItem:
162
262
  """Updates an existing data item."""
163
263
  payload = UpdateDataItemPayload(content=content)
164
- response_data = await self._request("POST", f"data_item/update/{str(data_item_id)}", json=payload.model_dump(), response_model=DataItem)
264
+ response_data = await self._request(
265
+ "POST",
266
+ f"data_item/update/{str(data_item_id)}",
267
+ json=payload.model_dump(),
268
+ response_model=DataItem,
269
+ )
165
270
  return response_data
166
271
 
167
- async def delete_data_item(self, data_item_id: Union[str, uuid.UUID]) -> DeletionResponse:
168
- response_data = await self._request("DELETE", f"data_item/delete/{str(data_item_id)}", response_model=DeletionResponse)
272
+ async def delete_data_item(
273
+ self, data_item_id: Union[str, uuid.UUID]
274
+ ) -> DeletionResponse:
275
+ response_data = await self._request(
276
+ "DELETE",
277
+ f"data_item/delete/{str(data_item_id)}",
278
+ response_model=DeletionResponse,
279
+ )
169
280
  return response_data
170
281
 
171
- async def generate_qual_response(self, agent_id: uuid.UUID, question: str, image_url: Optional[str] = None) -> QualGenerationResponse:
282
+ async def generate_qual_response(
283
+ self, agent_id: uuid.UUID, question: str, image_url: Optional[str] = None
284
+ ) -> QualGenerationResponse:
172
285
  """Generates a qualitative response from an agent based on a question."""
173
286
  endpoint = f"/generation/qual/{str(agent_id)}"
174
287
  request_payload = QualGenerationRequest(question=question, image_url=image_url)
175
288
  response_data = await self._request(
176
- "POST",
177
- endpoint,
178
- json=request_payload.model_dump(),
179
- response_model=QualGenerationResponse
289
+ "POST",
290
+ endpoint,
291
+ json=request_payload.model_dump(),
292
+ response_model=QualGenerationResponse,
180
293
  )
181
294
  return response_data
182
295
 
183
- async def generate_mc_response(self, agent_id: uuid.UUID, question: str, options: List[str], image_url: Optional[str] = None) -> MCGenerationResponse:
296
+ async def generate_mc_response(
297
+ self,
298
+ agent_id: uuid.UUID,
299
+ question: str,
300
+ options: List[str],
301
+ image_url: Optional[str] = None,
302
+ ) -> MCGenerationResponse:
184
303
  """Generates a multiple-choice response from an agent."""
185
304
  endpoint = f"generation/mc/{str(agent_id)}"
186
- request_payload = MCGenerationRequest(question=question, options=options, image_url=image_url)
305
+ request_payload = MCGenerationRequest(
306
+ question=question, options=options, image_url=image_url
307
+ )
187
308
  response_data = await self._request(
188
- "POST",
189
- endpoint,
190
- json=request_payload.model_dump(),
191
- response_model=MCGenerationResponse
309
+ "POST",
310
+ endpoint,
311
+ json=request_payload.model_dump(),
312
+ response_model=MCGenerationResponse,
192
313
  )
193
314
  return response_data
194
315
 
195
316
  async def aclose(self):
196
- await self._client.aclose()
317
+ await self._client.aclose()
197
318
 
198
319
  async def __aenter__(self):
199
320
  return self
simile/models.py CHANGED
@@ -1,6 +1,7 @@
1
- from typing import List, Dict, Any, Optional
2
- from pydantic import BaseModel, Field
1
+ from typing import List, Dict, Any, Optional, Union, Literal
2
+ from pydantic import BaseModel, Field, validator
3
3
  from datetime import datetime
4
+ from enum import Enum
4
5
  import uuid
5
6
 
6
7
 
@@ -61,7 +62,8 @@ class DeletionResponse(BaseModel):
61
62
  # --- Generation Operation Models ---
62
63
  class QualGenerationRequest(BaseModel):
63
64
  question: str
64
- image_url: Optional[str] = None
65
+ image_url: Optional[str] = None # For backward compatibility
66
+ images: Optional[Dict[str, str]] = None # Dict of {description: url} for multiple images
65
67
 
66
68
  class QualGenerationResponse(BaseModel):
67
69
  question: str
@@ -86,13 +88,71 @@ class AddContextResponse(BaseModel):
86
88
 
87
89
 
88
90
  # --- Survey Session Models ---
89
- class ConversationTurn(BaseModel):
90
- type: str # "qual" or "mc"
91
- question: str
92
- options: Optional[List[str]] = None
93
- answer: Optional[str] = None
94
- chosen_option: Optional[str] = None
95
- timestamp: datetime
91
+ class TurnType(str, Enum):
92
+ """Enum for different types of conversation turns."""
93
+ CONTEXT = "context"
94
+ IMAGE = "image"
95
+ QUALITATIVE_QUESTION = "qualitative_question"
96
+ MULTIPLE_CHOICE_QUESTION = "multiple_choice_question"
97
+
98
+
99
+ class BaseTurn(BaseModel):
100
+ """Base model for all conversation turns."""
101
+ timestamp: datetime = Field(default_factory=lambda: datetime.now())
102
+ type: TurnType
103
+
104
+ class Config:
105
+ use_enum_values = True
106
+
107
+
108
+ class ContextTurn(BaseTurn):
109
+ """A context turn that provides background information."""
110
+ type: Literal[TurnType.CONTEXT] = TurnType.CONTEXT
111
+ user_context: str
112
+
113
+
114
+ class ImageTurn(BaseTurn):
115
+ """A standalone image turn (e.g., for context or reference)."""
116
+ type: Literal[TurnType.IMAGE] = TurnType.IMAGE
117
+ image_url: str
118
+ caption: Optional[str] = None
119
+
120
+
121
+ class QualitativeQuestionTurn(BaseTurn):
122
+ """A qualitative question-answer turn."""
123
+ type: Literal[TurnType.QUALITATIVE_QUESTION] = TurnType.QUALITATIVE_QUESTION
124
+ user_question: str
125
+ user_image_url: Optional[str] = None # For backward compatibility
126
+ user_images: Optional[Dict[str, str]] = None # Dict of {description: url} for multiple images
127
+ llm_response: Optional[str] = None
128
+
129
+
130
+ class MultipleChoiceQuestionTurn(BaseTurn):
131
+ """A multiple choice question-answer turn."""
132
+ type: Literal[TurnType.MULTIPLE_CHOICE_QUESTION] = TurnType.MULTIPLE_CHOICE_QUESTION
133
+ user_question: str
134
+ user_options: List[str]
135
+ user_image_url: Optional[str] = None
136
+ llm_chosen_option: Optional[str] = None
137
+
138
+ @validator('user_options')
139
+ def validate_options(cls, v):
140
+ if not v:
141
+ raise ValueError("Multiple choice questions must have at least one option")
142
+ if len(v) < 2:
143
+ raise ValueError("Multiple choice questions should have at least two options")
144
+ return v
145
+
146
+ @validator('llm_chosen_option')
147
+ def validate_chosen_option(cls, v, values):
148
+ if v is not None and 'user_options' in values and v not in values['user_options']:
149
+ raise ValueError(f"Chosen option '{v}' must be one of the provided options")
150
+ return v
151
+
152
+
153
+ # Union type for all possible turn types
154
+ SurveySessionTurn = Union[ContextTurn, ImageTurn, QualitativeQuestionTurn, MultipleChoiceQuestionTurn]
155
+
96
156
 
97
157
  class SurveySessionCreateResponse(BaseModel):
98
158
  id: uuid.UUID # Session ID
@@ -100,6 +160,37 @@ class SurveySessionCreateResponse(BaseModel):
100
160
  created_at: datetime
101
161
  status: str
102
162
 
163
+
164
+ class SurveySessionDetailResponse(BaseModel):
165
+ """Detailed survey session response with typed conversation turns."""
166
+ id: uuid.UUID
167
+ agent_id: uuid.UUID
168
+ created_at: datetime
169
+ updated_at: datetime
170
+ status: str
171
+ conversation_history: List[SurveySessionTurn] = Field(default_factory=list)
172
+
173
+ class Config:
174
+ json_encoders = {
175
+ datetime: lambda v: v.isoformat()
176
+ }
177
+
178
+
179
+ class SurveySessionListItemResponse(BaseModel):
180
+ """Summary response for listing survey sessions."""
181
+ id: uuid.UUID
182
+ agent_id: uuid.UUID
183
+ created_at: datetime
184
+ updated_at: datetime
185
+ status: str
186
+ turn_count: int = Field(description="Number of turns in conversation history")
187
+
188
+ class Config:
189
+ json_encoders = {
190
+ datetime: lambda v: v.isoformat()
191
+ }
192
+
193
+
103
194
  class SurveySessionCloseResponse(BaseModel):
104
195
  id: uuid.UUID # Session ID
105
196
  status: str
simile/resources.py CHANGED
@@ -1,5 +1,5 @@
1
1
  import uuid
2
- from typing import TYPE_CHECKING, List, Optional
2
+ from typing import TYPE_CHECKING, List, Optional, Dict
3
3
 
4
4
  from .models import (
5
5
  QualGenerationRequest,
@@ -8,7 +8,8 @@ from .models import (
8
8
  MCGenerationResponse,
9
9
  SurveySessionCloseResponse,
10
10
  AddContextRequest,
11
- AddContextResponse
11
+ AddContextResponse,
12
+ SurveySessionDetailResponse
12
13
  )
13
14
 
14
15
  if TYPE_CHECKING:
@@ -53,10 +54,14 @@ class SurveySession:
53
54
  def status(self) -> str:
54
55
  return self._status
55
56
 
56
- async def generate_qual_response(self, question: str, image_url: Optional[str] = None) -> QualGenerationResponse:
57
+ async def get_details(self) -> SurveySessionDetailResponse:
58
+ """Retrieves detailed information about this survey session including typed conversation history."""
59
+ return await self._client.get_survey_session(self._id)
60
+
61
+ async def generate_qual_response(self, question: str, image_url: Optional[str] = None, images: Optional[Dict[str, str]] = None) -> QualGenerationResponse:
57
62
  """Generates a qualitative response within this survey session."""
58
63
  endpoint = f"sessions/{str(self._id)}/qual"
59
- payload = QualGenerationRequest(question=question, image_url=image_url)
64
+ payload = QualGenerationRequest(question=question, image_url=image_url, images=images)
60
65
  return await self._client._request(
61
66
  "POST",
62
67
  endpoint,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: simile
3
- Version: 0.2.6
3
+ Version: 0.2.8
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
@@ -0,0 +1,10 @@
1
+ simile/__init__.py,sha256=2OZ1LQIkAEtSs0EI5Fzlg7QGKduCgCe_nTh9FfIuHlQ,865
2
+ simile/client.py,sha256=6gtzniCdx4bfpseO448ViZa0CGz1CdQDPGXM3VBaRyg,11826
3
+ simile/exceptions.py,sha256=-rJ3KZcpvNRi9JXbDpxWDSL2lU1mEJX2piwYRZvhKmg,1406
4
+ simile/models.py,sha256=gM6QqVySJe6sG-X7deDcpQYo0JMhfxtfZtBHFP-ZqSI,5376
5
+ simile/resources.py,sha256=KPSmcX6cgVfOCPvL1eD5zc9fvOw5n4oe6pOieuzp8zg,3982
6
+ simile-0.2.8.dist-info/licenses/LICENSE,sha256=tpxX3bpODfyOQVyEM6kCMvPHFCpkjFDj0AICRqKqOFA,1066
7
+ simile-0.2.8.dist-info/METADATA,sha256=xic3erPzu6K041_zHaHDM8na8HkHGPIRKBcUsf4mH_g,1276
8
+ simile-0.2.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
9
+ simile-0.2.8.dist-info/top_level.txt,sha256=41lJneubAG4-ZOAs5qn7iDtDb-MDxa6DdvgBKwNX84M,7
10
+ simile-0.2.8.dist-info/RECORD,,
@@ -1,10 +0,0 @@
1
- simile/__init__.py,sha256=2OZ1LQIkAEtSs0EI5Fzlg7QGKduCgCe_nTh9FfIuHlQ,865
2
- simile/client.py,sha256=_XsrdDHO25Fsnap6uhUlbMrKO8vMJGJaDCeym8xBs8o,9866
3
- simile/exceptions.py,sha256=-rJ3KZcpvNRi9JXbDpxWDSL2lU1mEJX2piwYRZvhKmg,1406
4
- simile/models.py,sha256=dBqH3mVcjvNpOTPV5CBwXjkqZrgmgvZYU1r5ZUqI878,2311
5
- simile/resources.py,sha256=AeT8547YChPGGSIkhZ2bfN73BhDh1c3OEopJqGIlGE8,3650
6
- simile-0.2.6.dist-info/licenses/LICENSE,sha256=tpxX3bpODfyOQVyEM6kCMvPHFCpkjFDj0AICRqKqOFA,1066
7
- simile-0.2.6.dist-info/METADATA,sha256=Ny1lEKybPGZ_CC9q3ibcAfU4AtG2SKVg_jol8QDsbYE,1276
8
- simile-0.2.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
9
- simile-0.2.6.dist-info/top_level.txt,sha256=41lJneubAG4-ZOAs5qn7iDtDb-MDxa6DdvgBKwNX84M,7
10
- simile-0.2.6.dist-info/RECORD,,
File without changes