simile 0.1.0__tar.gz → 0.2.0__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 simile might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 Joon Sung Park
3
+ Copyright (c) 2025 Simile AI
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
simile-0.2.0/PKG-INFO ADDED
@@ -0,0 +1,47 @@
1
+ Metadata-Version: 2.4
2
+ Name: simile
3
+ Version: 0.2.0
4
+ Summary: Package for interfacing with Simile AI agents for simulation
5
+ Author-email: Simile AI <cqz@simile.ai>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/simile-team/simile-sdk
8
+ Keywords: api,sdk,simile,ai-agent,simulation
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.8
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
+ Requires-Python: >=3.8
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: httpx>=0.20.0
23
+ Requires-Dist: pydantic>=2.0.0
24
+ Dynamic: license-file
25
+
26
+ # Simile API Python Client
27
+
28
+ A Python client for interacting with the Simile API server.
29
+
30
+ ## Installation
31
+
32
+ ```bash
33
+ pip install simile
34
+ ```
35
+
36
+ ## Dependencies
37
+
38
+ - `httpx>=0.20.0`
39
+ - `pydantic>=2.0.0`
40
+
41
+ ## Usage
42
+
43
+ ```python
44
+ from simile import Simile
45
+
46
+ client = Simile(api_key="your_api_key")
47
+ ```
simile-0.2.0/README.md ADDED
@@ -0,0 +1,22 @@
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
+ ```
@@ -0,0 +1,35 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "simile"
7
+ version = "0.2.0"
8
+ authors = [
9
+ { name="Simile AI", email="cqz@simile.ai" },
10
+ ]
11
+ description = "Package for interfacing with Simile AI agents for simulation"
12
+ readme = "README.md"
13
+ requires-python = ">=3.8"
14
+ license = { text = "MIT" }
15
+ keywords = ["api", "sdk", "simile", "ai-agent", "simulation"]
16
+ classifiers = [
17
+ "Development Status :: 3 - Alpha",
18
+ "Intended Audience :: Developers",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.8",
21
+ "Programming Language :: Python :: 3.9",
22
+ "Programming Language :: Python :: 3.10",
23
+ "Programming Language :: Python :: 3.11",
24
+ "Programming Language :: Python :: 3.12",
25
+ "Operating System :: OS Independent",
26
+ "Topic :: Software Development :: Libraries :: Python Modules",
27
+ ]
28
+
29
+ dependencies = [
30
+ "httpx>=0.20.0",
31
+ "pydantic>=2.0.0",
32
+ ]
33
+
34
+ [project.urls]
35
+ "Homepage" = "https://github.com/simile-team/simile-sdk"
simile-0.2.0/setup.py ADDED
@@ -0,0 +1,4 @@
1
+ from setuptools import setup
2
+
3
+ if __name__ == "__main__":
4
+ setup()
@@ -0,0 +1,28 @@
1
+ from .client import Simile
2
+ from .models import (
3
+ Population, Agent, DataItem,
4
+ CreatePopulationPayload, CreateAgentPayload, CreateDataItemPayload, UpdateDataItemPayload,
5
+ DeletionResponse,
6
+ QualGenerationRequest,
7
+ QualGenerationResponse,
8
+ MCGenerationRequest,
9
+ MCGenerationResponse
10
+ )
11
+ from .exceptions import (
12
+ SimileAPIError,
13
+ SimileAuthenticationError,
14
+ SimileNotFoundError,
15
+ SimileBadRequestError
16
+ )
17
+
18
+ __all__ = [
19
+ "Simile",
20
+ "Population", "Agent", "DataItem",
21
+ "CreatePopulationPayload", "CreateAgentPayload", "CreateDataItemPayload", "UpdateDataItemPayload",
22
+ "DeletionResponse",
23
+ "QualGenerationRequest", "QualGenerationResponse",
24
+ "MCGenerationRequest", "MCGenerationResponse",
25
+ "SimileAPIError", "SimileAuthenticationError", "SimileNotFoundError", "SimileBadRequestError"
26
+ ]
27
+
28
+ __version__ = "0.1.0"
@@ -0,0 +1,134 @@
1
+ import httpx
2
+ from httpx import AsyncClient
3
+ from typing import List, Dict, Any, Optional, Union, Type
4
+ import uuid
5
+ from pydantic import BaseModel
6
+
7
+ from .models import (
8
+ Population, Agent, DataItem,
9
+ CreatePopulationPayload, CreateAgentPayload, CreateDataItemPayload, UpdateDataItemPayload,
10
+ DeletionResponse, QualGenerationRequest, QualGenerationResponse, MCGenerationRequest, MCGenerationResponse
11
+ )
12
+ from .exceptions import (
13
+ SimileAPIError, SimileAuthenticationError, SimileNotFoundError, SimileBadRequestError
14
+ )
15
+
16
+ DEFAULT_BASE_URL = "https://simile-api-3a83be7adae0.herokuapp.com/api/v1"
17
+ TIMEOUT_CONFIG = httpx.Timeout(5.0, read=30.0, write=30.0, pool=30.0)
18
+
19
+ class Simile:
20
+ def __init__(self, api_key: str, base_url: str = DEFAULT_BASE_URL):
21
+ if not api_key:
22
+ raise ValueError("API key is required.")
23
+ self.api_key = api_key
24
+ self.base_url = base_url.rstrip('/')
25
+ self._client = AsyncClient(
26
+ headers={"X-API-Key": self.api_key},
27
+ timeout=TIMEOUT_CONFIG
28
+ )
29
+
30
+ async def _request(self, method: str, endpoint: str, **kwargs) -> Union[httpx.Response, BaseModel]:
31
+ url = f"{self.base_url}/{endpoint.lstrip('/')}"
32
+ response_model_cls: Optional[Type[BaseModel]] = kwargs.pop("response_model", None)
33
+
34
+ try:
35
+ response = await self._client.request(method, url, **kwargs)
36
+ response.raise_for_status()
37
+
38
+ if response_model_cls:
39
+ return response_model_cls(**response.json())
40
+ else:
41
+ return response
42
+ except httpx.HTTPStatusError as e:
43
+ status_code = e.response.status_code
44
+ try:
45
+ error_data = e.response.json()
46
+ detail = error_data.get("detail", e.response.text)
47
+ except Exception:
48
+ detail = e.response.text
49
+
50
+ if status_code == 401:
51
+ raise SimileAuthenticationError(detail=detail)
52
+ elif status_code == 404:
53
+ raise SimileNotFoundError(detail=detail)
54
+ elif status_code == 400:
55
+ raise SimileBadRequestError(detail=detail)
56
+ else:
57
+ raise SimileAPIError(f"API request failed: {e}", status_code=status_code, detail=detail)
58
+ except httpx.RequestError as e:
59
+ raise SimileAPIError(f"Request error: {e}")
60
+
61
+ # --- Population Endpoints ---
62
+ async def create_population(self, payload: CreatePopulationPayload) -> Population:
63
+ response_data = await self._request("POST", "populations/create", json=payload.model_dump(mode='json', exclude_none=True), response_model=Population)
64
+ return response_data
65
+
66
+ async def get_population(self, population_id: Union[str, uuid.UUID]) -> Population:
67
+ response_data = await self._request("GET", f"populations/get/{str(population_id)}", response_model=Population)
68
+ return response_data
69
+
70
+ async def delete_population(self, population_id: Union[str, uuid.UUID]) -> DeletionResponse:
71
+ response_data = await self._request("DELETE", f"populations/delete/{str(population_id)}", response_model=DeletionResponse)
72
+ return response_data
73
+
74
+ # --- Agent Endpoints ---
75
+ async def create_agent(self, payload: CreateAgentPayload) -> Agent:
76
+ response_data = await self._request("POST", "agents/create", json=payload.model_dump(mode='json', exclude_none=True), response_model=Agent)
77
+ return response_data
78
+
79
+ async def get_agent(self, agent_id: Union[str, uuid.UUID]) -> Agent:
80
+ response_data = await self._request("GET", f"agents/get/{str(agent_id)}", response_model=Agent)
81
+ return response_data
82
+
83
+ async def delete_agent(self, agent_id: Union[str, uuid.UUID]) -> DeletionResponse:
84
+ response_data = await self._request("DELETE", f"agents/delete/{str(agent_id)}", response_model=DeletionResponse)
85
+ return response_data
86
+
87
+ # --- Data Item Endpoints ---
88
+ async def create_data_item(self, agent_id: Union[str, uuid.UUID], payload: CreateDataItemPayload) -> DataItem:
89
+ response_data = await self._request("POST", f"data_item/create/{str(agent_id)}", json=payload.model_dump(mode='json'), response_model=DataItem)
90
+ return response_data
91
+
92
+ async def get_data_item(self, data_item_id: Union[str, uuid.UUID]) -> DataItem:
93
+ response_data = await self._request("GET", f"data_item/get/{str(data_item_id)}", response_model=DataItem)
94
+ return response_data
95
+
96
+ async def list_data_items(self, agent_id: Union[str, uuid.UUID], data_type: Optional[str] = None) -> List[DataItem]:
97
+ params = {}
98
+ if data_type:
99
+ params["data_type"] = data_type
100
+ raw_response = await self._request("GET", f"data_item/list/{str(agent_id)}", params=params)
101
+ return [DataItem(**item) for item in raw_response.json()]
102
+
103
+ async def update_data_item(self, data_item_id: Union[str, uuid.UUID], payload: UpdateDataItemPayload) -> DataItem:
104
+ response_data = await self._request("POST", f"data_item/update/{data_item_id}", json=payload.model_dump(), response_model=DataItem)
105
+ return response_data
106
+
107
+ async def delete_data_item(self, data_item_id: Union[str, uuid.UUID]) -> DeletionResponse:
108
+ response_data = await self._request("DELETE", f"data_item/delete/{str(data_item_id)}", response_model=DeletionResponse)
109
+ return response_data
110
+
111
+ # --- LLM Generation Methods ---
112
+ async def generate_qual_response(self, agent_id: uuid.UUID, request_payload: QualGenerationRequest) -> QualGenerationResponse:
113
+ endpoint = f"/generation/qual/{str(agent_id)}"
114
+ response_data = await self._request(
115
+ "POST",
116
+ endpoint,
117
+ json=request_payload.model_dump(),
118
+ response_model=QualGenerationResponse
119
+ )
120
+ return response_data
121
+
122
+ async def generate_mc_response(self, agent_id: uuid.UUID, request_payload: MCGenerationRequest) -> MCGenerationResponse:
123
+ endpoint = f"generation/mc/{agent_id}"
124
+ response_data = await self._request("POST", endpoint, json=request_payload.model_dump(), response_model=MCGenerationResponse)
125
+ return response_data
126
+
127
+ async def aclose(self):
128
+ await self._client.aclose()
129
+
130
+ async def __aenter__(self):
131
+ return self
132
+
133
+ async def __aexit__(self, exc_type, exc_val, exc_tb):
134
+ await self.aclose()
@@ -0,0 +1,31 @@
1
+ class SimileAPIError(Exception):
2
+ """Base exception for Simile API client errors."""
3
+ def __init__(self, message: str, status_code: int = None, detail: str = None):
4
+ super().__init__(message)
5
+ self.status_code = status_code
6
+ self.detail = detail
7
+
8
+ def __str__(self):
9
+ if self.status_code and self.detail:
10
+ return f"{super().__str__()} (Status Code: {self.status_code}, Detail: {self.detail})"
11
+ elif self.status_code:
12
+ return f"{super().__str__()} (Status Code: {self.status_code})"
13
+ return super().__str__()
14
+
15
+
16
+ class SimileAuthenticationError(SimileAPIError):
17
+ """Exception for authentication errors (e.g., invalid API key)."""
18
+ def __init__(self, message: str = "Authentication failed. Ensure API key is valid.", status_code: int = 401, detail: str = None):
19
+ super().__init__(message, status_code, detail)
20
+
21
+
22
+ class SimileNotFoundError(SimileAPIError):
23
+ """Exception for resource not found errors (404)."""
24
+ def __init__(self, message: str = "Resource not found.", status_code: int = 404, detail: str = None):
25
+ super().__init__(message, status_code, detail)
26
+
27
+
28
+ class SimileBadRequestError(SimileAPIError):
29
+ """Exception for bad request errors (400)."""
30
+ def __init__(self, message: str = "Bad request.", status_code: int = 400, detail: str = None):
31
+ super().__init__(message, status_code, detail)
@@ -0,0 +1,74 @@
1
+ from typing import List, Dict, Any, Optional
2
+ from pydantic import BaseModel, Field
3
+ from datetime import datetime
4
+ import uuid
5
+
6
+
7
+ class Population(BaseModel):
8
+ population_id: uuid.UUID
9
+ name: str
10
+ description: Optional[str] = None
11
+ created_at: datetime
12
+ updated_at: datetime
13
+
14
+
15
+ class DataItem(BaseModel):
16
+ id: uuid.UUID
17
+ agent_id: uuid.UUID
18
+ data_type: str
19
+ content: Any
20
+ created_at: datetime
21
+ updated_at: datetime
22
+
23
+
24
+ class Agent(BaseModel):
25
+ agent_id: uuid.UUID
26
+ name: str
27
+ population_id: Optional[uuid.UUID] = None
28
+ created_at: datetime
29
+ updated_at: datetime
30
+ data_items: List[DataItem] = Field(default_factory=list)
31
+
32
+ class CreatePopulationPayload(BaseModel):
33
+ name: str
34
+ description: Optional[str] = None
35
+
36
+
37
+ class CreateAgentPayload(BaseModel):
38
+ name: str
39
+ population_id: Optional[uuid.UUID] = None
40
+ agent_data: Optional[List[Dict[str, Any]]] = None # For initial data items
41
+
42
+
43
+ class CreateDataItemPayload(BaseModel):
44
+ data_type: str
45
+ content: Any
46
+
47
+
48
+ class UpdateDataItemPayload(BaseModel):
49
+ content: Any
50
+
51
+
52
+ class DeletionResponse(BaseModel):
53
+ message: str
54
+
55
+
56
+ # --- LLM Generation Models ---
57
+
58
+ class QualGenerationRequest(BaseModel):
59
+ question: str
60
+
61
+ class QualGenerationResponse(BaseModel):
62
+ agent_id: uuid.UUID
63
+ question: str
64
+ answer: str
65
+
66
+ class MCGenerationRequest(BaseModel):
67
+ question: str
68
+ options: List[str]
69
+
70
+ class MCGenerationResponse(BaseModel):
71
+ agent_id: uuid.UUID
72
+ question: str
73
+ options: List[str]
74
+ chosen_option: str
@@ -0,0 +1,47 @@
1
+ Metadata-Version: 2.4
2
+ Name: simile
3
+ Version: 0.2.0
4
+ Summary: Package for interfacing with Simile AI agents for simulation
5
+ Author-email: Simile AI <cqz@simile.ai>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/simile-team/simile-sdk
8
+ Keywords: api,sdk,simile,ai-agent,simulation
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.8
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
+ Requires-Python: >=3.8
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: httpx>=0.20.0
23
+ Requires-Dist: pydantic>=2.0.0
24
+ Dynamic: license-file
25
+
26
+ # Simile API Python Client
27
+
28
+ A Python client for interacting with the Simile API server.
29
+
30
+ ## Installation
31
+
32
+ ```bash
33
+ pip install simile
34
+ ```
35
+
36
+ ## Dependencies
37
+
38
+ - `httpx>=0.20.0`
39
+ - `pydantic>=2.0.0`
40
+
41
+ ## Usage
42
+
43
+ ```python
44
+ from simile import Simile
45
+
46
+ client = Simile(api_key="your_api_key")
47
+ ```
@@ -0,0 +1,13 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ setup.py
5
+ simile/__init__.py
6
+ simile/client.py
7
+ simile/exceptions.py
8
+ simile/models.py
9
+ simile.egg-info/PKG-INFO
10
+ simile.egg-info/SOURCES.txt
11
+ simile.egg-info/dependency_links.txt
12
+ simile.egg-info/requires.txt
13
+ simile.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ httpx>=0.20.0
2
+ pydantic>=2.0.0
simile-0.1.0/MANIFEST.in DELETED
@@ -1,2 +0,0 @@
1
- include README.md
2
- include LICENSE
simile-0.1.0/PKG-INFO DELETED
@@ -1,41 +0,0 @@
1
- Metadata-Version: 2.2
2
- Name: simile
3
- Version: 0.1.0
4
- Summary: A Python client library for interacting with my Agent & Population endpoints
5
- Home-page: https://github.com/simile-team/simile
6
- Author: Joon Sung Park
7
- Author-email: joon.s.pk@gmail.com
8
- Classifier: Programming Language :: Python :: 3
9
- Classifier: License :: OSI Approved :: MIT License
10
- Classifier: Operating System :: OS Independent
11
- Requires-Python: >=3.7
12
- Description-Content-Type: text/markdown
13
- License-File: LICENSE
14
- Requires-Dist: requests>=2.22.0
15
- Requires-Dist: urllib3>=1.26.0
16
- Dynamic: author
17
- Dynamic: author-email
18
- Dynamic: classifier
19
- Dynamic: description
20
- Dynamic: description-content-type
21
- Dynamic: home-page
22
- Dynamic: requires-dist
23
- Dynamic: requires-python
24
- Dynamic: summary
25
-
26
- # Simile
27
-
28
- **Simile** is a Python client library for interacting with your Agent & Population endpoints. It provides a simple interface for creating and managing agents, managing populations, and performing asynchronous tasks such as generating agent responses or creating sub-populations.
29
-
30
- ## Features
31
-
32
- - **Agent Management**: Create, delete, retrieve details for agents.
33
- - **Population Management**: Create populations, add/remove agents, delete, or create sub-populations.
34
- - **Asynchronous Tasks**: Returns a `Task` object that can be polled or waited upon for long-running operations.
35
-
36
- ## Installation
37
-
38
- Install via **pip** (once you've published to PyPI):
39
-
40
- ```bash
41
- pip install simile
simile-0.1.0/README.md DELETED
@@ -1,16 +0,0 @@
1
- # Simile
2
-
3
- **Simile** is a Python client library for interacting with your Agent & Population endpoints. It provides a simple interface for creating and managing agents, managing populations, and performing asynchronous tasks such as generating agent responses or creating sub-populations.
4
-
5
- ## Features
6
-
7
- - **Agent Management**: Create, delete, retrieve details for agents.
8
- - **Population Management**: Create populations, add/remove agents, delete, or create sub-populations.
9
- - **Asynchronous Tasks**: Returns a `Task` object that can be polled or waited upon for long-running operations.
10
-
11
- ## Installation
12
-
13
- Install via **pip** (once you've published to PyPI):
14
-
15
- ```bash
16
- pip install simile
simile-0.1.0/setup.py DELETED
@@ -1,26 +0,0 @@
1
- import setuptools
2
-
3
- with open("README.md", "r", encoding="utf-8") as fh:
4
- long_description = fh.read()
5
-
6
- setuptools.setup(
7
- name="simile", # Replace with your desired package name
8
- version="0.1.0",
9
- author="Joon Sung Park",
10
- author_email="joon.s.pk@gmail.com",
11
- description="A Python client library for interacting with my Agent & Population endpoints",
12
- long_description=long_description,
13
- long_description_content_type="text/markdown",
14
- url="https://github.com/simile-team/simile", # or your repo link
15
- packages=setuptools.find_packages(),
16
- install_requires=[
17
- "requests>=2.22.0",
18
- "urllib3>=1.26.0"
19
- ],
20
- classifiers=[
21
- "Programming Language :: Python :: 3",
22
- "License :: OSI Approved :: MIT License", # or your choice
23
- "Operating System :: OS Independent",
24
- ],
25
- python_requires='>=3.7',
26
- )
@@ -1,38 +0,0 @@
1
- # simile/__init__.py
2
- import sys
3
- from . import config
4
- from .resource_agent import Agent
5
- from .resource_population import Population
6
- from .task import Task
7
- from .config import configure
8
-
9
- class _SimileModuleProxy:
10
- def __init__(self, real_module):
11
- self._real_module = real_module
12
-
13
- def __getattr__(self, name):
14
- # If user says simile.api_key → return config.api_key
15
- if name == "api_key":
16
- return config.api_key
17
- elif name == "api_base":
18
- return config.api_base
19
- elif hasattr(self._real_module, name):
20
- return getattr(self._real_module, name)
21
- else:
22
- raise AttributeError(f"No attribute {name} in simile")
23
-
24
- def __setattr__(self, name, value):
25
- if name in ("_real_module",):
26
- super().__setattr__(name, value)
27
- elif name == "api_key":
28
- config.api_key = value
29
- elif name == "api_base":
30
- config.api_base = value
31
- else:
32
- setattr(self._real_module, name, value)
33
-
34
- # Grab the current module object
35
- _this_module = sys.modules[__name__]
36
-
37
- # Replace it with our proxy
38
- sys.modules[__name__] = _SimileModuleProxy(_this_module)
@@ -1,48 +0,0 @@
1
- # simile/api_requestor.py
2
- import requests
3
- from . import config
4
- from .error import AuthenticationError, RequestError, ApiKeyNotSetError
5
-
6
- def request(method, endpoint, params=None, data=None, json=None, headers=None, timeout=30):
7
- # Refer back to config.api_key so changes to config are seen here
8
- if not config.api_key:
9
- raise ApiKeyNotSetError("No API key set. Please set simile.api_key = '...'")
10
-
11
- if not endpoint.startswith("/"):
12
- endpoint = "/" + endpoint
13
-
14
- url = config.api_base.rstrip("/") + endpoint
15
-
16
- # Common default headers
17
- default_headers = {
18
- "Authorization": f"Api-Key {config.api_key}",
19
- "Content-Type": "application/json",
20
- }
21
- if headers:
22
- default_headers.update(headers)
23
-
24
- try:
25
- resp = requests.request(
26
- method=method,
27
- url=url,
28
- params=params,
29
- data=data,
30
- json=json,
31
- headers=default_headers,
32
- timeout=timeout
33
- )
34
- except requests.exceptions.RequestException as e:
35
- raise RequestError(f"Request error: {e}")
36
-
37
- # Check for typical authentication or 4xx/5xx issues
38
- if resp.status_code == 401:
39
- raise AuthenticationError("Invalid or missing API key.")
40
- elif 400 <= resp.status_code < 600:
41
- # For all other error codes, raise a generic error
42
- raise RequestError(
43
- f"Error from server (status {resp.status_code}): {resp.text}",
44
- status_code=resp.status_code,
45
- response=resp.text
46
- )
47
-
48
- return resp
@@ -1,21 +0,0 @@
1
- # simile/config.py
2
- """
3
- Holds global configurations for the simile library.
4
- """
5
-
6
- # Default global configs
7
- api_key = None # The user must set this before making calls
8
- api_base = "https://agentbank-f515f1977c64.herokuapp.com/agents/api" # default; override if needed
9
-
10
- def configure(key=None, base=None):
11
- """
12
- Convenience function to set global API key/base from user code.
13
- Example:
14
- import simile
15
- simile.configure(key="abc123", base="https://example.com/agents/api")
16
- """
17
- global api_key, api_base
18
- if key is not None:
19
- api_key = key
20
- if base is not None:
21
- api_base = base
@@ -1,16 +0,0 @@
1
- # simile/error.py
2
- """
3
- Custom error/exception types for the simile library.
4
- """
5
-
6
- class ApiKeyNotSetError(Exception):
7
- pass
8
-
9
- class AuthenticationError(Exception):
10
- pass
11
-
12
- class RequestError(Exception):
13
- def __init__(self, message, status_code=None, response=None):
14
- super().__init__(message)
15
- self.status_code = status_code
16
- self.response = response
@@ -1,105 +0,0 @@
1
- # simile/resource_agent.py
2
- """
3
- Implements Agent-related methods analogous to how you might use openai.Completion or similar classes.
4
- """
5
-
6
- from .api_requestor import request
7
- from .task import Task
8
- from .error import RequestError
9
-
10
- class Agent:
11
- @staticmethod
12
- def create(
13
- first_name,
14
- last_name,
15
- forked_agent_id="",
16
- speech_pattern="",
17
- self_description="",
18
- population_id="",
19
- read_permission="private",
20
- write_permission="private",
21
- agent_data=None
22
- ):
23
- """
24
- Asynchronously create an agent via POST /create_single_agent/
25
- Returns a Task object that you can poll or wait on.
26
-
27
- Usage:
28
- from simile import Agent
29
- task = Agent.create("John", "Doe")
30
- # block until done:
31
- result = task.wait() # => {"agent_id": "..."}
32
- new_agent_id = result["agent_id"]
33
- """
34
- if agent_data is None:
35
- agent_data = []
36
-
37
- payload = {
38
- "first_name": first_name,
39
- "last_name": last_name,
40
- "forked_agent_id": forked_agent_id,
41
- "speech_pattern": speech_pattern,
42
- "self_description": self_description,
43
- "population_id": population_id,
44
- "read_permission": read_permission,
45
- "write_permission": write_permission,
46
- "agent_data": agent_data
47
- }
48
-
49
- resp = request("POST", "/create_single_agent/", json=payload)
50
- data = resp.json()
51
- task_id = data.get("task_id")
52
- if not task_id:
53
- raise RequestError("No 'task_id' returned from create_single_agent endpoint.")
54
-
55
- # The result endpoint is /create_single_agent_result/<task_id>/
56
- result_endpoint = "/create_single_agent_result/{task_id}/"
57
- return Task(task_id, result_endpoint)
58
-
59
- @staticmethod
60
- def retrieve_details(agent_id):
61
- """
62
- Synchronously retrieve agent details via GET /get_agent_details/.
63
- Returns a dict with details or raises RequestError on failure.
64
- """
65
- params = {"agent_id": agent_id}
66
- resp = request("GET", "/get_agent_details/", params=params)
67
- return resp.json()
68
-
69
- @staticmethod
70
- def delete(agent_id):
71
- """
72
- Synchronously delete an agent via POST /delete_agent/.
73
- Returns a dict with {status, message} or raises RequestError.
74
- """
75
- payload = {"agent_id": agent_id}
76
- resp = request("POST", "/delete_agent/", json=payload)
77
- return resp.json()
78
-
79
- @staticmethod
80
- def generate_response(agent_id, question_type, question_payload):
81
- """
82
- Asynchronously generate an agent's response via /generate_agent_response/.
83
- question_type can be 'categorical', 'numerical', or 'chat'.
84
- question_payload is a dict. E.g. { "question": "...", "options": [...] }, etc.
85
-
86
- Returns a Task object for polling or waiting.
87
- Usage:
88
- from simile import Agent
89
- task = Agent.generate_response("a_123", "chat", {...})
90
- result = task.wait()
91
- """
92
- payload = {
93
- "agent_id": agent_id,
94
- "question_type": question_type,
95
- "question": question_payload
96
- }
97
- resp = request("POST", "/generate_agent_response/", json=payload)
98
- data = resp.json()
99
- task_id = data.get("task_id")
100
- if not task_id:
101
- raise RequestError("No 'task_id' returned from generate_agent_response endpoint.")
102
-
103
- # The result endpoint is /generate_agent_response_result/<task_id>/
104
- result_endpoint = "/generate_agent_response_result/{task_id}/"
105
- return Task(task_id, result_endpoint)
@@ -1,87 +0,0 @@
1
- # simile/resource_population.py
2
- """
3
- Implements Population-related methods: create, get_agents, add_agent, remove_agent, delete, etc.
4
- """
5
-
6
- from .api_requestor import request
7
- from .task import Task
8
- from .error import RequestError
9
-
10
- class Population:
11
- @staticmethod
12
- def create(name="New Population"):
13
- """
14
- Synchronously create a population via POST /create_population/.
15
- Returns a dict { "status": "success", "population_id": "..." } or raises an error.
16
- """
17
- payload = {"name": name}
18
- resp = request("POST", "/create_population/", json=payload)
19
- return resp.json()
20
-
21
- @staticmethod
22
- def get_agents(population_id):
23
- """
24
- Synchronously get the agents in a population via GET /get_population_agents/.
25
- Returns { "agent_ids": [ ... ] }
26
- """
27
- params = {"population_id": population_id}
28
- resp = request("GET", "/get_population_agents/", params=params)
29
- return resp.json()
30
-
31
- @staticmethod
32
- def add_agent(population_id, agent_id):
33
- """
34
- Synchronously add an agent to a population via POST /population_add_agent/.
35
- Returns { "status": "...", "message": "..." } or raises an error.
36
- """
37
- payload = {
38
- "population_id": population_id,
39
- "agent_id": agent_id
40
- }
41
- resp = request("POST", "/population_add_agent/", json=payload)
42
- return resp.json()
43
-
44
- @staticmethod
45
- def remove_agent(population_id, agent_id):
46
- """
47
- Synchronously remove an agent from a population via DELETE /population_remove_agent/.
48
- Returns { "status": "...", "message": "..." } or raises an error.
49
- """
50
- payload = {
51
- "population_id": population_id,
52
- "agent_id": agent_id
53
- }
54
- resp = request("DELETE", "/population_remove_agent/", json=payload)
55
- return resp.json()
56
-
57
- @staticmethod
58
- def delete(population_id):
59
- """
60
- Synchronously delete a population via DELETE /delete_population/.
61
- Returns { "status": "...", "message": "..." }
62
- """
63
- payload = {"population_id": population_id}
64
- resp = request("DELETE", "/delete_population/", json=payload)
65
- return resp.json()
66
-
67
- @staticmethod
68
- def create_sub_population(population_id="", n=1):
69
- """
70
- Asynchronously create a sub-population by sampling from an existing population
71
- or from all agents if no population_id is given.
72
- Endpoint: POST /create_sub_population/
73
- Returns a Task object. On success, final data should have "new_population_id".
74
- """
75
- payload = {
76
- "population_id": population_id,
77
- "n": n
78
- }
79
- resp = request("POST", "/create_sub_population/", json=payload)
80
- data = resp.json()
81
- task_id = data.get("task_id")
82
- if not task_id:
83
- raise RequestError("No 'task_id' returned from create_sub_population endpoint.")
84
-
85
- # The result endpoint is /create_sub_population_result/<task_id>/
86
- result_endpoint = "/create_sub_population_result/{task_id}/"
87
- return Task(task_id, result_endpoint)
@@ -1,79 +0,0 @@
1
- # simile/task.py
2
- import time
3
- from .api_requestor import request
4
-
5
- class Task:
6
- """
7
- Represents an asynchronous Celery-like task.
8
- Contains logic for polling the result endpoint until completion or failure.
9
- """
10
- def __init__(self, task_id, result_endpoint):
11
- self.task_id = task_id
12
- self.result_endpoint = result_endpoint # e.g. '/generate_agent_response_result/{task_id}/'
13
- self._last_status = None
14
- self._last_result = None
15
- self._finished = False
16
-
17
- @property
18
- def last_status(self):
19
- """Returns the last known status from the server."""
20
- return self._last_status
21
-
22
- @property
23
- def result(self):
24
- """If the task has finished successfully, returns the result payload."""
25
- if self._finished and self._last_status == "SUCCESS":
26
- return self._last_result
27
- return None
28
-
29
- @property
30
- def error(self):
31
- """If the task has failed, returns the error message."""
32
- if self._finished and self._last_status == "FAILURE":
33
- return self._last_result
34
- return None
35
-
36
- def poll(self):
37
- """
38
- Perform a single poll to the result endpoint,
39
- storing the status in self._last_status and marking self._finished if done.
40
- """
41
- url = self.result_endpoint.format(task_id=self.task_id)
42
- resp = request("GET", url)
43
- data = resp.json()
44
-
45
- status_ = data.get("status")
46
- self._last_status = status_
47
-
48
- if status_ == "PENDING":
49
- # still running
50
- pass
51
- elif status_ == "SUCCESS":
52
- self._finished = True
53
- self._last_result = data.get("result") or data.get("data")
54
- elif status_ == "FAILURE":
55
- self._finished = True
56
- self._last_result = data.get("error")
57
- else:
58
- # Some other custom statuses
59
- # We'll treat them like "still running"
60
- pass
61
-
62
- def wait(self, interval=2, timeout=300):
63
- """
64
- Poll in a loop until the task finishes or times out.
65
- Returns the final result on success, or raises an exception on failure or timeout.
66
- """
67
- start = time.time()
68
- while True:
69
- self.poll()
70
- if self._finished:
71
- break
72
- if time.time() - start > timeout:
73
- raise TimeoutError(f"Task {self.task_id} did not complete within {timeout} seconds.")
74
- time.sleep(interval)
75
-
76
- if self._last_status == "SUCCESS":
77
- return self._last_result
78
- else:
79
- raise RuntimeError(f"Task {self.task_id} failed with error: {self._last_result}")
@@ -1,8 +0,0 @@
1
- # simile/utils.py
2
- """
3
- Optional helper functions. You might or might not need this, depending on how you structure your code.
4
- For now, it's just a placeholder.
5
- """
6
-
7
- def example_helper():
8
- pass
@@ -1,41 +0,0 @@
1
- Metadata-Version: 2.2
2
- Name: simile
3
- Version: 0.1.0
4
- Summary: A Python client library for interacting with my Agent & Population endpoints
5
- Home-page: https://github.com/simile-team/simile
6
- Author: Joon Sung Park
7
- Author-email: joon.s.pk@gmail.com
8
- Classifier: Programming Language :: Python :: 3
9
- Classifier: License :: OSI Approved :: MIT License
10
- Classifier: Operating System :: OS Independent
11
- Requires-Python: >=3.7
12
- Description-Content-Type: text/markdown
13
- License-File: LICENSE
14
- Requires-Dist: requests>=2.22.0
15
- Requires-Dist: urllib3>=1.26.0
16
- Dynamic: author
17
- Dynamic: author-email
18
- Dynamic: classifier
19
- Dynamic: description
20
- Dynamic: description-content-type
21
- Dynamic: home-page
22
- Dynamic: requires-dist
23
- Dynamic: requires-python
24
- Dynamic: summary
25
-
26
- # Simile
27
-
28
- **Simile** is a Python client library for interacting with your Agent & Population endpoints. It provides a simple interface for creating and managing agents, managing populations, and performing asynchronous tasks such as generating agent responses or creating sub-populations.
29
-
30
- ## Features
31
-
32
- - **Agent Management**: Create, delete, retrieve details for agents.
33
- - **Population Management**: Create populations, add/remove agents, delete, or create sub-populations.
34
- - **Asynchronous Tasks**: Returns a `Task` object that can be polled or waited upon for long-running operations.
35
-
36
- ## Installation
37
-
38
- Install via **pip** (once you've published to PyPI):
39
-
40
- ```bash
41
- pip install simile
@@ -1,17 +0,0 @@
1
- LICENSE
2
- MANIFEST.in
3
- README.md
4
- setup.py
5
- simile/__init__.py
6
- simile/api_requestor.py
7
- simile/config.py
8
- simile/error.py
9
- simile/resource_agent.py
10
- simile/resource_population.py
11
- simile/task.py
12
- simile/utils.py
13
- simile.egg-info/PKG-INFO
14
- simile.egg-info/SOURCES.txt
15
- simile.egg-info/dependency_links.txt
16
- simile.egg-info/requires.txt
17
- simile.egg-info/top_level.txt
@@ -1,2 +0,0 @@
1
- requests>=2.22.0
2
- urllib3>=1.26.0
File without changes