futurehouse-client 0.5.0__tar.gz → 0.5.2__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.
Files changed (39) hide show
  1. {futurehouse_client-0.5.0/src/futurehouse_client.egg-info → futurehouse_client-0.5.2}/PKG-INFO +1 -2
  2. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/pyproject.toml +0 -1
  3. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/src/futurehouse_client/clients/data_storage_methods.py +1 -1
  4. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/src/futurehouse_client/clients/rest_client.py +35 -12
  5. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/src/futurehouse_client/models/app.py +16 -0
  6. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/src/futurehouse_client/models/data_storage_methods.py +1 -12
  7. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/src/futurehouse_client/version.py +3 -3
  8. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2/src/futurehouse_client.egg-info}/PKG-INFO +1 -2
  9. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/src/futurehouse_client.egg-info/requires.txt +0 -1
  10. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/tests/test_rest.py +3 -0
  11. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/LICENSE +0 -0
  12. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/README.md +0 -0
  13. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/data_storage.md +0 -0
  14. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/docs/__init__.py +0 -0
  15. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/docs/client_notebook.ipynb +0 -0
  16. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/setup.cfg +0 -0
  17. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/src/futurehouse_client/__init__.py +0 -0
  18. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/src/futurehouse_client/clients/__init__.py +0 -0
  19. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/src/futurehouse_client/clients/job_client.py +0 -0
  20. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/src/futurehouse_client/models/__init__.py +0 -0
  21. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/src/futurehouse_client/models/client.py +0 -0
  22. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/src/futurehouse_client/models/job_event.py +0 -0
  23. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/src/futurehouse_client/models/rest.py +0 -0
  24. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/src/futurehouse_client/py.typed +0 -0
  25. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/src/futurehouse_client/utils/__init__.py +0 -0
  26. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/src/futurehouse_client/utils/auth.py +0 -0
  27. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/src/futurehouse_client/utils/general.py +0 -0
  28. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/src/futurehouse_client/utils/module_utils.py +0 -0
  29. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/src/futurehouse_client/utils/monitoring.py +0 -0
  30. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/src/futurehouse_client/utils/world_model_tools.py +0 -0
  31. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/src/futurehouse_client.egg-info/SOURCES.txt +0 -0
  32. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/src/futurehouse_client.egg-info/dependency_links.txt +0 -0
  33. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/src/futurehouse_client.egg-info/top_level.txt +0 -0
  34. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/tests/test_client.py +0 -0
  35. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/tests/test_data/test_file.txt +0 -0
  36. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/tests/test_data/test_information.txt +0 -0
  37. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/tests/test_data/test_manifest.yaml +0 -0
  38. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/tests/test_data_storage_e2e.py +0 -0
  39. {futurehouse_client-0.5.0 → futurehouse_client-0.5.2}/tests/test_data_storage_methods.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: futurehouse-client
3
- Version: 0.5.0
3
+ Version: 0.5.2
4
4
  Summary: A client for interacting with endpoints of the FutureHouse service.
5
5
  Author-email: FutureHouse technical staff <hello@futurehouse.org>
6
6
  License: Apache License
@@ -224,7 +224,6 @@ Requires-Dist: openai<1.100.0,>=1
224
224
  Requires-Dist: pydantic
225
225
  Requires-Dist: python-dotenv
226
226
  Requires-Dist: requests
227
- Requires-Dist: sqlalchemy-utils>=0.41.2
228
227
  Requires-Dist: tenacity
229
228
  Requires-Dist: tqdm>=4.62
230
229
  Provides-Extra: dev
@@ -28,7 +28,6 @@ dependencies = [
28
28
  "pydantic",
29
29
  "python-dotenv",
30
30
  "requests",
31
- "sqlalchemy-utils>=0.41.2",
32
31
  "tenacity",
33
32
  "tqdm>=4.62", # For tqdm.asyncio stdlib consistency
34
33
  ]
@@ -2514,7 +2514,7 @@ class DataStorageMethods:
2514
2514
  return self._download_from_gcs(
2515
2515
  storage_location.storage_config.signed_url,
2516
2516
  (
2517
- storage_location.storage_config.location.split("/")[-1]
2517
+ Path(storage_location.storage_config.location).name
2518
2518
  if storage_location.storage_config.location
2519
2519
  else None
2520
2520
  ),
@@ -46,6 +46,7 @@ from futurehouse_client.clients.data_storage_methods import DataStorageMethods
46
46
  from futurehouse_client.models.app import (
47
47
  AuthType,
48
48
  JobDeploymentConfig,
49
+ LiteTaskResponse,
49
50
  Stage,
50
51
  TaskRequest,
51
52
  TaskResponse,
@@ -530,8 +531,12 @@ class RestClient(DataStorageMethods):
530
531
  before_sleep=before_sleep_log(logger, logging.WARNING),
531
532
  )
532
533
  def get_task(
533
- self, task_id: str | None = None, history: bool = False, verbose: bool = False
534
- ) -> "TaskResponse":
534
+ self,
535
+ task_id: str | None = None,
536
+ history: bool = False,
537
+ verbose: bool = False,
538
+ lite: bool = False,
539
+ ) -> "TaskResponse | LiteTaskResponse":
535
540
  """Get details for a specific task."""
536
541
  task_id = task_id or self.trajectory_id
537
542
  url = f"/v0.1/trajectories/{task_id}"
@@ -547,7 +552,9 @@ class RestClient(DataStorageMethods):
547
552
  "job_id": task_id,
548
553
  },
549
554
  ),
550
- self.client.stream("GET", url, params={"history": history}) as response,
555
+ self.client.stream(
556
+ "GET", url, params={"history": history, "lite": lite}
557
+ ) as response,
551
558
  ):
552
559
  if response.status_code in {401, 403}:
553
560
  raise PermissionError(
@@ -558,6 +565,10 @@ class RestClient(DataStorageMethods):
558
565
  data = json.loads(json_data)
559
566
  if "id" not in data:
560
567
  data["id"] = task_id
568
+
569
+ if lite:
570
+ return LiteTaskResponse(**data)
571
+
561
572
  verbose_response = TaskResponseVerbose(**data)
562
573
 
563
574
  if verbose:
@@ -571,8 +582,12 @@ class RestClient(DataStorageMethods):
571
582
  before_sleep=before_sleep_log(logger, logging.WARNING),
572
583
  )
573
584
  async def aget_task(
574
- self, task_id: str | None = None, history: bool = False, verbose: bool = False
575
- ) -> "TaskResponse":
585
+ self,
586
+ task_id: str | None = None,
587
+ history: bool = False,
588
+ verbose: bool = False,
589
+ lite: bool = False,
590
+ ) -> "TaskResponse | LiteTaskResponse":
576
591
  """Get details for a specific task asynchronously."""
577
592
  task_id = task_id or self.trajectory_id
578
593
  url = f"/v0.1/trajectories/{task_id}"
@@ -588,7 +603,7 @@ class RestClient(DataStorageMethods):
588
603
  },
589
604
  ):
590
605
  async with self.async_client.stream(
591
- "GET", url, params={"history": history}
606
+ "GET", url, params={"history": history, "lite": lite}
592
607
  ) as response:
593
608
  if response.status_code in {401, 403}:
594
609
  raise PermissionError(
@@ -599,6 +614,10 @@ class RestClient(DataStorageMethods):
599
614
  data = json.loads(json_data)
600
615
  if "id" not in data:
601
616
  data["id"] = task_id
617
+
618
+ if lite:
619
+ return LiteTaskResponse(**data)
620
+
602
621
  verbose_response = TaskResponseVerbose(**data)
603
622
 
604
623
  if verbose:
@@ -735,7 +754,9 @@ class RestClient(DataStorageMethods):
735
754
  progress_bar: bool = False,
736
755
  concurrency: int = 10,
737
756
  timeout: int = DEFAULT_AGENT_TIMEOUT,
738
- ) -> list[TaskResponse]:
757
+ ) -> list[
758
+ LiteTaskResponse | TaskResponse
759
+ ]: # return will always be lite because we always call with lite=True
739
760
  all_tasks: Collection[TaskRequest | dict[str, Any]] = (
740
761
  cast(Collection[TaskRequest | dict[str, Any]], [task_data])
741
762
  if (isinstance(task_data, dict) or not isinstance(task_data, Collection))
@@ -749,7 +770,7 @@ class RestClient(DataStorageMethods):
749
770
  )
750
771
 
751
772
  start_time = time.monotonic()
752
- completed_tasks: dict[str, TaskResponse] = {}
773
+ completed_tasks: dict[str, LiteTaskResponse | TaskResponse] = {}
753
774
 
754
775
  if progress_bar:
755
776
  progress = tqdm(
@@ -760,7 +781,7 @@ class RestClient(DataStorageMethods):
760
781
  task_results = await gather_with_concurrency(
761
782
  concurrency,
762
783
  [
763
- self.aget_task(task_id, verbose=verbose)
784
+ self.aget_task(task_id, verbose=verbose, lite=True)
764
785
  for task_id in trajectory_ids
765
786
  if task_id not in completed_tasks
766
787
  ],
@@ -807,7 +828,9 @@ class RestClient(DataStorageMethods):
807
828
  verbose: bool = False,
808
829
  progress_bar: bool = False,
809
830
  timeout: int = DEFAULT_AGENT_TIMEOUT,
810
- ) -> list[TaskResponse]:
831
+ ) -> list[
832
+ LiteTaskResponse | TaskResponse
833
+ ]: # return will always be lite because we always call with lite=True
811
834
  """Run multiple tasks and wait for them to complete.
812
835
 
813
836
  Args:
@@ -828,7 +851,7 @@ class RestClient(DataStorageMethods):
828
851
  trajectory_ids = [self.create_task(task) for task in all_tasks]
829
852
 
830
853
  start_time = time.monotonic()
831
- completed_tasks: dict[str, TaskResponse] = {}
854
+ completed_tasks: dict[str, LiteTaskResponse | TaskResponse] = {}
832
855
 
833
856
  if progress_bar:
834
857
  progress = sync_tqdm(
@@ -842,7 +865,7 @@ class RestClient(DataStorageMethods):
842
865
  if task_id in completed_tasks:
843
866
  continue
844
867
 
845
- task = self.get_task(task_id, verbose=verbose)
868
+ task = self.get_task(task_id, verbose=verbose, lite=True)
846
869
 
847
870
  if not ExecutionStatus(task.status).is_terminal_state():
848
871
  all_done = False
@@ -749,6 +749,22 @@ class SimpleOrganization(BaseModel):
749
749
  display_name: str
750
750
 
751
751
 
752
+ class LiteTaskResponse(BaseModel):
753
+ task_id: UUID = Field(description="Identifier for a trajectory")
754
+ query: str = Field(description="Query executed for the trajectory")
755
+ status: str = Field(description="Current status of the trajectory")
756
+
757
+ @model_validator(mode="before")
758
+ @classmethod
759
+ def validate_fields(cls, original_data: Mapping[str, Any]) -> Mapping[str, Any]:
760
+ data = copy.deepcopy(original_data) # Avoid mutating the original data
761
+ if not isinstance(data, dict):
762
+ return data
763
+ data["query"] = data.get("task", data.get("query"))
764
+ data["task_id"] = cast(UUID, data.get("id", data.get("task_id")))
765
+ return data
766
+
767
+
752
768
  class TaskResponse(BaseModel):
753
769
  """Base class for task responses. This holds attributes shared over all futurehouse jobs."""
754
770
 
@@ -3,25 +3,14 @@ from datetime import datetime
3
3
  from enum import StrEnum, auto
4
4
  from os import PathLike
5
5
  from pathlib import Path
6
- from typing import Annotated, Any
6
+ from typing import Any
7
7
  from uuid import UUID
8
8
 
9
9
  from pydantic import (
10
10
  BaseModel,
11
11
  Field,
12
12
  JsonValue,
13
- PlainSerializer,
14
- PlainValidator,
15
- WithJsonSchema,
16
13
  )
17
- from sqlalchemy_utils import Ltree
18
-
19
- LtreeField = Annotated[
20
- Ltree,
21
- PlainValidator(Ltree),
22
- PlainSerializer(lambda v: v.path),
23
- WithJsonSchema({"type": "string", "examples": ["some.path"]}),
24
- ]
25
14
 
26
15
 
27
16
  class DataStorageEntryStatus(StrEnum):
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '0.5.0'
32
- __version_tuple__ = version_tuple = (0, 5, 0)
31
+ __version__ = version = '0.5.2'
32
+ __version_tuple__ = version_tuple = (0, 5, 2)
33
33
 
34
- __commit_id__ = commit_id = 'gdcf18bc98'
34
+ __commit_id__ = commit_id = 'ga56210327'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: futurehouse-client
3
- Version: 0.5.0
3
+ Version: 0.5.2
4
4
  Summary: A client for interacting with endpoints of the FutureHouse service.
5
5
  Author-email: FutureHouse technical staff <hello@futurehouse.org>
6
6
  License: Apache License
@@ -224,7 +224,6 @@ Requires-Dist: openai<1.100.0,>=1
224
224
  Requires-Dist: pydantic
225
225
  Requires-Dist: python-dotenv
226
226
  Requires-Dist: requests
227
- Requires-Dist: sqlalchemy-utils>=0.41.2
228
227
  Requires-Dist: tenacity
229
228
  Requires-Dist: tqdm>=4.62
230
229
  Provides-Extra: dev
@@ -9,7 +9,6 @@ openai<1.100.0,>=1
9
9
  pydantic
10
10
  python-dotenv
11
11
  requests
12
- sqlalchemy-utils>=0.41.2
13
12
  tenacity
14
13
  tqdm>=4.62
15
14
 
@@ -39,6 +39,7 @@ from futurehouse_client.clients.rest_client import (
39
39
  UserAgentRequestFetchError,
40
40
  )
41
41
  from futurehouse_client.models.app import (
42
+ LiteTaskResponse,
42
43
  PhoenixTaskResponse,
43
44
  PQATaskResponse,
44
45
  Stage,
@@ -150,10 +151,12 @@ async def test_job_response( # noqa: PLR0915
150
151
  with subtests.test("Test TaskResponse with queued task"):
151
152
  task_response = admin_client.get_task(task_id)
152
153
  assert task_response.status in {"queued", "in progress"}
154
+ assert not isinstance(task_response, LiteTaskResponse)
153
155
  assert task_response.job_name == pqa_task_req.name
154
156
  assert task_response.query == pqa_task_req.query
155
157
  task_response = await admin_client.aget_task(atask_id)
156
158
  assert task_response.status in {"queued", "in progress"}
159
+ assert not isinstance(task_response, LiteTaskResponse)
157
160
  assert task_response.job_name == pqa_task_req.name
158
161
  assert task_response.query == pqa_task_req.query
159
162