fleet-python 0.2.3__py3-none-any.whl → 0.2.5__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.

Files changed (42) hide show
  1. examples/dsl_example.py +2 -1
  2. examples/example.py +2 -2
  3. examples/json_tasks_example.py +1 -1
  4. examples/nova_act_example.py +1 -1
  5. examples/openai_example.py +17 -24
  6. examples/openai_simple_example.py +11 -12
  7. fleet/__init__.py +18 -3
  8. fleet/_async/base.py +51 -0
  9. fleet/_async/client.py +133 -0
  10. fleet/_async/env/__init__.py +0 -0
  11. fleet/_async/env/client.py +15 -0
  12. fleet/_async/exceptions.py +73 -0
  13. fleet/_async/instance/__init__.py +24 -0
  14. fleet/_async/instance/base.py +37 -0
  15. fleet/_async/instance/client.py +278 -0
  16. fleet/_async/instance/models.py +141 -0
  17. fleet/_async/models.py +109 -0
  18. fleet/_async/playwright.py +291 -0
  19. fleet/_async/resources/__init__.py +0 -0
  20. fleet/_async/resources/base.py +26 -0
  21. fleet/_async/resources/browser.py +41 -0
  22. fleet/_async/resources/sqlite.py +41 -0
  23. fleet/base.py +1 -24
  24. fleet/client.py +31 -99
  25. fleet/env/__init__.py +13 -1
  26. fleet/env/client.py +7 -7
  27. fleet/instance/__init__.py +3 -2
  28. fleet/instance/base.py +1 -24
  29. fleet/instance/client.py +40 -57
  30. fleet/playwright.py +45 -47
  31. fleet/resources/__init__.py +0 -0
  32. fleet/resources/browser.py +14 -14
  33. fleet/resources/sqlite.py +11 -11
  34. fleet/verifiers/__init__.py +5 -10
  35. fleet/verifiers/code.py +1 -132
  36. {fleet_python-0.2.3.dist-info → fleet_python-0.2.5.dist-info}/METADATA +12 -11
  37. fleet_python-0.2.5.dist-info/RECORD +48 -0
  38. {fleet_python-0.2.3.dist-info → fleet_python-0.2.5.dist-info}/top_level.txt +1 -0
  39. scripts/unasync.py +28 -0
  40. fleet_python-0.2.3.dist-info/RECORD +0 -31
  41. {fleet_python-0.2.3.dist-info → fleet_python-0.2.5.dist-info}/WHEEL +0 -0
  42. {fleet_python-0.2.3.dist-info → fleet_python-0.2.5.dist-info}/licenses/LICENSE +0 -0
@@ -1,6 +1,7 @@
1
1
  """Fleet SDK Environment Module."""
2
2
 
3
- from .client import InstanceClient, AsyncInstanceClient, ValidatorType
3
+ from .client import InstanceClient, ValidatorType
4
+ from .._async.instance.client import AsyncInstanceClient
4
5
  from .models import (
5
6
  ResetRequest,
6
7
  ResetResponse,
@@ -22,4 +23,4 @@ __all__ = [
22
23
  "ChromeStartResponse",
23
24
  "ChromeStatusResponse",
24
25
  "ExecuteFunctionResponse"
25
- ]
26
+ ]
fleet/instance/base.py CHANGED
@@ -34,27 +34,4 @@ class SyncWrapper(BaseWrapper):
34
34
  params=params,
35
35
  json=json,
36
36
  **kwargs,
37
- )
38
-
39
-
40
- class AsyncWrapper(BaseWrapper):
41
- def __init__(self, *, httpx_client: httpx.AsyncClient, **kwargs):
42
- super().__init__(**kwargs)
43
- self.httpx_client = httpx_client
44
-
45
- async def request(
46
- self,
47
- method: str,
48
- path: str,
49
- params: Optional[Dict[str, Any]] = None,
50
- json: Optional[Any] = None,
51
- **kwargs,
52
- ) -> httpx.Response:
53
- return await self.httpx_client.request(
54
- method,
55
- f"{self.url}{path}",
56
- headers=self.get_headers(),
57
- params=params,
58
- json=json,
59
- **kwargs,
60
- )
37
+ )
fleet/instance/client.py CHANGED
@@ -1,4 +1,4 @@
1
- """Fleet SDK Base Environment Classes."""
1
+ """Fleet SDK Async Instance Client."""
2
2
 
3
3
  from typing import Any, Callable, Dict, List, Optional, Tuple
4
4
  import asyncio
@@ -8,15 +8,15 @@ import time
8
8
  import logging
9
9
  from urllib.parse import urlparse
10
10
 
11
- from ..resources.sqlite import AsyncSQLiteResource
12
- from ..resources.browser import AsyncBrowserResource
11
+ from ..resources.sqlite import SQLiteResource
12
+ from ..resources.browser import BrowserResource
13
13
  from ..resources.base import Resource
14
14
 
15
15
  from ..verifiers import DatabaseSnapshot
16
16
 
17
17
  from ..exceptions import FleetEnvironmentError, FleetAPIError
18
18
 
19
- from .base import SyncWrapper, AsyncWrapper
19
+ from .base import SyncWrapper
20
20
  from .models import (
21
21
  ResetRequest,
22
22
  ResetResponse,
@@ -32,8 +32,8 @@ logger = logging.getLogger(__name__)
32
32
 
33
33
 
34
34
  RESOURCE_TYPES = {
35
- ResourceType.db: AsyncSQLiteResource,
36
- ResourceType.cdp: AsyncBrowserResource,
35
+ ResourceType.db: SQLiteResource,
36
+ ResourceType.cdp: BrowserResource,
37
37
  }
38
38
 
39
39
  ValidatorType = Callable[
@@ -50,38 +50,21 @@ class InstanceClient:
50
50
  ):
51
51
  self.base_url = url
52
52
  self.client = SyncWrapper(
53
- url=self.base_url, httpx_client=httpx_client or httpx.Client()
54
- )
55
- raise NotImplementedError("SyncManager is not implemented")
56
-
57
- def reset(self) -> ResetResponse:
58
- response = self.client.request("POST", "/reset")
59
- return ResetResponse(**response.json())
60
-
61
-
62
- class AsyncInstanceClient:
63
- def __init__(
64
- self,
65
- url: str,
66
- httpx_client: Optional[httpx.AsyncClient] = None,
67
- ):
68
- self.base_url = url
69
- self.client = AsyncWrapper(
70
53
  url=self.base_url,
71
- httpx_client=httpx_client or httpx.AsyncClient(timeout=60.0),
54
+ httpx_client=httpx_client or httpx.Client(timeout=60.0),
72
55
  )
73
56
  self._resources: Optional[List[ResourceModel]] = None
74
57
  self._resources_state: Dict[str, Dict[str, Resource]] = {
75
58
  resource_type.value: {} for resource_type in ResourceType
76
59
  }
77
60
 
78
- async def load(self) -> None:
79
- await self._load_resources()
61
+ def load(self) -> None:
62
+ self._load_resources()
80
63
 
81
- async def reset(
64
+ def reset(
82
65
  self, reset_request: Optional[ResetRequest] = None
83
66
  ) -> ResetResponse:
84
- response = await self.client.request(
67
+ response = self.client.request(
85
68
  "POST", "/reset", json=reset_request.model_dump() if reset_request else None
86
69
  )
87
70
  return ResetResponse(**response.json())
@@ -90,7 +73,7 @@ class AsyncInstanceClient:
90
73
  url = urlparse(uri)
91
74
  return self._resources_state[url.scheme][url.netloc]
92
75
 
93
- def db(self, name: str) -> AsyncSQLiteResource:
76
+ def db(self, name: str) -> SQLiteResource:
94
77
  """
95
78
  Returns an AsyncSQLiteResource object for the given SQLite database name.
96
79
 
@@ -100,32 +83,32 @@ class AsyncInstanceClient:
100
83
  Returns:
101
84
  An AsyncSQLiteResource object for the given SQLite database name
102
85
  """
103
- return AsyncSQLiteResource(
86
+ return SQLiteResource(
104
87
  self._resources_state[ResourceType.db.value][name], self.client
105
88
  )
106
89
 
107
- def browser(self, name: str) -> AsyncBrowserResource:
108
- return AsyncBrowserResource(
90
+ def browser(self, name: str) -> BrowserResource:
91
+ return BrowserResource(
109
92
  self._resources_state[ResourceType.cdp.value][name], self.client
110
93
  )
111
94
 
112
- async def resources(self) -> List[Resource]:
113
- await self._load_resources()
95
+ def resources(self) -> List[Resource]:
96
+ self._load_resources()
114
97
  return [
115
98
  resource
116
99
  for resources_by_name in self._resources_state.values()
117
100
  for resource in resources_by_name.values()
118
101
  ]
119
102
 
120
- async def verify(self, validator: ValidatorType) -> ExecuteFunctionResponse:
103
+ def verify(self, validator: ValidatorType) -> ExecuteFunctionResponse:
121
104
  function_code = inspect.getsource(validator)
122
105
  function_name = validator.__name__
123
- return await self.verify_raw(function_code, function_name)
106
+ return self.verify_raw(function_code, function_name)
124
107
 
125
- async def verify_raw(
108
+ def verify_raw(
126
109
  self, function_code: str, function_name: str
127
110
  ) -> ExecuteFunctionResponse:
128
- response = await self.client.request(
111
+ response = self.client.request(
129
112
  "POST",
130
113
  "/execute_verifier_function",
131
114
  json=ExecuteFunctionRequest(
@@ -135,9 +118,9 @@ class AsyncInstanceClient:
135
118
  )
136
119
  return ExecuteFunctionResponse(**response.json())
137
120
 
138
- async def _load_resources(self) -> None:
121
+ def _load_resources(self) -> None:
139
122
  if self._resources is None:
140
- response = await self.client.request("GET", "/resources")
123
+ response = self.client.request("GET", "/resources")
141
124
  if response.status_code != 200:
142
125
  self._resources = []
143
126
  return
@@ -159,7 +142,7 @@ class AsyncInstanceClient:
159
142
  RESOURCE_TYPES[resource.type](resource, self.client)
160
143
  )
161
144
 
162
- async def step(self, action: Dict[str, Any]) -> Tuple[Dict[str, Any], float, bool]:
145
+ def step(self, action: Dict[str, Any]) -> Tuple[Dict[str, Any], float, bool]:
163
146
  """Execute one step in the environment."""
164
147
  if not self._instance_id:
165
148
  raise FleetEnvironmentError(
@@ -172,20 +155,20 @@ class AsyncInstanceClient:
172
155
 
173
156
  # Execute action through instance manager API
174
157
  # This is a placeholder - actual implementation depends on the manager API spec
175
- state, reward, done = await self._execute_action(action)
158
+ state, reward, done = self._execute_action(action)
176
159
 
177
160
  return state, reward, done
178
161
 
179
162
  except Exception as e:
180
163
  raise FleetEnvironmentError(f"Failed to execute step: {e}")
181
164
 
182
- async def close(self) -> None:
165
+ def close(self) -> None:
183
166
  """Close the environment and clean up resources."""
184
167
  try:
185
168
  # Delete instance if it exists
186
169
  if self._instance_id:
187
170
  try:
188
- await self._client.delete_instance(self._instance_id)
171
+ self._client.delete_instance(self._instance_id)
189
172
  logger.info(f"Deleted instance: {self._instance_id}")
190
173
  except FleetAPIError as e:
191
174
  logger.warning(f"Failed to delete instance: {e}")
@@ -195,20 +178,20 @@ class AsyncInstanceClient:
195
178
 
196
179
  # Close manager client
197
180
  if self._manager_client:
198
- await self._manager_client.close()
181
+ self._manager_client.close()
199
182
  self._manager_client = None
200
183
 
201
184
  # Close API client
202
- await self._client.close()
185
+ self._client.close()
203
186
 
204
187
  except Exception as e:
205
188
  logger.error(f"Error closing environment: {e}")
206
189
 
207
- async def manager_health_check(self) -> Optional[HealthResponse]:
208
- response = await self.client.request("GET", "/health")
190
+ def manager_health_check(self) -> Optional[HealthResponse]:
191
+ response = self.client.request("GET", "/health")
209
192
  return HealthResponse(**response.json())
210
193
 
211
- async def _wait_for_instance_ready(self, timeout: float = 300.0) -> None:
194
+ def _wait_for_instance_ready(self, timeout: float = 300.0) -> None:
212
195
  """Wait for instance to be ready.
213
196
 
214
197
  Args:
@@ -218,7 +201,7 @@ class AsyncInstanceClient:
218
201
 
219
202
  while time.time() - start_time < timeout:
220
203
  try:
221
- instance = await self._client.get_instance(self._instance_id)
204
+ instance = self._client.get_instance(self._instance_id)
222
205
  self._instance_response = instance
223
206
 
224
207
  if instance.status == "running":
@@ -231,20 +214,20 @@ class AsyncInstanceClient:
231
214
  )
232
215
 
233
216
  # Wait before checking again
234
- await asyncio.sleep(5)
217
+ asyncio.sleep(5)
235
218
 
236
219
  except FleetAPIError as e:
237
220
  if time.time() - start_time >= timeout:
238
221
  raise FleetEnvironmentError(
239
222
  f"Timeout waiting for instance to be ready: {e}"
240
223
  )
241
- await asyncio.sleep(5)
224
+ asyncio.sleep(5)
242
225
 
243
226
  raise FleetEnvironmentError(
244
227
  f"Timeout waiting for instance {self._instance_id} to be ready"
245
228
  )
246
229
 
247
- async def _execute_action(
230
+ def _execute_action(
248
231
  self, action: Dict[str, Any]
249
232
  ) -> Tuple[Dict[str, Any], float, bool]:
250
233
  """Execute an action through the instance manager API.
@@ -259,7 +242,7 @@ class AsyncInstanceClient:
259
242
  Tuple of (state, reward, done)
260
243
  """
261
244
  # Ensure manager client is available
262
- await self._ensure_manager_client()
245
+ self._ensure_manager_client()
263
246
 
264
247
  # TODO: In the future, this would use the manager API to execute actions
265
248
  # For example: await self._manager_client.log_action(action)
@@ -286,10 +269,10 @@ class AsyncInstanceClient:
286
269
  "status": "running",
287
270
  }
288
271
 
289
- async def __aenter__(self):
272
+ def __enter__(self):
290
273
  """Async context manager entry."""
291
274
  return self
292
275
 
293
- async def __aexit__(self, exc_type, exc_val, exc_tb):
276
+ def __exit__(self, exc_type, exc_val, exc_tb):
294
277
  """Async context manager exit."""
295
- await self.close()
278
+ self.close()
fleet/playwright.py CHANGED
@@ -1,7 +1,7 @@
1
1
  import base64
2
2
  from typing import List, Dict, Any
3
- from playwright.async_api import async_playwright, Browser, Page
4
- from .client import AsyncEnvironment
3
+ from playwright.sync_api import sync_playwright, Browser, Page
4
+ from .client import Environment
5
5
 
6
6
 
7
7
  # Key mapping for computer use actions
@@ -65,7 +65,7 @@ class FleetPlaywrightWrapper:
65
65
 
66
66
  def __init__(
67
67
  self,
68
- env: AsyncEnvironment,
68
+ env: Environment,
69
69
  display_width: int = 1920,
70
70
  display_height: int = 1080,
71
71
  ):
@@ -86,35 +86,33 @@ class FleetPlaywrightWrapper:
86
86
  self._page: Page | None = None
87
87
  self._started = False
88
88
 
89
- async def start(self):
89
+ def start(self):
90
90
  """Start the browser and establish connection."""
91
91
  if self._started:
92
92
  return
93
93
 
94
94
  # Start Playwright
95
- self._playwright = await async_playwright().start()
95
+ self._playwright = sync_playwright().start()
96
96
 
97
97
  # Start browser on the Fleet instance
98
98
  print("Starting browser...")
99
- await self.env.browser().start()
100
- cdp = await self.env.browser().describe()
99
+ self.env.browser().start()
100
+ cdp = self.env.browser().describe()
101
101
 
102
102
  # Connect to browser
103
- self._browser = await self._playwright.chromium.connect_over_cdp(
104
- cdp.cdp_browser_url
105
- )
103
+ self._browser = self._playwright.chromium.connect_over_cdp(cdp.cdp_browser_url)
106
104
  self._page = self._browser.contexts[0].pages[0]
107
- await self._page.set_viewport_size(
105
+ self._page.set_viewport_size(
108
106
  {"width": self.display_width, "height": self.display_height}
109
107
  )
110
108
 
111
109
  self._started = True
112
110
  print(f"Track agent: {cdp.cdp_devtools_url}")
113
111
 
114
- async def close(self):
112
+ def close(self):
115
113
  """Close the browser connection."""
116
114
  if self._playwright:
117
- await self._playwright.stop()
115
+ self._playwright.stop()
118
116
  self._playwright = None
119
117
  self._browser = None
120
118
  self._page = None
@@ -140,7 +138,7 @@ class FleetPlaywrightWrapper:
140
138
  "environment": "browser",
141
139
  }
142
140
 
143
- async def screenshot(self) -> str:
141
+ def screenshot(self) -> str:
144
142
  """
145
143
  Take a screenshot and return base64 encoded string.
146
144
 
@@ -149,7 +147,7 @@ class FleetPlaywrightWrapper:
149
147
  """
150
148
  self._ensure_started()
151
149
 
152
- png_bytes = await self._page.screenshot(full_page=False)
150
+ png_bytes = self._page.screenshot(full_page=False)
153
151
  return base64.b64encode(png_bytes).decode("utf-8")
154
152
 
155
153
  def get_current_url(self) -> str:
@@ -157,7 +155,7 @@ class FleetPlaywrightWrapper:
157
155
  self._ensure_started()
158
156
  return self._page.url
159
157
 
160
- async def execute_computer_action(self, action: Dict[str, Any]) -> Dict[str, Any]:
158
+ def execute_computer_action(self, action: Dict[str, Any]) -> Dict[str, Any]:
161
159
  """
162
160
  Execute a computer action and return the result for OpenAI API.
163
161
 
@@ -177,12 +175,12 @@ class FleetPlaywrightWrapper:
177
175
  # Execute the action
178
176
  if hasattr(self, f"_{action_type}"):
179
177
  method = getattr(self, f"_{action_type}")
180
- await method(**action_args)
178
+ method(**action_args)
181
179
  else:
182
180
  raise ValueError(f"Unsupported action type: {action_type}")
183
181
 
184
182
  # Take screenshot after action
185
- screenshot_base64 = await self.screenshot()
183
+ screenshot_base64 = self.screenshot()
186
184
 
187
185
  return {
188
186
  "type": "input_image",
@@ -191,81 +189,81 @@ class FleetPlaywrightWrapper:
191
189
  }
192
190
 
193
191
  # Computer action implementations
194
- async def _click(self, x: int, y: int, button: str = "left") -> None:
192
+ def _click(self, x: int, y: int, button: str = "left") -> None:
195
193
  """Click at coordinates."""
196
194
  self._ensure_started()
197
- await self._page.mouse.click(x, y, button=button)
195
+ self._page.mouse.click(x, y, button=button)
198
196
 
199
- async def _double_click(self, x: int, y: int) -> None:
197
+ def _double_click(self, x: int, y: int) -> None:
200
198
  """Double-click at coordinates."""
201
199
  self._ensure_started()
202
- await self._page.mouse.dblclick(x, y)
200
+ self._page.mouse.dblclick(x, y)
203
201
 
204
- async def _scroll(self, x: int, y: int, scroll_x: int, scroll_y: int) -> None:
202
+ def _scroll(self, x: int, y: int, scroll_x: int, scroll_y: int) -> None:
205
203
  """Scroll from coordinates."""
206
204
  self._ensure_started()
207
- await self._page.mouse.move(x, y)
208
- await self._page.evaluate(f"window.scrollBy({scroll_x}, {scroll_y})")
205
+ self._page.mouse.move(x, y)
206
+ self._page.evaluate(f"window.scrollBy({scroll_x}, {scroll_y})")
209
207
 
210
- async def _type(self, text: str) -> None:
208
+ def _type(self, text: str) -> None:
211
209
  """Type text."""
212
210
  self._ensure_started()
213
- await self._page.keyboard.type(text)
211
+ self._page.keyboard.type(text)
214
212
 
215
- async def _keypress(self, keys: List[str]) -> None:
213
+ def _keypress(self, keys: List[str]) -> None:
216
214
  """Press key combination."""
217
215
  self._ensure_started()
218
216
  mapped_keys = [CUA_KEY_TO_PLAYWRIGHT_KEY.get(key.lower(), key) for key in keys]
219
217
  for key in mapped_keys:
220
- await self._page.keyboard.down(key)
218
+ self._page.keyboard.down(key)
221
219
  for key in reversed(mapped_keys):
222
- await self._page.keyboard.up(key)
220
+ self._page.keyboard.up(key)
223
221
 
224
- async def _move(self, x: int, y: int) -> None:
222
+ def _move(self, x: int, y: int) -> None:
225
223
  """Move mouse to coordinates."""
226
224
  self._ensure_started()
227
- await self._page.mouse.move(x, y)
225
+ self._page.mouse.move(x, y)
228
226
 
229
- async def _drag(self, path: List[Dict[str, int]]) -> None:
227
+ def _drag(self, path: List[Dict[str, int]]) -> None:
230
228
  """Drag mouse along path."""
231
229
  self._ensure_started()
232
230
  if not path:
233
231
  return
234
- await self._page.mouse.move(path[0]["x"], path[0]["y"])
235
- await self._page.mouse.down()
232
+ self._page.mouse.move(path[0]["x"], path[0]["y"])
233
+ self._page.mouse.down()
236
234
  for point in path[1:]:
237
- await self._page.mouse.move(point["x"], point["y"])
238
- await self._page.mouse.up()
235
+ self._page.mouse.move(point["x"], point["y"])
236
+ self._page.mouse.up()
239
237
 
240
- async def _wait(self, ms: int = 1000) -> None:
238
+ def _wait(self, ms: int = 1000) -> None:
241
239
  """Wait for specified milliseconds."""
242
240
  import asyncio
243
241
 
244
- await asyncio.sleep(ms / 1000)
242
+ asyncio.sleep(ms / 1000)
245
243
 
246
244
  # Browser-specific actions
247
- async def _goto(self, url: str) -> None:
245
+ def _goto(self, url: str) -> None:
248
246
  """Navigate to URL."""
249
247
  self._ensure_started()
250
248
  try:
251
- await self._page.goto(url)
249
+ self._page.goto(url)
252
250
  except Exception as e:
253
251
  print(f"Error navigating to {url}: {e}")
254
252
 
255
- async def _back(self) -> None:
253
+ def _back(self) -> None:
256
254
  """Go back in browser history."""
257
255
  self._ensure_started()
258
- await self._page.go_back()
256
+ self._page.go_back()
259
257
 
260
- async def _forward(self) -> None:
258
+ def _forward(self) -> None:
261
259
  """Go forward in browser history."""
262
260
  self._ensure_started()
263
- await self._page.go_forward()
261
+ self._page.go_forward()
264
262
 
265
- async def _refresh(self) -> None:
263
+ def _refresh(self) -> None:
266
264
  """Refresh the page."""
267
265
  self._ensure_started()
268
- await self._page.reload()
266
+ self._page.reload()
269
267
 
270
268
  # ------------------------------------------------------------------
271
269
  # Public aliases (no leading underscore) expected by the Agent &
File without changes
@@ -10,32 +10,32 @@ from .base import Resource
10
10
  from typing import TYPE_CHECKING
11
11
 
12
12
  if TYPE_CHECKING:
13
- from ..instance.base import AsyncWrapper
13
+ from ..instance.base import SyncWrapper
14
14
 
15
15
 
16
- class AsyncBrowserResource(Resource):
17
- def __init__(self, resource: ResourceModel, client: "AsyncWrapper"):
16
+ class BrowserResource(Resource):
17
+ def __init__(self, resource: ResourceModel, client: "SyncWrapper"):
18
18
  super().__init__(resource)
19
19
  self.client = client
20
20
 
21
- async def start(self, width: int = 1920, height: int = 1080) -> CDPDescribeResponse:
22
- response = await self.client.request(
21
+ def start(self, width: int = 1920, height: int = 1080) -> CDPDescribeResponse:
22
+ response = self.client.request(
23
23
  "POST",
24
24
  "/resources/cdp/start",
25
25
  json=ChromeStartRequest(resolution=f"{width},{height}").model_dump(),
26
26
  )
27
27
  ChromeStartResponse(**response.json())
28
- return await self.describe()
28
+ return self.describe()
29
29
 
30
- async def describe(self) -> CDPDescribeResponse:
31
- response = await self.client.request("GET", "/resources/cdp/describe")
30
+ def describe(self) -> CDPDescribeResponse:
31
+ response = self.client.request("GET", "/resources/cdp/describe")
32
32
  if response.status_code != 200:
33
- await self.start()
34
- response = await self.client.request("GET", "/resources/cdp/describe")
33
+ self.start()
34
+ response = self.client.request("GET", "/resources/cdp/describe")
35
35
  return CDPDescribeResponse(**response.json())
36
36
 
37
- async def cdp_url(self) -> str:
38
- return (await self.describe()).cdp_browser_url
37
+ def cdp_url(self) -> str:
38
+ return (self.describe()).cdp_browser_url
39
39
 
40
- async def devtools_url(self) -> str:
41
- return (await self.describe()).cdp_devtools_url
40
+ def devtools_url(self) -> str:
41
+ return (self.describe()).cdp_devtools_url
fleet/resources/sqlite.py CHANGED
@@ -6,34 +6,34 @@ from .base import Resource
6
6
  from typing import TYPE_CHECKING
7
7
 
8
8
  if TYPE_CHECKING:
9
- from ..instance.base import AsyncWrapper
9
+ from ..instance.base import SyncWrapper
10
10
 
11
11
 
12
- class AsyncSQLiteResource(Resource):
13
- def __init__(self, resource: ResourceModel, client: "AsyncWrapper"):
12
+ class SQLiteResource(Resource):
13
+ def __init__(self, resource: ResourceModel, client: "SyncWrapper"):
14
14
  super().__init__(resource)
15
15
  self.client = client
16
16
 
17
- async def describe(self) -> DescribeResponse:
17
+ def describe(self) -> DescribeResponse:
18
18
  """Describe the SQLite database schema."""
19
- response = await self.client.request(
19
+ response = self.client.request(
20
20
  "GET", f"/resources/sqlite/{self.resource.name}/describe"
21
21
  )
22
22
  return DescribeResponse(**response.json())
23
23
 
24
- async def query(
24
+ def query(
25
25
  self, query: str, args: Optional[List[Any]] = None
26
26
  ) -> QueryResponse:
27
- return await self._query(query, args, read_only=True)
27
+ return self._query(query, args, read_only=True)
28
28
 
29
- async def exec(self, query: str, args: Optional[List[Any]] = None) -> QueryResponse:
30
- return await self._query(query, args, read_only=False)
29
+ def exec(self, query: str, args: Optional[List[Any]] = None) -> QueryResponse:
30
+ return self._query(query, args, read_only=False)
31
31
 
32
- async def _query(
32
+ def _query(
33
33
  self, query: str, args: Optional[List[Any]] = None, read_only: bool = True
34
34
  ) -> QueryResponse:
35
35
  request = QueryRequest(query=query, args=args, read_only=read_only)
36
- response = await self.client.request(
36
+ response = self.client.request(
37
37
  "POST",
38
38
  f"/resources/sqlite/{self.resource.name}/query",
39
39
  json=request.model_dump(),
@@ -1,16 +1,11 @@
1
- from .db import QueryBuilder, DatabaseSnapshot, SnapshotDiff, IgnoreConfig
2
- from .code import (
3
- TASK_SUCCESSFUL_SCORE,
4
- extract_last_assistant_message,
5
- execute_validation_function,
6
- )
1
+ """Fleet verifiers module - database snapshot validation utilities."""
2
+
3
+ from .db import DatabaseSnapshot, IgnoreConfig, SnapshotDiff
4
+ from .code import TASK_SUCCESSFUL_SCORE
7
5
 
8
6
  __all__ = [
9
7
  "DatabaseSnapshot",
10
- "QueryBuilder",
11
- "SnapshotDiff",
12
8
  "IgnoreConfig",
9
+ "SnapshotDiff",
13
10
  "TASK_SUCCESSFUL_SCORE",
14
- "extract_last_assistant_message",
15
- "execute_validation_function",
16
11
  ]