futurehouse-client 0.4.5.dev119__py3-none-any.whl → 0.4.5.dev201__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.
- futurehouse_client/__init__.py +12 -0
- futurehouse_client/clients/rest_client.py +187 -0
- futurehouse_client/models/__init__.py +12 -0
- futurehouse_client/models/client.py +5 -5
- futurehouse_client/models/job_event.py +75 -0
- futurehouse_client/version.py +2 -2
- {futurehouse_client-0.4.5.dev119.dist-info → futurehouse_client-0.4.5.dev201.dist-info}/METADATA +1 -1
- {futurehouse_client-0.4.5.dev119.dist-info → futurehouse_client-0.4.5.dev201.dist-info}/RECORD +11 -10
- {futurehouse_client-0.4.5.dev119.dist-info → futurehouse_client-0.4.5.dev201.dist-info}/WHEEL +0 -0
- {futurehouse_client-0.4.5.dev119.dist-info → futurehouse_client-0.4.5.dev201.dist-info}/licenses/LICENSE +0 -0
- {futurehouse_client-0.4.5.dev119.dist-info → futurehouse_client-0.4.5.dev201.dist-info}/top_level.txt +0 -0
futurehouse_client/__init__.py
CHANGED
@@ -8,6 +8,13 @@ from .models.app import (
|
|
8
8
|
TaskResponse,
|
9
9
|
TaskResponseVerbose,
|
10
10
|
)
|
11
|
+
from .models.job_event import (
|
12
|
+
CostComponent,
|
13
|
+
ExecutionType,
|
14
|
+
JobEventCreateRequest,
|
15
|
+
JobEventCreateResponse,
|
16
|
+
JobEventUpdateRequest,
|
17
|
+
)
|
11
18
|
from .utils.world_model_tools import (
|
12
19
|
create_world_model_tool,
|
13
20
|
make_world_model_tools,
|
@@ -15,9 +22,14 @@ from .utils.world_model_tools import (
|
|
15
22
|
)
|
16
23
|
|
17
24
|
__all__ = [
|
25
|
+
"CostComponent",
|
26
|
+
"ExecutionType",
|
18
27
|
"FinchTaskResponse",
|
19
28
|
"FutureHouseClient",
|
20
29
|
"JobClient",
|
30
|
+
"JobEventCreateRequest",
|
31
|
+
"JobEventCreateResponse",
|
32
|
+
"JobEventUpdateRequest",
|
21
33
|
"JobNames",
|
22
34
|
"PQATaskResponse",
|
23
35
|
"PhoenixTaskResponse",
|
@@ -52,6 +52,11 @@ from futurehouse_client.models.app import (
|
|
52
52
|
TaskResponseVerbose,
|
53
53
|
TrajectoryQueryParams,
|
54
54
|
)
|
55
|
+
from futurehouse_client.models.job_event import (
|
56
|
+
JobEventCreateRequest,
|
57
|
+
JobEventCreateResponse,
|
58
|
+
JobEventUpdateRequest,
|
59
|
+
)
|
55
60
|
from futurehouse_client.models.rest import (
|
56
61
|
DiscoveryResponse,
|
57
62
|
ExecutionStatus,
|
@@ -160,6 +165,18 @@ class FileUploadError(RestClientError):
|
|
160
165
|
"""Raised when there's an error uploading a file."""
|
161
166
|
|
162
167
|
|
168
|
+
class JobEventClientError(RestClientError):
|
169
|
+
"""Raised when there's an error with job event operations."""
|
170
|
+
|
171
|
+
|
172
|
+
class JobEventCreationError(JobEventClientError):
|
173
|
+
"""Raised when there's an error creating a job event."""
|
174
|
+
|
175
|
+
|
176
|
+
class JobEventUpdateError(JobEventClientError):
|
177
|
+
"""Raised when there's an error updating a job event."""
|
178
|
+
|
179
|
+
|
163
180
|
retry_if_connection_error = create_retry_if_connection_error(FileUploadError)
|
164
181
|
|
165
182
|
DEFAULT_AGENT_TIMEOUT: int = 2400 # seconds
|
@@ -2609,6 +2626,176 @@ class RestClient(DataStorageMethods):
|
|
2609
2626
|
f"Error fetching discoveries for project: {e!r}"
|
2610
2627
|
) from e
|
2611
2628
|
|
2629
|
+
@retry(
|
2630
|
+
stop=stop_after_attempt(MAX_RETRY_ATTEMPTS),
|
2631
|
+
wait=wait_exponential(multiplier=RETRY_MULTIPLIER, max=MAX_RETRY_WAIT),
|
2632
|
+
retry=retry_if_connection_error,
|
2633
|
+
before_sleep=before_sleep_log(logger, logging.WARNING),
|
2634
|
+
)
|
2635
|
+
def create_job_event(
|
2636
|
+
self, request: JobEventCreateRequest
|
2637
|
+
) -> JobEventCreateResponse:
|
2638
|
+
"""Create a new job event.
|
2639
|
+
|
2640
|
+
Args:
|
2641
|
+
request: Job event creation request
|
2642
|
+
|
2643
|
+
Returns:
|
2644
|
+
Job event creation response
|
2645
|
+
|
2646
|
+
Raises:
|
2647
|
+
JobEventCreationError: If the API call fails
|
2648
|
+
"""
|
2649
|
+
try:
|
2650
|
+
response = self.client.post(
|
2651
|
+
"/v0.1/job-events",
|
2652
|
+
json=request.model_dump(exclude_none=True, mode="json"),
|
2653
|
+
)
|
2654
|
+
response.raise_for_status()
|
2655
|
+
return JobEventCreateResponse(**response.json())
|
2656
|
+
except HTTPStatusError as e:
|
2657
|
+
if e.response.status_code == codes.BAD_REQUEST:
|
2658
|
+
raise JobEventCreationError(
|
2659
|
+
f"Invalid job event creation request: {e.response.text}."
|
2660
|
+
) from e
|
2661
|
+
if e.response.status_code == codes.NOT_FOUND:
|
2662
|
+
raise JobEventCreationError(
|
2663
|
+
f"Execution not found for job event creation: {e.response.text}."
|
2664
|
+
) from e
|
2665
|
+
raise JobEventCreationError(
|
2666
|
+
f"Error creating job event: {e.response.status_code} - {e.response.text}."
|
2667
|
+
) from e
|
2668
|
+
except Exception as e:
|
2669
|
+
raise JobEventCreationError(
|
2670
|
+
f"An unexpected error occurred during job event creation: {e!r}."
|
2671
|
+
) from e
|
2672
|
+
|
2673
|
+
@retry(
|
2674
|
+
stop=stop_after_attempt(MAX_RETRY_ATTEMPTS),
|
2675
|
+
wait=wait_exponential(multiplier=RETRY_MULTIPLIER, max=MAX_RETRY_WAIT),
|
2676
|
+
retry=retry_if_connection_error,
|
2677
|
+
before_sleep=before_sleep_log(logger, logging.WARNING),
|
2678
|
+
)
|
2679
|
+
async def acreate_job_event(
|
2680
|
+
self, request: JobEventCreateRequest
|
2681
|
+
) -> JobEventCreateResponse:
|
2682
|
+
"""Asynchronously create a new job event.
|
2683
|
+
|
2684
|
+
Args:
|
2685
|
+
request: Job event creation request
|
2686
|
+
|
2687
|
+
Returns:
|
2688
|
+
Job event creation response
|
2689
|
+
|
2690
|
+
Raises:
|
2691
|
+
JobEventCreationError: If the API call fails
|
2692
|
+
"""
|
2693
|
+
try:
|
2694
|
+
response = await self.async_client.post(
|
2695
|
+
"/v0.1/job-events",
|
2696
|
+
json=request.model_dump(exclude_none=True, mode="json"),
|
2697
|
+
)
|
2698
|
+
response.raise_for_status()
|
2699
|
+
return JobEventCreateResponse(**response.json())
|
2700
|
+
except HTTPStatusError as e:
|
2701
|
+
if e.response.status_code == codes.BAD_REQUEST:
|
2702
|
+
raise JobEventCreationError(
|
2703
|
+
f"Invalid job event creation request: {e.response.text}."
|
2704
|
+
) from e
|
2705
|
+
if e.response.status_code == codes.NOT_FOUND:
|
2706
|
+
raise JobEventCreationError(
|
2707
|
+
f"Execution not found for job event creation: {e.response.text}."
|
2708
|
+
) from e
|
2709
|
+
raise JobEventCreationError(
|
2710
|
+
f"Error creating job event: {e.response.status_code} - {e.response.text}."
|
2711
|
+
) from e
|
2712
|
+
except Exception as e:
|
2713
|
+
raise JobEventCreationError(
|
2714
|
+
f"An unexpected error occurred during job event creation: {e!r}."
|
2715
|
+
) from e
|
2716
|
+
|
2717
|
+
@retry(
|
2718
|
+
stop=stop_after_attempt(MAX_RETRY_ATTEMPTS),
|
2719
|
+
wait=wait_exponential(multiplier=RETRY_MULTIPLIER, max=MAX_RETRY_WAIT),
|
2720
|
+
retry=retry_if_connection_error,
|
2721
|
+
before_sleep=before_sleep_log(logger, logging.WARNING),
|
2722
|
+
)
|
2723
|
+
def update_job_event(
|
2724
|
+
self, job_event_id: UUID, request: JobEventUpdateRequest
|
2725
|
+
) -> None:
|
2726
|
+
"""Update an existing job event.
|
2727
|
+
|
2728
|
+
Args:
|
2729
|
+
job_event_id: ID of the job event to update
|
2730
|
+
request: Job event update request
|
2731
|
+
|
2732
|
+
Raises:
|
2733
|
+
JobEventUpdateError: If the API call fails
|
2734
|
+
"""
|
2735
|
+
try:
|
2736
|
+
response = self.client.patch(
|
2737
|
+
f"/v0.1/job-events/{job_event_id}",
|
2738
|
+
json=request.model_dump(exclude_none=True, mode="json"),
|
2739
|
+
)
|
2740
|
+
response.raise_for_status()
|
2741
|
+
except HTTPStatusError as e:
|
2742
|
+
if e.response.status_code == codes.NOT_FOUND:
|
2743
|
+
raise JobEventUpdateError(
|
2744
|
+
f"Job event with ID {job_event_id} not found."
|
2745
|
+
) from e
|
2746
|
+
if e.response.status_code == codes.BAD_REQUEST:
|
2747
|
+
raise JobEventUpdateError(
|
2748
|
+
f"Invalid job event update request: {e.response.text}."
|
2749
|
+
) from e
|
2750
|
+
raise JobEventUpdateError(
|
2751
|
+
f"Error updating job event: {e.response.status_code} - {e.response.text}."
|
2752
|
+
) from e
|
2753
|
+
except Exception as e:
|
2754
|
+
raise JobEventUpdateError(
|
2755
|
+
f"An unexpected error occurred during job event update: {e!r}."
|
2756
|
+
) from e
|
2757
|
+
|
2758
|
+
@retry(
|
2759
|
+
stop=stop_after_attempt(MAX_RETRY_ATTEMPTS),
|
2760
|
+
wait=wait_exponential(multiplier=RETRY_MULTIPLIER, max=MAX_RETRY_WAIT),
|
2761
|
+
retry=retry_if_connection_error,
|
2762
|
+
before_sleep=before_sleep_log(logger, logging.WARNING),
|
2763
|
+
)
|
2764
|
+
async def aupdate_job_event(
|
2765
|
+
self, job_event_id: UUID, request: JobEventUpdateRequest
|
2766
|
+
) -> None:
|
2767
|
+
"""Asynchronously update an existing job event.
|
2768
|
+
|
2769
|
+
Args:
|
2770
|
+
job_event_id: ID of the job event to update
|
2771
|
+
request: Job event update request
|
2772
|
+
|
2773
|
+
Raises:
|
2774
|
+
JobEventUpdateError: If the API call fails
|
2775
|
+
"""
|
2776
|
+
try:
|
2777
|
+
response = await self.async_client.patch(
|
2778
|
+
f"/v0.1/job-events/{job_event_id}",
|
2779
|
+
json=request.model_dump(exclude_none=True, mode="json"),
|
2780
|
+
)
|
2781
|
+
response.raise_for_status()
|
2782
|
+
except HTTPStatusError as e:
|
2783
|
+
if e.response.status_code == codes.NOT_FOUND:
|
2784
|
+
raise JobEventUpdateError(
|
2785
|
+
f"Job event with ID {job_event_id} not found."
|
2786
|
+
) from e
|
2787
|
+
if e.response.status_code == codes.BAD_REQUEST:
|
2788
|
+
raise JobEventUpdateError(
|
2789
|
+
f"Invalid job event update request: {e.response.text}."
|
2790
|
+
) from e
|
2791
|
+
raise JobEventUpdateError(
|
2792
|
+
f"Error updating job event: {e.response.status_code} - {e.response.text}."
|
2793
|
+
) from e
|
2794
|
+
except Exception as e:
|
2795
|
+
raise JobEventUpdateError(
|
2796
|
+
f"An unexpected error occurred during job event update: {e!r}."
|
2797
|
+
) from e
|
2798
|
+
|
2612
2799
|
|
2613
2800
|
def get_installed_packages() -> dict[str, str]:
|
2614
2801
|
"""Returns a dictionary of installed packages and their versions."""
|
@@ -13,13 +13,25 @@ from .app import (
|
|
13
13
|
TaskResponse,
|
14
14
|
TaskResponseVerbose,
|
15
15
|
)
|
16
|
+
from .job_event import (
|
17
|
+
CostComponent,
|
18
|
+
ExecutionType,
|
19
|
+
JobEventCreateRequest,
|
20
|
+
JobEventCreateResponse,
|
21
|
+
JobEventUpdateRequest,
|
22
|
+
)
|
16
23
|
from .rest import TrajectoryPatchRequest, WorldModel, WorldModelResponse
|
17
24
|
|
18
25
|
__all__ = [
|
19
26
|
"AuthType",
|
27
|
+
"CostComponent",
|
20
28
|
"DockerContainerConfiguration",
|
29
|
+
"ExecutionType",
|
21
30
|
"FramePath",
|
22
31
|
"JobDeploymentConfig",
|
32
|
+
"JobEventCreateRequest",
|
33
|
+
"JobEventCreateResponse",
|
34
|
+
"JobEventUpdateRequest",
|
23
35
|
"PQATaskResponse",
|
24
36
|
"RuntimeConfig",
|
25
37
|
"Stage",
|
@@ -7,6 +7,8 @@ from ldp.data_structures import Transition
|
|
7
7
|
from ldp.graph.ops import OpResult
|
8
8
|
from pydantic import BaseModel, ConfigDict, Field, field_serializer
|
9
9
|
|
10
|
+
from .app import Step
|
11
|
+
|
10
12
|
T = TypeVar("T")
|
11
13
|
|
12
14
|
|
@@ -84,15 +86,13 @@ class GlobalState(BaseState):
|
|
84
86
|
def _get_safe_previous_observations(
|
85
87
|
self, current_obs: list[Message] | None = None
|
86
88
|
) -> list[Message]:
|
87
|
-
if self.last_step_state:
|
88
|
-
|
89
|
-
if last_step_state.next_observation:
|
90
|
-
return last_step_state.next_observation
|
89
|
+
if self.last_step_state and self.last_step_state.next_observation:
|
90
|
+
return self.last_step_state.next_observation
|
91
91
|
if self.observations:
|
92
92
|
return self.observations
|
93
93
|
return current_obs or []
|
94
94
|
|
95
|
-
def create_step_state(self, callback_type:
|
95
|
+
def create_step_state(self, callback_type: Step, **kwargs) -> Transition:
|
96
96
|
defaults = {
|
97
97
|
"timestep": getattr(self.agent, "_timestep", 0) if self.agent else 0,
|
98
98
|
"agent_state": self.agent_state,
|
@@ -0,0 +1,75 @@
|
|
1
|
+
"""Job event models for cost and usage tracking."""
|
2
|
+
|
3
|
+
from datetime import datetime
|
4
|
+
from enum import StrEnum, auto
|
5
|
+
from typing import Any
|
6
|
+
from uuid import UUID
|
7
|
+
|
8
|
+
from pydantic import BaseModel, Field
|
9
|
+
|
10
|
+
|
11
|
+
class ExecutionType(StrEnum):
|
12
|
+
"""Type of execution for job events."""
|
13
|
+
|
14
|
+
TRAJECTORY = auto()
|
15
|
+
SESSION = auto()
|
16
|
+
|
17
|
+
|
18
|
+
class CostComponent(StrEnum):
|
19
|
+
"""Cost component types for job events."""
|
20
|
+
|
21
|
+
LLM_USAGE = auto()
|
22
|
+
EXTERNAL_SERVICE = auto()
|
23
|
+
STEP = auto()
|
24
|
+
|
25
|
+
|
26
|
+
class JobEventCreateRequest(BaseModel):
|
27
|
+
"""Request model for creating a job event matching crow-service schema."""
|
28
|
+
|
29
|
+
execution_id: UUID = Field(description="UUID for trajectory_id or session_id")
|
30
|
+
execution_type: ExecutionType = Field(
|
31
|
+
description="Either 'TRAJECTORY' or 'SESSION'"
|
32
|
+
)
|
33
|
+
cost_component: CostComponent = Field(
|
34
|
+
description="Cost component: 'LLM_USAGE', 'EXTERNAL_SERVICE', or 'STEP'"
|
35
|
+
)
|
36
|
+
started_at: datetime = Field(description="Start time of the job event")
|
37
|
+
ended_at: datetime = Field(description="End time of the job event")
|
38
|
+
crow: str | None = Field(default=None, description="unique identifier for the crow")
|
39
|
+
amount_acu: float | None = Field(default=None, description="Cost amount in ACUs")
|
40
|
+
amount_usd: float | None = Field(default=None, description="Cost amount in USD")
|
41
|
+
rate: float | None = Field(default=None, description="Rate per token/call in USD")
|
42
|
+
input_token_count: int | None = Field(
|
43
|
+
default=None, description="Input token count for LLM calls"
|
44
|
+
)
|
45
|
+
completion_token_count: int | None = Field(
|
46
|
+
default=None, description="Completion token count for LLM calls"
|
47
|
+
)
|
48
|
+
metadata: dict[str, Any] | None = Field(default=None)
|
49
|
+
|
50
|
+
|
51
|
+
class JobEventUpdateRequest(BaseModel):
|
52
|
+
"""Request model for updating a job event matching crow-service schema."""
|
53
|
+
|
54
|
+
amount_acu: float | None = Field(default=None, description="Cost amount in ACUs")
|
55
|
+
amount_usd: float | None = Field(default=None, description="Cost amount in USD")
|
56
|
+
rate: float | None = Field(default=None, description="Rate per token/call in USD")
|
57
|
+
input_token_count: int | None = Field(
|
58
|
+
default=None, description="Input token count for LLM calls"
|
59
|
+
)
|
60
|
+
completion_token_count: int | None = Field(
|
61
|
+
default=None, description="Completion token count for LLM calls"
|
62
|
+
)
|
63
|
+
metadata: dict[str, Any] | None = Field(default=None)
|
64
|
+
started_at: datetime | None = Field(
|
65
|
+
default=None, description="Start time of the job event"
|
66
|
+
)
|
67
|
+
ended_at: datetime | None = Field(
|
68
|
+
default=None, description="End time of the job event"
|
69
|
+
)
|
70
|
+
|
71
|
+
|
72
|
+
class JobEventCreateResponse(BaseModel):
|
73
|
+
"""Response model for job event creation."""
|
74
|
+
|
75
|
+
id: UUID = Field(description="UUID of the created job event")
|
futurehouse_client/version.py
CHANGED
@@ -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.4.5.
|
32
|
-
__version_tuple__ = version_tuple = (0, 4, 5, '
|
31
|
+
__version__ = version = '0.4.5.dev201'
|
32
|
+
__version_tuple__ = version_tuple = (0, 4, 5, 'dev201')
|
33
33
|
|
34
34
|
__commit_id__ = commit_id = None
|
{futurehouse_client-0.4.5.dev119.dist-info → futurehouse_client-0.4.5.dev201.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: futurehouse-client
|
3
|
-
Version: 0.4.5.
|
3
|
+
Version: 0.4.5.dev201
|
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
|
{futurehouse_client-0.4.5.dev119.dist-info → futurehouse_client-0.4.5.dev201.dist-info}/RECORD
RENAMED
@@ -1,14 +1,15 @@
|
|
1
|
-
futurehouse_client/__init__.py,sha256=
|
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=
|
3
|
+
futurehouse_client/version.py,sha256=gVEi6V2NhKQOnRNh8vVkILg1cdwbsy1LGjqPIbyPeLo,721
|
4
4
|
futurehouse_client/clients/__init__.py,sha256=-HXNj-XJ3LRO5XM6MZ709iPs29YpApss0Q2YYg1qMZw,280
|
5
5
|
futurehouse_client/clients/data_storage_methods.py,sha256=f8ZsVicEtO50pRXoPzEB2GpiyqosNofyoW8vJeYvFnM,119266
|
6
6
|
futurehouse_client/clients/job_client.py,sha256=b5gpzulZpxpv9R337r3UKItnMdtd6CGlI1sV3_VQJso,13985
|
7
|
-
futurehouse_client/clients/rest_client.py,sha256=
|
8
|
-
futurehouse_client/models/__init__.py,sha256=
|
7
|
+
futurehouse_client/clients/rest_client.py,sha256=kLCR4dYduwX_16jaOZ26RGCOR2A_6nk2gpBKUqQ-KVI,110247
|
8
|
+
futurehouse_client/models/__init__.py,sha256=N1MwDUYonsMN9NdaShsYcJspyL7H756MYj7VWFeD3fk,978
|
9
9
|
futurehouse_client/models/app.py,sha256=UUg17I3zk6cH_7mrdojHGYvQfm_SeDkuUxsPlRyIYz0,31895
|
10
|
-
futurehouse_client/models/client.py,sha256=
|
10
|
+
futurehouse_client/models/client.py,sha256=554vp7Cr-17BTeRZtN5DhCRQesRRtr31ZPkHXUrhyCE,3835
|
11
11
|
futurehouse_client/models/data_storage_methods.py,sha256=cpF2g4y_REECaz--WhaJeLqXA_3m3keRP5XOXiL8GOI,13811
|
12
|
+
futurehouse_client/models/job_event.py,sha256=lMrx-lV7BQkKl419ErWZ6Q1EjurmhBFSns0z6zwGaVo,2766
|
12
13
|
futurehouse_client/models/rest.py,sha256=SbeXZSPUCM0lQ_gVUPa64vKzMxuUVgqmJ5YThfDWs8g,4726
|
13
14
|
futurehouse_client/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
14
15
|
futurehouse_client/utils/auth.py,sha256=tgWELjKfg8eWme_qdcRmc8TjQN9DVZuHHaVXZNHLchk,2960
|
@@ -16,8 +17,8 @@ futurehouse_client/utils/general.py,sha256=PIkGLCSA3kUvc6mwR-prEB7YnMdKILOIm6cPo
|
|
16
17
|
futurehouse_client/utils/module_utils.py,sha256=aFyd-X-pDARXz9GWpn8SSViUVYdSbuy9vSkrzcVIaGI,4955
|
17
18
|
futurehouse_client/utils/monitoring.py,sha256=UjRlufe67kI3VxRHOd5fLtJmlCbVA2Wqwpd4uZhXkQM,8728
|
18
19
|
futurehouse_client/utils/world_model_tools.py,sha256=v2krZGrco0ur2a_pcRMtnQL05SxlIoBXuJ5R1JkQNws,2921
|
19
|
-
futurehouse_client-0.4.5.
|
20
|
-
futurehouse_client-0.4.5.
|
21
|
-
futurehouse_client-0.4.5.
|
22
|
-
futurehouse_client-0.4.5.
|
23
|
-
futurehouse_client-0.4.5.
|
20
|
+
futurehouse_client-0.4.5.dev201.dist-info/licenses/LICENSE,sha256=oQ9ZHjUi-_6GfP3gs14FlPb0OlGwE1QCCKFGnJ4LD2I,11341
|
21
|
+
futurehouse_client-0.4.5.dev201.dist-info/METADATA,sha256=2MNiAgseBRKeAO9y03jEiq2ejMC3r87PwHvS-_DGWp8,27101
|
22
|
+
futurehouse_client-0.4.5.dev201.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
23
|
+
futurehouse_client-0.4.5.dev201.dist-info/top_level.txt,sha256=TRuLUCt_qBnggdFHCX4O_BoCu1j2X43lKfIZC-ElwWY,19
|
24
|
+
futurehouse_client-0.4.5.dev201.dist-info/RECORD,,
|
{futurehouse_client-0.4.5.dev119.dist-info → futurehouse_client-0.4.5.dev201.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|
File without changes
|