futurehouse-client 0.5.0__py3-none-any.whl → 0.5.2__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.
@@ -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
34
  __commit_id__ = commit_id = None
@@ -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
@@ -1,14 +1,14 @@
1
1
  futurehouse_client/__init__.py,sha256=q5cpcuPkhTaueXsySsgWpH0F-2EsRxcdJfP91ze6khU,991
2
2
  futurehouse_client/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- futurehouse_client/version.py,sha256=fvHpBU3KZKRinkriKdtAt3crenOyysELF-M9y3ozg3U,704
3
+ futurehouse_client/version.py,sha256=LGYtjQ6cyPZC_N0AovMIeSYYDK21050nm3HYgDanQBM,704
4
4
  futurehouse_client/clients/__init__.py,sha256=-HXNj-XJ3LRO5XM6MZ709iPs29YpApss0Q2YYg1qMZw,280
5
- futurehouse_client/clients/data_storage_methods.py,sha256=wnKu8CazlEX_BQauX1qvZRRw7EpbD0oofmH1wXLnDf8,120034
5
+ futurehouse_client/clients/data_storage_methods.py,sha256=eBbGdxUmk-QGmLveuwdZd4LjsElhJxJGsvu4q-MoTGY,120030
6
6
  futurehouse_client/clients/job_client.py,sha256=b5gpzulZpxpv9R337r3UKItnMdtd6CGlI1sV3_VQJso,13985
7
- futurehouse_client/clients/rest_client.py,sha256=tLskIkiR6-Acbo2W1_UUNdIjiYfZMURaN_Mi0aJPWXg,110277
7
+ futurehouse_client/clients/rest_client.py,sha256=LI8-F4cUcv8gnWhI06NB0k6iMnfDZVKv9Uh0FfXiDwo,110915
8
8
  futurehouse_client/models/__init__.py,sha256=N1MwDUYonsMN9NdaShsYcJspyL7H756MYj7VWFeD3fk,978
9
- futurehouse_client/models/app.py,sha256=UUg17I3zk6cH_7mrdojHGYvQfm_SeDkuUxsPlRyIYz0,31895
9
+ futurehouse_client/models/app.py,sha256=2bFtQY1wl9oZM5Gyx1NrybKC9-fKzk20YRu20h2LiHY,32581
10
10
  futurehouse_client/models/client.py,sha256=554vp7Cr-17BTeRZtN5DhCRQesRRtr31ZPkHXUrhyCE,3835
11
- futurehouse_client/models/data_storage_methods.py,sha256=cpF2g4y_REECaz--WhaJeLqXA_3m3keRP5XOXiL8GOI,13811
11
+ futurehouse_client/models/data_storage_methods.py,sha256=tqLBEPXyyvLNVLU167_EiEnzT8AiMWeL3Fga1HpLg5o,13533
12
12
  futurehouse_client/models/job_event.py,sha256=lMrx-lV7BQkKl419ErWZ6Q1EjurmhBFSns0z6zwGaVo,2766
13
13
  futurehouse_client/models/rest.py,sha256=SbeXZSPUCM0lQ_gVUPa64vKzMxuUVgqmJ5YThfDWs8g,4726
14
14
  futurehouse_client/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -17,8 +17,8 @@ futurehouse_client/utils/general.py,sha256=PIkGLCSA3kUvc6mwR-prEB7YnMdKILOIm6cPo
17
17
  futurehouse_client/utils/module_utils.py,sha256=aFyd-X-pDARXz9GWpn8SSViUVYdSbuy9vSkrzcVIaGI,4955
18
18
  futurehouse_client/utils/monitoring.py,sha256=UjRlufe67kI3VxRHOd5fLtJmlCbVA2Wqwpd4uZhXkQM,8728
19
19
  futurehouse_client/utils/world_model_tools.py,sha256=v2krZGrco0ur2a_pcRMtnQL05SxlIoBXuJ5R1JkQNws,2921
20
- futurehouse_client-0.5.0.dist-info/licenses/LICENSE,sha256=oQ9ZHjUi-_6GfP3gs14FlPb0OlGwE1QCCKFGnJ4LD2I,11341
21
- futurehouse_client-0.5.0.dist-info/METADATA,sha256=4lMUB0HZPj5tBCb2l5QxCwjBzk9KtOG73V_zNxui_ug,27094
22
- futurehouse_client-0.5.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
23
- futurehouse_client-0.5.0.dist-info/top_level.txt,sha256=TRuLUCt_qBnggdFHCX4O_BoCu1j2X43lKfIZC-ElwWY,19
24
- futurehouse_client-0.5.0.dist-info/RECORD,,
20
+ futurehouse_client-0.5.2.dist-info/licenses/LICENSE,sha256=oQ9ZHjUi-_6GfP3gs14FlPb0OlGwE1QCCKFGnJ4LD2I,11341
21
+ futurehouse_client-0.5.2.dist-info/METADATA,sha256=jUjgFhsqsfh_w4WzwGLblQPy5MgWt50mxyEtpRziN6M,27054
22
+ futurehouse_client-0.5.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
23
+ futurehouse_client-0.5.2.dist-info/top_level.txt,sha256=TRuLUCt_qBnggdFHCX4O_BoCu1j2X43lKfIZC-ElwWY,19
24
+ futurehouse_client-0.5.2.dist-info/RECORD,,