fleet-python 0.2.2__py3-none-any.whl → 0.2.4__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.
Potentially problematic release.
This version of fleet-python might be problematic. Click here for more details.
- examples/dsl_example.py +108 -92
- examples/example.py +2 -2
- examples/json_tasks_example.py +82 -0
- examples/nova_act_example.py +18 -169
- examples/openai_example.py +89 -311
- examples/openai_simple_example.py +60 -0
- examples/quickstart.py +5 -5
- fleet/__init__.py +32 -3
- fleet/_async/base.py +51 -0
- fleet/_async/client.py +133 -0
- fleet/_async/env/__init__.py +0 -0
- fleet/_async/env/client.py +15 -0
- fleet/_async/exceptions.py +73 -0
- fleet/{manager → _async/instance}/__init__.py +4 -2
- fleet/{manager → _async/instance}/base.py +1 -24
- fleet/{manager → _async/instance}/client.py +44 -24
- fleet/{manager → _async/instance}/models.py +13 -0
- fleet/_async/models.py +109 -0
- fleet/_async/playwright.py +291 -0
- fleet/_async/resources/__init__.py +0 -0
- fleet/_async/resources/base.py +26 -0
- fleet/_async/resources/browser.py +41 -0
- fleet/_async/resources/sqlite.py +41 -0
- fleet/base.py +1 -24
- fleet/client.py +42 -95
- fleet/env/__init__.py +13 -1
- fleet/env/client.py +7 -7
- fleet/instance/__init__.py +26 -0
- fleet/instance/base.py +37 -0
- fleet/instance/client.py +278 -0
- fleet/instance/models.py +141 -0
- fleet/playwright.py +289 -0
- fleet/resources/__init__.py +0 -0
- fleet/resources/base.py +1 -1
- fleet/resources/browser.py +20 -23
- fleet/resources/sqlite.py +13 -13
- fleet/verifiers/__init__.py +10 -3
- fleet/verifiers/code.py +1 -0
- fleet/verifiers/{database_snapshot.py → db.py} +62 -22
- fleet/verifiers/sql_differ.py +1 -1
- {fleet_python-0.2.2.dist-info → fleet_python-0.2.4.dist-info}/METADATA +4 -1
- fleet_python-0.2.4.dist-info/RECORD +48 -0
- {fleet_python-0.2.2.dist-info → fleet_python-0.2.4.dist-info}/top_level.txt +1 -0
- scripts/unasync.py +28 -0
- fleet_python-0.2.2.dist-info/RECORD +0 -27
- {fleet_python-0.2.2.dist-info → fleet_python-0.2.4.dist-info}/WHEEL +0 -0
- {fleet_python-0.2.2.dist-info → fleet_python-0.2.4.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""Fleet SDK Environment Module."""
|
|
2
|
+
|
|
3
|
+
from .client import InstanceClient, ValidatorType
|
|
4
|
+
from .._async.instance.client import AsyncInstanceClient
|
|
5
|
+
from .models import (
|
|
6
|
+
ResetRequest,
|
|
7
|
+
ResetResponse,
|
|
8
|
+
CDPDescribeResponse,
|
|
9
|
+
ChromeStartRequest,
|
|
10
|
+
ChromeStartResponse,
|
|
11
|
+
ChromeStatusResponse,
|
|
12
|
+
ExecuteFunctionResponse,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"ValidatorType",
|
|
17
|
+
"InstanceClient",
|
|
18
|
+
"AsyncInstanceClient",
|
|
19
|
+
"ResetRequest",
|
|
20
|
+
"ResetResponse",
|
|
21
|
+
"CDPDescribeResponse",
|
|
22
|
+
"ChromeStartRequest",
|
|
23
|
+
"ChromeStartResponse",
|
|
24
|
+
"ChromeStatusResponse",
|
|
25
|
+
"ExecuteFunctionResponse"
|
|
26
|
+
]
|
fleet/instance/base.py
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import httpx
|
|
2
|
+
from typing import Dict, Any, Optional
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class BaseWrapper:
|
|
6
|
+
def __init__(self, *, url: str):
|
|
7
|
+
self.url = url
|
|
8
|
+
|
|
9
|
+
def get_headers(self) -> Dict[str, str]:
|
|
10
|
+
headers: Dict[str, str] = {
|
|
11
|
+
"X-Fleet-SDK-Language": "Python",
|
|
12
|
+
"X-Fleet-SDK-Version": "1.0.0",
|
|
13
|
+
}
|
|
14
|
+
return headers
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class SyncWrapper(BaseWrapper):
|
|
18
|
+
def __init__(self, *, httpx_client: httpx.Client, **kwargs):
|
|
19
|
+
super().__init__(**kwargs)
|
|
20
|
+
self.httpx_client = httpx_client
|
|
21
|
+
|
|
22
|
+
def request(
|
|
23
|
+
self,
|
|
24
|
+
method: str,
|
|
25
|
+
path: str,
|
|
26
|
+
params: Optional[Dict[str, Any]] = None,
|
|
27
|
+
json: Optional[Any] = None,
|
|
28
|
+
**kwargs,
|
|
29
|
+
) -> httpx.Response:
|
|
30
|
+
return self.httpx_client.request(
|
|
31
|
+
method,
|
|
32
|
+
f"{self.url}{path}",
|
|
33
|
+
headers=self.get_headers(),
|
|
34
|
+
params=params,
|
|
35
|
+
json=json,
|
|
36
|
+
**kwargs,
|
|
37
|
+
)
|
fleet/instance/client.py
ADDED
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
"""Fleet SDK Async Instance Client."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Callable, Dict, List, Optional, Tuple
|
|
4
|
+
import asyncio
|
|
5
|
+
import httpx
|
|
6
|
+
import inspect
|
|
7
|
+
import time
|
|
8
|
+
import logging
|
|
9
|
+
from urllib.parse import urlparse
|
|
10
|
+
|
|
11
|
+
from ..resources.sqlite import SQLiteResource
|
|
12
|
+
from ..resources.browser import BrowserResource
|
|
13
|
+
from ..resources.base import Resource
|
|
14
|
+
|
|
15
|
+
from ..verifiers import DatabaseSnapshot
|
|
16
|
+
|
|
17
|
+
from ..exceptions import FleetEnvironmentError, FleetAPIError
|
|
18
|
+
|
|
19
|
+
from .base import SyncWrapper
|
|
20
|
+
from .models import (
|
|
21
|
+
ResetRequest,
|
|
22
|
+
ResetResponse,
|
|
23
|
+
Resource as ResourceModel,
|
|
24
|
+
ResourceType,
|
|
25
|
+
HealthResponse,
|
|
26
|
+
ExecuteFunctionRequest,
|
|
27
|
+
ExecuteFunctionResponse,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
logger = logging.getLogger(__name__)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
RESOURCE_TYPES = {
|
|
35
|
+
ResourceType.db: SQLiteResource,
|
|
36
|
+
ResourceType.cdp: BrowserResource,
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
ValidatorType = Callable[
|
|
40
|
+
[DatabaseSnapshot, DatabaseSnapshot, Optional[str]],
|
|
41
|
+
int,
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class InstanceClient:
|
|
46
|
+
def __init__(
|
|
47
|
+
self,
|
|
48
|
+
url: str,
|
|
49
|
+
httpx_client: Optional[httpx.Client] = None,
|
|
50
|
+
):
|
|
51
|
+
self.base_url = url
|
|
52
|
+
self.client = SyncWrapper(
|
|
53
|
+
url=self.base_url,
|
|
54
|
+
httpx_client=httpx_client or httpx.Client(timeout=60.0),
|
|
55
|
+
)
|
|
56
|
+
self._resources: Optional[List[ResourceModel]] = None
|
|
57
|
+
self._resources_state: Dict[str, Dict[str, Resource]] = {
|
|
58
|
+
resource_type.value: {} for resource_type in ResourceType
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
def load(self) -> None:
|
|
62
|
+
self._load_resources()
|
|
63
|
+
|
|
64
|
+
def reset(
|
|
65
|
+
self, reset_request: Optional[ResetRequest] = None
|
|
66
|
+
) -> ResetResponse:
|
|
67
|
+
response = self.client.request(
|
|
68
|
+
"POST", "/reset", json=reset_request.model_dump() if reset_request else None
|
|
69
|
+
)
|
|
70
|
+
return ResetResponse(**response.json())
|
|
71
|
+
|
|
72
|
+
def state(self, uri: str) -> Resource:
|
|
73
|
+
url = urlparse(uri)
|
|
74
|
+
return self._resources_state[url.scheme][url.netloc]
|
|
75
|
+
|
|
76
|
+
def db(self, name: str) -> SQLiteResource:
|
|
77
|
+
"""
|
|
78
|
+
Returns an AsyncSQLiteResource object for the given SQLite database name.
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
name: The name of the SQLite database to return
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
An AsyncSQLiteResource object for the given SQLite database name
|
|
85
|
+
"""
|
|
86
|
+
return SQLiteResource(
|
|
87
|
+
self._resources_state[ResourceType.db.value][name], self.client
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
def browser(self, name: str) -> BrowserResource:
|
|
91
|
+
return BrowserResource(
|
|
92
|
+
self._resources_state[ResourceType.cdp.value][name], self.client
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
def resources(self) -> List[Resource]:
|
|
96
|
+
self._load_resources()
|
|
97
|
+
return [
|
|
98
|
+
resource
|
|
99
|
+
for resources_by_name in self._resources_state.values()
|
|
100
|
+
for resource in resources_by_name.values()
|
|
101
|
+
]
|
|
102
|
+
|
|
103
|
+
def verify(self, validator: ValidatorType) -> ExecuteFunctionResponse:
|
|
104
|
+
function_code = inspect.getsource(validator)
|
|
105
|
+
function_name = validator.__name__
|
|
106
|
+
return self.verify_raw(function_code, function_name)
|
|
107
|
+
|
|
108
|
+
def verify_raw(
|
|
109
|
+
self, function_code: str, function_name: str
|
|
110
|
+
) -> ExecuteFunctionResponse:
|
|
111
|
+
response = self.client.request(
|
|
112
|
+
"POST",
|
|
113
|
+
"/execute_verifier_function",
|
|
114
|
+
json=ExecuteFunctionRequest(
|
|
115
|
+
function_code=function_code,
|
|
116
|
+
function_name=function_name,
|
|
117
|
+
).model_dump(),
|
|
118
|
+
)
|
|
119
|
+
return ExecuteFunctionResponse(**response.json())
|
|
120
|
+
|
|
121
|
+
def _load_resources(self) -> None:
|
|
122
|
+
if self._resources is None:
|
|
123
|
+
response = self.client.request("GET", "/resources")
|
|
124
|
+
if response.status_code != 200:
|
|
125
|
+
self._resources = []
|
|
126
|
+
return
|
|
127
|
+
|
|
128
|
+
# Handle both old and new response formats
|
|
129
|
+
response_data = response.json()
|
|
130
|
+
if isinstance(response_data, dict) and "resources" in response_data:
|
|
131
|
+
# Old format: {"resources": [...]}
|
|
132
|
+
resources_list = response_data["resources"]
|
|
133
|
+
else:
|
|
134
|
+
# New format: [...]
|
|
135
|
+
resources_list = response_data
|
|
136
|
+
|
|
137
|
+
self._resources = [ResourceModel(**resource) for resource in resources_list]
|
|
138
|
+
for resource in self._resources:
|
|
139
|
+
if resource.type not in self._resources_state:
|
|
140
|
+
self._resources_state[resource.type.value] = {}
|
|
141
|
+
self._resources_state[resource.type.value][resource.name] = (
|
|
142
|
+
RESOURCE_TYPES[resource.type](resource, self.client)
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
def step(self, action: Dict[str, Any]) -> Tuple[Dict[str, Any], float, bool]:
|
|
146
|
+
"""Execute one step in the environment."""
|
|
147
|
+
if not self._instance_id:
|
|
148
|
+
raise FleetEnvironmentError(
|
|
149
|
+
"Environment not initialized. Call reset() first."
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
try:
|
|
153
|
+
# Increment step count
|
|
154
|
+
self._increment_step()
|
|
155
|
+
|
|
156
|
+
# Execute action through instance manager API
|
|
157
|
+
# This is a placeholder - actual implementation depends on the manager API spec
|
|
158
|
+
state, reward, done = self._execute_action(action)
|
|
159
|
+
|
|
160
|
+
return state, reward, done
|
|
161
|
+
|
|
162
|
+
except Exception as e:
|
|
163
|
+
raise FleetEnvironmentError(f"Failed to execute step: {e}")
|
|
164
|
+
|
|
165
|
+
def close(self) -> None:
|
|
166
|
+
"""Close the environment and clean up resources."""
|
|
167
|
+
try:
|
|
168
|
+
# Delete instance if it exists
|
|
169
|
+
if self._instance_id:
|
|
170
|
+
try:
|
|
171
|
+
self._client.delete_instance(self._instance_id)
|
|
172
|
+
logger.info(f"Deleted instance: {self._instance_id}")
|
|
173
|
+
except FleetAPIError as e:
|
|
174
|
+
logger.warning(f"Failed to delete instance: {e}")
|
|
175
|
+
finally:
|
|
176
|
+
self._instance_id = None
|
|
177
|
+
self._instance_response = None
|
|
178
|
+
|
|
179
|
+
# Close manager client
|
|
180
|
+
if self._manager_client:
|
|
181
|
+
self._manager_client.close()
|
|
182
|
+
self._manager_client = None
|
|
183
|
+
|
|
184
|
+
# Close API client
|
|
185
|
+
self._client.close()
|
|
186
|
+
|
|
187
|
+
except Exception as e:
|
|
188
|
+
logger.error(f"Error closing environment: {e}")
|
|
189
|
+
|
|
190
|
+
def manager_health_check(self) -> Optional[HealthResponse]:
|
|
191
|
+
response = self.client.request("GET", "/health")
|
|
192
|
+
return HealthResponse(**response.json())
|
|
193
|
+
|
|
194
|
+
def _wait_for_instance_ready(self, timeout: float = 300.0) -> None:
|
|
195
|
+
"""Wait for instance to be ready.
|
|
196
|
+
|
|
197
|
+
Args:
|
|
198
|
+
timeout: Maximum time to wait in seconds
|
|
199
|
+
"""
|
|
200
|
+
start_time = time.time()
|
|
201
|
+
|
|
202
|
+
while time.time() - start_time < timeout:
|
|
203
|
+
try:
|
|
204
|
+
instance = self._client.get_instance(self._instance_id)
|
|
205
|
+
self._instance_response = instance
|
|
206
|
+
|
|
207
|
+
if instance.status == "running":
|
|
208
|
+
logger.info(f"Instance {self._instance_id} is ready")
|
|
209
|
+
return
|
|
210
|
+
|
|
211
|
+
elif instance.status == "error":
|
|
212
|
+
raise FleetEnvironmentError(
|
|
213
|
+
f"Instance {self._instance_id} failed to start"
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
# Wait before checking again
|
|
217
|
+
asyncio.sleep(5)
|
|
218
|
+
|
|
219
|
+
except FleetAPIError as e:
|
|
220
|
+
if time.time() - start_time >= timeout:
|
|
221
|
+
raise FleetEnvironmentError(
|
|
222
|
+
f"Timeout waiting for instance to be ready: {e}"
|
|
223
|
+
)
|
|
224
|
+
asyncio.sleep(5)
|
|
225
|
+
|
|
226
|
+
raise FleetEnvironmentError(
|
|
227
|
+
f"Timeout waiting for instance {self._instance_id} to be ready"
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
def _execute_action(
|
|
231
|
+
self, action: Dict[str, Any]
|
|
232
|
+
) -> Tuple[Dict[str, Any], float, bool]:
|
|
233
|
+
"""Execute an action through the instance manager API.
|
|
234
|
+
|
|
235
|
+
This is a placeholder implementation that should be extended based on
|
|
236
|
+
the actual manager API specification.
|
|
237
|
+
|
|
238
|
+
Args:
|
|
239
|
+
action: The action to execute as a dictionary
|
|
240
|
+
|
|
241
|
+
Returns:
|
|
242
|
+
Tuple of (state, reward, done)
|
|
243
|
+
"""
|
|
244
|
+
# Ensure manager client is available
|
|
245
|
+
self._ensure_manager_client()
|
|
246
|
+
|
|
247
|
+
# TODO: In the future, this would use the manager API to execute actions
|
|
248
|
+
# For example: await self._manager_client.log_action(action)
|
|
249
|
+
# For now, return placeholder values
|
|
250
|
+
|
|
251
|
+
# Create a placeholder state
|
|
252
|
+
state = self._create_state_from_action(action)
|
|
253
|
+
|
|
254
|
+
# Create a placeholder reward
|
|
255
|
+
reward = 0.0
|
|
256
|
+
|
|
257
|
+
# Determine if episode is done (placeholder logic)
|
|
258
|
+
done = self._step_count >= 100 # Example: done after 100 steps
|
|
259
|
+
|
|
260
|
+
return state, reward, done
|
|
261
|
+
|
|
262
|
+
def _create_state_from_action(self, action: Dict[str, Any]) -> Dict[str, Any]:
|
|
263
|
+
"""Create state based on executed action."""
|
|
264
|
+
return {
|
|
265
|
+
"instance_id": self._instance_id,
|
|
266
|
+
"step": self._step_count,
|
|
267
|
+
"last_action": action,
|
|
268
|
+
"timestamp": time.time(),
|
|
269
|
+
"status": "running",
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
def __enter__(self):
|
|
273
|
+
"""Async context manager entry."""
|
|
274
|
+
return self
|
|
275
|
+
|
|
276
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
277
|
+
"""Async context manager exit."""
|
|
278
|
+
self.close()
|
fleet/instance/models.py
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# generated by datamodel-codegen:
|
|
2
|
+
# filename: openapi (2).json
|
|
3
|
+
# timestamp: 2025-07-09T20:11:31+00:00
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from enum import Enum
|
|
8
|
+
from typing import Any, Dict, List, Optional, Union
|
|
9
|
+
|
|
10
|
+
from pydantic import BaseModel, Field
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class CDPDescribeResponse(BaseModel):
|
|
14
|
+
success: bool = Field(..., title="Success")
|
|
15
|
+
cdp_page_url: str = Field(..., title="Url")
|
|
16
|
+
cdp_browser_url: str = Field(..., title="Browser Url")
|
|
17
|
+
cdp_devtools_url: str = Field(..., title="Devtools Url")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ChromeStartRequest(BaseModel):
|
|
21
|
+
resolution: Optional[str] = Field("1920x1080", title="Resolution")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ChromeStartResponse(BaseModel):
|
|
25
|
+
success: bool = Field(..., title="Success")
|
|
26
|
+
message: str = Field(..., title="Message")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class ChromeStatusResponse(BaseModel):
|
|
30
|
+
running: bool = Field(..., title="Running")
|
|
31
|
+
message: str = Field(..., title="Message")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class CreateSnapshotsResponse(BaseModel):
|
|
35
|
+
success: bool = Field(..., title="Success")
|
|
36
|
+
initial_snapshot_path: Optional[str] = Field(None, title="Initial Snapshot Path")
|
|
37
|
+
final_snapshot_path: Optional[str] = Field(None, title="Final Snapshot Path")
|
|
38
|
+
message: str = Field(..., title="Message")
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class HealthResponse(BaseModel):
|
|
42
|
+
status: str = Field(..., title="Status")
|
|
43
|
+
timestamp: str = Field(..., title="Timestamp")
|
|
44
|
+
service: str = Field(..., title="Service")
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class LogActionRequest(BaseModel):
|
|
48
|
+
action_type: str = Field(..., title="Action Type")
|
|
49
|
+
sql: Optional[str] = Field(None, title="Sql")
|
|
50
|
+
args: Optional[str] = Field(None, title="Args")
|
|
51
|
+
path: Optional[str] = Field(None, title="Path")
|
|
52
|
+
raw_payload: Optional[str] = Field(None, title="Raw Payload")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class LogActionResponse(BaseModel):
|
|
56
|
+
success: bool = Field(..., title="Success")
|
|
57
|
+
message: str = Field(..., title="Message")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class QueryRequest(BaseModel):
|
|
61
|
+
query: str = Field(..., title="Query")
|
|
62
|
+
args: Optional[List] = Field(None, title="Args")
|
|
63
|
+
read_only: Optional[bool] = Field(True, title="Read Only")
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class QueryResponse(BaseModel):
|
|
67
|
+
success: bool = Field(..., title="Success")
|
|
68
|
+
columns: Optional[List[str]] = Field(None, title="Columns")
|
|
69
|
+
rows: Optional[List[List]] = Field(None, title="Rows")
|
|
70
|
+
rows_affected: Optional[int] = Field(None, title="Rows Affected")
|
|
71
|
+
last_insert_id: Optional[int] = Field(None, title="Last Insert Id")
|
|
72
|
+
error: Optional[str] = Field(None, title="Error")
|
|
73
|
+
message: str = Field(..., title="Message")
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class ResetRequest(BaseModel):
|
|
77
|
+
timestamp: Optional[int] = Field(None, title="Timestamp")
|
|
78
|
+
seed: Optional[int] = Field(None, title="Seed")
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class ResetResponse(BaseModel):
|
|
82
|
+
success: bool = Field(..., title="Success")
|
|
83
|
+
message: str = Field(..., title="Message")
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class ResourceMode(Enum):
|
|
87
|
+
ro = "ro"
|
|
88
|
+
rw = "rw"
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class ResourceType(Enum):
|
|
92
|
+
db = "sqlite"
|
|
93
|
+
cdp = "cdp"
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class TableSchema(BaseModel):
|
|
97
|
+
name: str = Field(..., title="Name")
|
|
98
|
+
sql: str = Field(..., title="Sql")
|
|
99
|
+
columns: List[Dict[str, Any]] = Field(..., title="Columns")
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class TimestampResponse(BaseModel):
|
|
103
|
+
timestamp: str = Field(..., title="Timestamp")
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
class ValidationError(BaseModel):
|
|
107
|
+
loc: List[Union[str, int]] = Field(..., title="Location")
|
|
108
|
+
msg: str = Field(..., title="Message")
|
|
109
|
+
type: str = Field(..., title="Error Type")
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class DescribeResponse(BaseModel):
|
|
113
|
+
success: bool = Field(..., title="Success")
|
|
114
|
+
resource_name: str = Field(..., title="Resource Name")
|
|
115
|
+
tables: Optional[List[TableSchema]] = Field(None, title="Tables")
|
|
116
|
+
error: Optional[str] = Field(None, title="Error")
|
|
117
|
+
message: str = Field(..., title="Message")
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class HTTPValidationError(BaseModel):
|
|
121
|
+
detail: Optional[List[ValidationError]] = Field(None, title="Detail")
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class Resource(BaseModel):
|
|
125
|
+
name: str = Field(..., title="Name")
|
|
126
|
+
type: ResourceType
|
|
127
|
+
mode: ResourceMode
|
|
128
|
+
label: Optional[str] = Field(None, title="Label")
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class ExecuteFunctionRequest(BaseModel):
|
|
132
|
+
function_code: str
|
|
133
|
+
function_name: str
|
|
134
|
+
text_solution: Optional[str] = None
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
class ExecuteFunctionResponse(BaseModel):
|
|
138
|
+
success: bool
|
|
139
|
+
result: Optional[Any] = None
|
|
140
|
+
error: Optional[str] = None
|
|
141
|
+
message: str
|