futurehouse-client 0.3.20.dev295__tar.gz → 0.4.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.
- {futurehouse_client-0.3.20.dev295/futurehouse_client.egg-info → futurehouse_client-0.4.0}/PKG-INFO +1 -1
- {futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/futurehouse_client/clients/rest_client.py +137 -4
- {futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/futurehouse_client/models/rest.py +14 -0
- {futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/futurehouse_client/version.py +16 -3
- {futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0/futurehouse_client.egg-info}/PKG-INFO +1 -1
- {futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/tests/test_rest.py +3 -0
- {futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/LICENSE +0 -0
- {futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/README.md +0 -0
- {futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/docs/__init__.py +0 -0
- {futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/docs/client_notebook.ipynb +0 -0
- {futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/futurehouse_client/__init__.py +0 -0
- {futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/futurehouse_client/clients/__init__.py +0 -0
- {futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/futurehouse_client/clients/job_client.py +0 -0
- {futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/futurehouse_client/models/__init__.py +0 -0
- {futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/futurehouse_client/models/app.py +0 -0
- {futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/futurehouse_client/models/client.py +0 -0
- {futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/futurehouse_client/py.typed +0 -0
- {futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/futurehouse_client/utils/__init__.py +0 -0
- {futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/futurehouse_client/utils/auth.py +0 -0
- {futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/futurehouse_client/utils/general.py +0 -0
- {futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/futurehouse_client/utils/module_utils.py +0 -0
- {futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/futurehouse_client/utils/monitoring.py +0 -0
- {futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/futurehouse_client.egg-info/SOURCES.txt +0 -0
- {futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/futurehouse_client.egg-info/dependency_links.txt +0 -0
- {futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/futurehouse_client.egg-info/requires.txt +0 -0
- {futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/futurehouse_client.egg-info/top_level.txt +0 -0
- {futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/pyproject.toml +0 -0
- {futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/setup.cfg +0 -0
- {futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/tests/test_client.py +0 -0
@@ -58,6 +58,7 @@ from futurehouse_client.models.app import (
|
|
58
58
|
TrajectoryQueryParams,
|
59
59
|
)
|
60
60
|
from futurehouse_client.models.rest import (
|
61
|
+
DiscoveryResponse,
|
61
62
|
ExecutionStatus,
|
62
63
|
UserAgentRequest,
|
63
64
|
UserAgentRequestPostPayload,
|
@@ -139,6 +140,14 @@ class ProjectError(RestClientError):
|
|
139
140
|
"""Raised when there's an error with trajectory group operations."""
|
140
141
|
|
141
142
|
|
143
|
+
class DiscoveryCreationError(RestClientError):
|
144
|
+
"""Raised when there's an error creating a discovery."""
|
145
|
+
|
146
|
+
|
147
|
+
class DiscoveryFetchError(RestClientError):
|
148
|
+
"""Raised when there's an error fetching a discovery."""
|
149
|
+
|
150
|
+
|
142
151
|
class InvalidTaskDescriptionError(Exception):
|
143
152
|
"""Raised when the task description is invalid or empty."""
|
144
153
|
|
@@ -1737,11 +1746,18 @@ class RestClient:
|
|
1737
1746
|
wait=wait_exponential(multiplier=RETRY_MULTIPLIER, max=MAX_RETRY_WAIT),
|
1738
1747
|
retry=retry_if_connection_error,
|
1739
1748
|
)
|
1740
|
-
def create_project(
|
1749
|
+
def create_project(
|
1750
|
+
self,
|
1751
|
+
name: str,
|
1752
|
+
shared_with_organizations: list[int] | None = None,
|
1753
|
+
shared_with_users: list[str] | None = None,
|
1754
|
+
) -> str:
|
1741
1755
|
"""Create a new project.
|
1742
1756
|
|
1743
1757
|
Args:
|
1744
1758
|
name: The name for the project
|
1759
|
+
shared_with_organizations: List of organization IDs to share the project with
|
1760
|
+
shared_with_users: List of user emails to share the project with
|
1745
1761
|
|
1746
1762
|
Returns:
|
1747
1763
|
UUID of the created project
|
@@ -1750,7 +1766,11 @@ class RestClient:
|
|
1750
1766
|
ProjectError: If there's an error creating the project
|
1751
1767
|
"""
|
1752
1768
|
try:
|
1753
|
-
data = {
|
1769
|
+
data = {
|
1770
|
+
"name": name,
|
1771
|
+
"shared_with_organizations": shared_with_organizations,
|
1772
|
+
"shared_with_users": shared_with_users,
|
1773
|
+
}
|
1754
1774
|
response = self.client.post("/v0.1/projects", json=data)
|
1755
1775
|
response.raise_for_status()
|
1756
1776
|
return response.json()
|
@@ -1802,11 +1822,18 @@ class RestClient:
|
|
1802
1822
|
wait=wait_exponential(multiplier=RETRY_MULTIPLIER, max=MAX_RETRY_WAIT),
|
1803
1823
|
retry=retry_if_connection_error,
|
1804
1824
|
)
|
1805
|
-
async def acreate_project(
|
1825
|
+
async def acreate_project(
|
1826
|
+
self,
|
1827
|
+
name: str,
|
1828
|
+
shared_with_organizations: list[int] | None = None,
|
1829
|
+
shared_with_users: list[str] | None = None,
|
1830
|
+
) -> str:
|
1806
1831
|
"""Asynchronously create a new project.
|
1807
1832
|
|
1808
1833
|
Args:
|
1809
1834
|
name: The name for the project
|
1835
|
+
shared_with_organizations: List of organization IDs to share the project with
|
1836
|
+
shared_with_users: List of user emails to share the project with
|
1810
1837
|
|
1811
1838
|
Returns:
|
1812
1839
|
UUID of the created project
|
@@ -1815,7 +1842,11 @@ class RestClient:
|
|
1815
1842
|
ProjectError: If there's an error creating the project
|
1816
1843
|
"""
|
1817
1844
|
try:
|
1818
|
-
data = {
|
1845
|
+
data = {
|
1846
|
+
"name": name,
|
1847
|
+
"shared_with_organizations": shared_with_organizations,
|
1848
|
+
"shared_with_users": shared_with_users,
|
1849
|
+
}
|
1819
1850
|
response = await self.async_client.post("/v0.1/projects", json=data)
|
1820
1851
|
response.raise_for_status()
|
1821
1852
|
return response.json()
|
@@ -2326,6 +2357,108 @@ class RestClient:
|
|
2326
2357
|
f"An unexpected error occurred while responding to the request: {e!r}."
|
2327
2358
|
) from e
|
2328
2359
|
|
2360
|
+
def create_discovery(
|
2361
|
+
self,
|
2362
|
+
project_id: UUID,
|
2363
|
+
world_model_id: UUID,
|
2364
|
+
dataset_id: UUID,
|
2365
|
+
description: str,
|
2366
|
+
associated_trajectories: list[UUID],
|
2367
|
+
validation_level: int,
|
2368
|
+
) -> UUID:
|
2369
|
+
"""Create a new discovery.
|
2370
|
+
|
2371
|
+
Args:
|
2372
|
+
project_id: The ID of the project the discovery is associated with.
|
2373
|
+
world_model_id: The ID of the world model the discovery is associated with.
|
2374
|
+
dataset_id: The ID of the dataset the discovery is associated with.
|
2375
|
+
description: The description of the discovery.
|
2376
|
+
associated_trajectories: The IDs of the trajectories to associate with the discovery.
|
2377
|
+
validation_level: The validation level of the discovery.
|
2378
|
+
|
2379
|
+
Returns:
|
2380
|
+
The ID of the created discovery.
|
2381
|
+
|
2382
|
+
Raises:
|
2383
|
+
DiscoveryCreationError: If there's an error creating the discovery.
|
2384
|
+
"""
|
2385
|
+
try:
|
2386
|
+
data = {
|
2387
|
+
"project_id": str(project_id),
|
2388
|
+
"world_model_id": str(world_model_id),
|
2389
|
+
"dataset_id": str(dataset_id),
|
2390
|
+
"description": description,
|
2391
|
+
"associated_trajectories": [
|
2392
|
+
str(trajectory) for trajectory in associated_trajectories
|
2393
|
+
],
|
2394
|
+
"validation_level": validation_level,
|
2395
|
+
}
|
2396
|
+
response = self.client.post("/v0.1/discoveries", json=data)
|
2397
|
+
response.raise_for_status()
|
2398
|
+
return UUID(response.json())
|
2399
|
+
except HTTPStatusError as e:
|
2400
|
+
raise DiscoveryCreationError(
|
2401
|
+
f"Error creating discovery: {e.response.status_code} - {e.response.text}"
|
2402
|
+
) from e
|
2403
|
+
except Exception as e:
|
2404
|
+
raise DiscoveryCreationError(f"Error creating discovery: {e!r}") from e
|
2405
|
+
|
2406
|
+
def get_discovery(self, discovery_id: UUID) -> DiscoveryResponse:
|
2407
|
+
"""Get a discovery by its ID.
|
2408
|
+
|
2409
|
+
Args:
|
2410
|
+
discovery_id: The ID of the discovery to get.
|
2411
|
+
|
2412
|
+
Returns:
|
2413
|
+
The discovery.
|
2414
|
+
|
2415
|
+
Raises:
|
2416
|
+
DiscoveryFetchError: If there's an error fetching the discovery.
|
2417
|
+
"""
|
2418
|
+
try:
|
2419
|
+
response = self.client.get(f"/v0.1/discoveries/{discovery_id}")
|
2420
|
+
response.raise_for_status()
|
2421
|
+
return DiscoveryResponse.model_validate(response.json())
|
2422
|
+
except HTTPStatusError as e:
|
2423
|
+
raise DiscoveryFetchError(
|
2424
|
+
f"Error fetching discovery: {e.response.status_code} - {e.response.text}"
|
2425
|
+
) from e
|
2426
|
+
except Exception as e:
|
2427
|
+
raise DiscoveryFetchError(f"Error fetching discovery: {e!r}") from e
|
2428
|
+
|
2429
|
+
def list_discoveries_for_project(
|
2430
|
+
self, project_id: UUID, limit: int = 50, offset: int = 0
|
2431
|
+
) -> list[DiscoveryResponse]:
|
2432
|
+
"""List discoveries for a specific project.
|
2433
|
+
|
2434
|
+
Args:
|
2435
|
+
project_id: The ID of the project to get discoveries for.
|
2436
|
+
limit: The maximum number of discoveries to return.
|
2437
|
+
offset: The number of discoveries to skip.
|
2438
|
+
|
2439
|
+
Returns:
|
2440
|
+
A list of discoveries for the specified project.
|
2441
|
+
|
2442
|
+
Raises:
|
2443
|
+
DiscoveryFetchError: If there's an error fetching the discoveries.
|
2444
|
+
"""
|
2445
|
+
try:
|
2446
|
+
response = self.client.get(
|
2447
|
+
f"/v0.1/projects/{project_id}/discoveries",
|
2448
|
+
params={"limit": limit, "offset": offset},
|
2449
|
+
)
|
2450
|
+
response.raise_for_status()
|
2451
|
+
data = response.json()
|
2452
|
+
return [DiscoveryResponse.model_validate(d) for d in data]
|
2453
|
+
except HTTPStatusError as e:
|
2454
|
+
raise DiscoveryFetchError(
|
2455
|
+
f"Error fetching discoveries for project: {e.response.status_code} - {e.response.text}"
|
2456
|
+
) from e
|
2457
|
+
except Exception as e:
|
2458
|
+
raise DiscoveryFetchError(
|
2459
|
+
f"Error fetching discoveries for project: {e!r}"
|
2460
|
+
) from e
|
2461
|
+
|
2329
2462
|
|
2330
2463
|
def get_installed_packages() -> dict[str, str]:
|
2331
2464
|
"""Returns a dictionary of installed packages and their versions."""
|
{futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/futurehouse_client/models/rest.py
RENAMED
@@ -111,6 +111,7 @@ class UserAgentRequestPostPayload(BaseModel):
|
|
111
111
|
status: UserAgentRequestStatus = UserAgentRequestStatus.PENDING
|
112
112
|
expires_in_seconds: int | None = None
|
113
113
|
user_response_task: JsonValue | None = None
|
114
|
+
notify_user: JsonValue = {"email": True, "sms": False}
|
114
115
|
|
115
116
|
|
116
117
|
class UserAgentResponsePayload(BaseModel):
|
@@ -118,3 +119,16 @@ class UserAgentResponsePayload(BaseModel):
|
|
118
119
|
|
119
120
|
response: JsonValue
|
120
121
|
response_world_model_edit_id: UUID | None = None
|
122
|
+
|
123
|
+
|
124
|
+
class DiscoveryResponse(BaseModel):
|
125
|
+
"""Response model for a discovery request. This model is received from the API."""
|
126
|
+
|
127
|
+
discovery_id: UUID | str
|
128
|
+
project_id: UUID | str
|
129
|
+
world_model_id: UUID | str
|
130
|
+
dataset_id: UUID | str
|
131
|
+
description: str
|
132
|
+
associated_trajectories: list[UUID | str]
|
133
|
+
validation_level: int
|
134
|
+
created_at: datetime
|
@@ -1,7 +1,14 @@
|
|
1
1
|
# file generated by setuptools-scm
|
2
2
|
# don't change, don't track in version control
|
3
3
|
|
4
|
-
__all__ = [
|
4
|
+
__all__ = [
|
5
|
+
"__version__",
|
6
|
+
"__version_tuple__",
|
7
|
+
"version",
|
8
|
+
"version_tuple",
|
9
|
+
"__commit_id__",
|
10
|
+
"commit_id",
|
11
|
+
]
|
5
12
|
|
6
13
|
TYPE_CHECKING = False
|
7
14
|
if TYPE_CHECKING:
|
@@ -9,13 +16,19 @@ if TYPE_CHECKING:
|
|
9
16
|
from typing import Union
|
10
17
|
|
11
18
|
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
19
|
+
COMMIT_ID = Union[str, None]
|
12
20
|
else:
|
13
21
|
VERSION_TUPLE = object
|
22
|
+
COMMIT_ID = object
|
14
23
|
|
15
24
|
version: str
|
16
25
|
__version__: str
|
17
26
|
__version_tuple__: VERSION_TUPLE
|
18
27
|
version_tuple: VERSION_TUPLE
|
28
|
+
commit_id: COMMIT_ID
|
29
|
+
__commit_id__: COMMIT_ID
|
19
30
|
|
20
|
-
__version__ = version = '0.
|
21
|
-
__version_tuple__ = version_tuple = (0,
|
31
|
+
__version__ = version = '0.4.0'
|
32
|
+
__version_tuple__ = version_tuple = (0, 4, 0)
|
33
|
+
|
34
|
+
__commit_id__ = commit_id = 'g5229864ab'
|
@@ -978,6 +978,7 @@ class TestUserAgentRequestOperations:
|
|
978
978
|
payload = UserAgentRequestPostPayload(
|
979
979
|
trajectory_id=running_trajectory_id,
|
980
980
|
request={"question": "Do you approve?"},
|
981
|
+
notify_user={"email": False, "sms": False}, # avoid sending notifications
|
981
982
|
)
|
982
983
|
request_id = admin_client.create_user_agent_request(payload)
|
983
984
|
assert isinstance(request_id, UUID)
|
@@ -1045,6 +1046,7 @@ class TestAsyncUserAgentRequestOperations:
|
|
1045
1046
|
query="Why would I follow up on this query?",
|
1046
1047
|
).model_dump(mode="json"),
|
1047
1048
|
expires_in_seconds=10,
|
1049
|
+
notify_user={"email": False, "sms": False}, # avoid sending notifications
|
1048
1050
|
)
|
1049
1051
|
|
1050
1052
|
request_id = await admin_client.acreate_user_agent_request(payload)
|
@@ -1097,6 +1099,7 @@ class TestAsyncUserAgentRequestOperations:
|
|
1097
1099
|
name=JobNames.from_string("dummy"),
|
1098
1100
|
query="Why would I follow up on this query?",
|
1099
1101
|
).model_dump(mode="json"),
|
1102
|
+
notify_user={"email": False, "sms": False}, # avoid sending notifications
|
1100
1103
|
)
|
1101
1104
|
|
1102
1105
|
request_id = await admin_client.acreate_user_agent_request(payload)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/futurehouse_client/__init__.py
RENAMED
File without changes
|
{futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/futurehouse_client/clients/__init__.py
RENAMED
File without changes
|
File without changes
|
{futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/futurehouse_client/models/__init__.py
RENAMED
File without changes
|
{futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/futurehouse_client/models/app.py
RENAMED
File without changes
|
{futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/futurehouse_client/models/client.py
RENAMED
File without changes
|
File without changes
|
{futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/futurehouse_client/utils/__init__.py
RENAMED
File without changes
|
{futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/futurehouse_client/utils/auth.py
RENAMED
File without changes
|
{futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/futurehouse_client/utils/general.py
RENAMED
File without changes
|
File without changes
|
{futurehouse_client-0.3.20.dev295 → futurehouse_client-0.4.0}/futurehouse_client/utils/monitoring.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|