fleet-python 0.2.13__py3-none-any.whl → 0.2.16__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 (41) hide show
  1. examples/diff_example.py +161 -0
  2. examples/dsl_example.py +50 -1
  3. examples/example_action_log.py +28 -0
  4. examples/example_mcp_anthropic.py +77 -0
  5. examples/example_mcp_openai.py +27 -0
  6. examples/example_task.py +199 -0
  7. examples/example_verifier.py +71 -0
  8. examples/query_builder_example.py +117 -0
  9. fleet/__init__.py +51 -40
  10. fleet/_async/base.py +14 -1
  11. fleet/_async/client.py +155 -19
  12. fleet/_async/env/client.py +4 -4
  13. fleet/_async/instance/__init__.py +1 -2
  14. fleet/_async/instance/client.py +3 -2
  15. fleet/_async/playwright.py +2 -2
  16. fleet/_async/resources/sqlite.py +654 -0
  17. fleet/_async/tasks.py +44 -0
  18. fleet/_async/verifiers/__init__.py +17 -0
  19. fleet/_async/verifiers/bundler.py +699 -0
  20. fleet/_async/verifiers/verifier.py +301 -0
  21. fleet/base.py +14 -1
  22. fleet/client.py +664 -12
  23. fleet/config.py +1 -1
  24. fleet/instance/__init__.py +1 -2
  25. fleet/instance/client.py +15 -5
  26. fleet/models.py +171 -4
  27. fleet/resources/browser.py +7 -8
  28. fleet/resources/mcp.py +60 -0
  29. fleet/resources/sqlite.py +654 -0
  30. fleet/tasks.py +44 -0
  31. fleet/types.py +18 -0
  32. fleet/verifiers/__init__.py +11 -5
  33. fleet/verifiers/bundler.py +699 -0
  34. fleet/verifiers/decorator.py +103 -0
  35. fleet/verifiers/verifier.py +301 -0
  36. {fleet_python-0.2.13.dist-info → fleet_python-0.2.16.dist-info}/METADATA +3 -42
  37. fleet_python-0.2.16.dist-info/RECORD +69 -0
  38. fleet_python-0.2.13.dist-info/RECORD +0 -52
  39. {fleet_python-0.2.13.dist-info → fleet_python-0.2.16.dist-info}/WHEEL +0 -0
  40. {fleet_python-0.2.13.dist-info → fleet_python-0.2.16.dist-info}/licenses/LICENSE +0 -0
  41. {fleet_python-0.2.13.dist-info → fleet_python-0.2.16.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,117 @@
1
+ import asyncio
2
+ import fleet as flt
3
+ from dotenv import load_dotenv
4
+
5
+ load_dotenv()
6
+
7
+
8
+ async def main():
9
+ # Create a new instance
10
+ print("Creating new Hubspot instance...")
11
+ env = await flt.env.make_async("hubspot:v1.2.7")
12
+ print(f"New Instance: {env.instance_id}")
13
+
14
+ try:
15
+ # Reset the instance
16
+ response = await env.reset(seed=42)
17
+ print(f"Reset response: {response}")
18
+
19
+ # Get the database resource
20
+ db = env.db()
21
+
22
+ # Example 1: Query with the builder pattern
23
+ print("\n=== Query Builder Examples ===")
24
+
25
+ # Find all entries of type 'deal'
26
+ print("\n1. Finding all deals:")
27
+ deals = await db.table("entries").eq("type", "deal").all()
28
+ print(f"Found {len(deals)} deals")
29
+
30
+ # Count entries
31
+ print("\n2. Counting entries:")
32
+ entry_count = await db.table("entries").count()
33
+ print(f"Total entries: {entry_count}")
34
+
35
+ # Find a specific entry
36
+ print("\n3. Finding specific entry:")
37
+ entry = await db.table("entries").eq("id", 1).first()
38
+ if entry:
39
+ print(f"Found entry: {entry['name']} (type: {entry['type']})")
40
+
41
+ # Complex query with multiple conditions
42
+ print("\n4. Complex query with conditions:")
43
+ recent_deals = await (
44
+ db.table("entries")
45
+ .eq("type", "deal")
46
+ .not_null("name")
47
+ .select("id", "name", "type", "createdDate")
48
+ .sort("createdDate", desc=True)
49
+ .limit(5)
50
+ .all()
51
+ )
52
+ print(f"Recent deals: {len(recent_deals)}")
53
+ for deal in recent_deals:
54
+ print(f" - {deal['name']} (id: {deal['id']})")
55
+
56
+ # Using assertions
57
+ print("\n5. Using assertions:")
58
+ try:
59
+ # This should succeed if there are entries
60
+ await db.table("entries").assert_exists()
61
+ print("✓ Entries table has records")
62
+ except AssertionError as e:
63
+ print(f"✗ Assertion failed: {e}")
64
+
65
+ # Check for non-existent record
66
+ try:
67
+ await db.table("entries").eq("id", 999999).assert_none()
68
+ print("✓ No entry with id 999999")
69
+ except AssertionError as e:
70
+ print(f"✗ Assertion failed: {e}")
71
+
72
+ # Insert a new entry and verify with query builder
73
+ print("\n6. Insert and verify with query builder:")
74
+ insert_query = """
75
+ INSERT INTO entries (id, name, type, owner_id, createdDate, lastModifiedDate, createdAt, updatedAt, properties)
76
+ VALUES (
77
+ 99999,
78
+ 'Test Deal via Query Builder',
79
+ 'deal',
80
+ 1,
81
+ datetime('now'),
82
+ datetime('now'),
83
+ datetime('now'),
84
+ datetime('now'),
85
+ '{}'
86
+ )
87
+ """
88
+ await db.exec(insert_query)
89
+
90
+ # Verify insertion with query builder
91
+ new_deal = await db.table("entries").eq("id", 99999).first()
92
+ if new_deal:
93
+ print(f"✓ Successfully inserted: {new_deal['name']}")
94
+
95
+ # Assert specific field value
96
+ await db.table("entries").eq("id", 99999).assert_eq("name", "Test Deal via Query Builder")
97
+ print("✓ Name assertion passed")
98
+
99
+ # Using IN clause
100
+ print("\n7. Using IN clause:")
101
+ specific_entries = await db.table("entries").in_("id", [1, 2, 3]).all()
102
+ print(f"Found {len(specific_entries)} entries with ids in [1, 2, 3]")
103
+
104
+ # Pattern matching with LIKE
105
+ print("\n8. Pattern matching:")
106
+ test_entries = await db.table("entries").ilike("name", "%test%").all()
107
+ print(f"Found {len(test_entries)} entries with 'test' in name")
108
+
109
+ finally:
110
+ # Delete the instance
111
+ print("\n\nDeleting instance...")
112
+ await env.close()
113
+ print("Instance deleted.")
114
+
115
+
116
+ if __name__ == "__main__":
117
+ asyncio.run(main())
fleet/__init__.py CHANGED
@@ -23,60 +23,71 @@ from .exceptions import (
23
23
  FleetConfigurationError,
24
24
  )
25
25
  from .client import Fleet, Environment
26
- from ._async.client import AsyncFleet, AsyncEnvironment
27
- from .models import InstanceRequest
28
- from .instance import (
29
- InstanceClient,
30
- ResetRequest,
31
- ResetResponse,
32
- CDPDescribeResponse,
33
- ChromeStartRequest,
34
- ChromeStartResponse,
35
- ChromeStatusResponse,
36
- )
37
- from ._async.instance import AsyncInstanceClient
26
+ from ._async.client import AsyncFleet, AsyncEnv
27
+ from .models import InstanceRecord
28
+ from .instance.models import Resource, ResetResponse
29
+
30
+ # Import sync verifiers with explicit naming
38
31
  from .verifiers import (
32
+ verifier as verifier_sync,
33
+ SyncVerifierFunction,
39
34
  DatabaseSnapshot,
40
35
  IgnoreConfig,
41
36
  SnapshotDiff,
42
37
  TASK_SUCCESSFUL_SCORE,
43
38
  )
39
+
40
+ # Import Playwright wrapper
41
+ from .playwright import FleetPlaywrightWrapper
42
+
43
+ # Import async verifiers (default verifier is async for modern usage)
44
+ from ._async.verifiers import (
45
+ verifier,
46
+ AsyncVerifierFunction,
47
+ )
48
+
49
+ # Import async tasks (default tasks are async for modern usage)
50
+ from ._async.tasks import Task
51
+
52
+ # Import shared types
53
+ from .types import VerifierFunction
54
+
55
+ # Create a module-level env attribute for convenient access
44
56
  from . import env
45
57
 
46
- # Optional playwright integration
47
- try:
48
- from .playwright import FleetPlaywrightWrapper
49
- _PLAYWRIGHT_AVAILABLE = True
50
- except ImportError:
51
- FleetPlaywrightWrapper = None
52
- _PLAYWRIGHT_AVAILABLE = False
58
+ __version__ = "0.1.0"
53
59
 
54
- __version__ = "0.1.1"
55
60
  __all__ = [
56
- "env",
57
- "FleetError",
58
- "FleetAPIError",
59
- "FleetTimeoutError",
60
- "FleetConfigurationError",
61
+ # Core classes
61
62
  "Fleet",
62
63
  "Environment",
63
64
  "AsyncFleet",
64
- "AsyncEnvironment",
65
- "InstanceClient",
66
- "AsyncInstanceClient",
67
- "InstanceRequest",
68
- "ResetRequest",
65
+ "AsyncEnv",
66
+ # Models
67
+ "InstanceRecord",
68
+ "Resource",
69
69
  "ResetResponse",
70
- "CDPDescribeResponse",
71
- "ChromeStartRequest",
72
- "ChromeStartResponse",
73
- "ChromeStatusResponse",
70
+ # Task models
71
+ "Task",
72
+ "VerifierFunction",
73
+ # Exceptions
74
+ "FleetError",
75
+ "FleetAPIError",
76
+ "FleetTimeoutError",
77
+ "FleetConfigurationError",
78
+ # Playwright wrapper
79
+ "FleetPlaywrightWrapper",
80
+ # Verifiers (async is default)
81
+ "verifier",
82
+ "verifier_sync",
83
+ "AsyncVerifierFunction",
84
+ "SyncVerifierFunction",
74
85
  "DatabaseSnapshot",
75
- "IgnoreConfig",
86
+ "IgnoreConfig",
76
87
  "SnapshotDiff",
77
88
  "TASK_SUCCESSFUL_SCORE",
78
- ]
79
-
80
- # Add playwright wrapper to exports if available
81
- if _PLAYWRIGHT_AVAILABLE:
82
- __all__.append("FleetPlaywrightWrapper")
89
+ # Environment module
90
+ "env",
91
+ # Version
92
+ "__version__",
93
+ ]
fleet/_async/base.py CHANGED
@@ -1,8 +1,10 @@
1
1
  import httpx
2
2
  from typing import Dict, Any, Optional
3
3
  import json
4
+ import logging
4
5
 
5
6
  from ..models import InstanceResponse
7
+ from ..config import GLOBAL_BASE_URL
6
8
  from .exceptions import (
7
9
  FleetAPIError,
8
10
  FleetAuthenticationError,
@@ -18,6 +20,8 @@ from .exceptions import (
18
20
  FleetPermissionError,
19
21
  )
20
22
 
23
+ logger = logging.getLogger(__name__)
24
+
21
25
 
22
26
  class EnvironmentBase(InstanceResponse):
23
27
  @property
@@ -31,7 +35,7 @@ class BaseWrapper:
31
35
  raise ValueError("api_key is required")
32
36
  self.api_key = api_key
33
37
  if base_url is None:
34
- base_url = "https://orchestrator.fleetai.com"
38
+ base_url = GLOBAL_BASE_URL
35
39
  self.base_url = base_url
36
40
 
37
41
  def get_headers(self) -> Dict[str, str]:
@@ -40,6 +44,10 @@ class BaseWrapper:
40
44
  "X-Fleet-SDK-Version": "1.0.0",
41
45
  }
42
46
  headers["Authorization"] = f"Bearer {self.api_key}"
47
+ # Debug log
48
+ import logging
49
+ logger = logging.getLogger(__name__)
50
+ logger.debug(f"Headers being sent: {headers}")
43
51
  return headers
44
52
 
45
53
 
@@ -81,6 +89,11 @@ class AsyncWrapper(BaseWrapper):
81
89
  def _handle_error_response(self, response: httpx.Response) -> None:
82
90
  """Handle HTTP error responses and convert to appropriate Fleet exceptions."""
83
91
  status_code = response.status_code
92
+
93
+ # Debug log 500 errors
94
+ if status_code == 500:
95
+ logger.error(f"Got 500 error from {response.url}")
96
+ logger.error(f"Response text: {response.text}")
84
97
 
85
98
  # Try to parse error response as JSON
86
99
  try:
fleet/_async/client.py CHANGED
@@ -14,23 +14,32 @@
14
14
 
15
15
  """Fleet API Client for making HTTP requests to Fleet services."""
16
16
 
17
- import os
17
+ import base64
18
+ import cloudpickle
18
19
  import httpx
19
20
  import logging
20
- from typing import Optional, List
21
+ import os
22
+ from typing import List, Optional, Dict
21
23
 
22
24
  from .base import EnvironmentBase, AsyncWrapper
23
- from ..models import InstanceRequest, InstanceRecord, Environment as EnvironmentModel
25
+ from ..models import (
26
+ InstanceRequest,
27
+ InstanceRecord,
28
+ Environment as EnvironmentModel,
29
+ VerifiersCheckResponse,
30
+ VerificationResponse,
31
+ VerifiersExecuteResponse,
32
+ )
24
33
 
25
34
  from .instance import (
26
35
  AsyncInstanceClient,
27
36
  ResetRequest,
28
37
  ResetResponse,
29
- ValidatorType,
30
38
  ExecuteFunctionResponse,
31
39
  )
32
40
  from ..config import DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT, REGION_BASE_URL
33
41
  from .instance.base import default_httpx_client
42
+ from .instance.client import ValidatorType
34
43
  from .resources.base import Resource
35
44
  from .resources.sqlite import AsyncSQLiteResource
36
45
  from .resources.browser import AsyncBrowserResource
@@ -38,24 +47,43 @@ from .resources.browser import AsyncBrowserResource
38
47
  logger = logging.getLogger(__name__)
39
48
 
40
49
 
41
- async def _delete_instance(client: AsyncWrapper, instance_id: str) -> InstanceRecord:
42
- response = await client.request("DELETE", f"/v1/env/instances/{instance_id}")
43
- return InstanceRecord(**response.json())
44
-
45
-
46
- class AsyncEnvironment(EnvironmentBase):
47
- def __init__(self, client: AsyncWrapper, **kwargs):
50
+ class AsyncEnv(EnvironmentBase):
51
+ def __init__(self, client: Optional[AsyncWrapper], **kwargs):
48
52
  super().__init__(**kwargs)
49
53
  self._client = client
54
+ self._apps: Dict[str, AsyncInstanceClient] = {}
50
55
  self._instance: Optional[AsyncInstanceClient] = None
51
56
 
52
57
  @property
53
58
  def instance(self) -> AsyncInstanceClient:
54
59
  if self._instance is None:
55
60
  self._instance = AsyncInstanceClient(
56
- self.manager_url, self._client.httpx_client
61
+ self.manager_url, self._client.httpx_client if self._client else None
57
62
  )
58
63
  return self._instance
64
+
65
+ def app(self, name: str) -> AsyncInstanceClient:
66
+ if name not in self._apps:
67
+ # Extract base URL by removing the current app path (e.g., /sentry/api/v1/env)
68
+ # manager_url looks like: https://xxx.fleetai.com/sentry/api/v1/env
69
+ base_url = self.manager_url.split('/api/v1/env')[0]
70
+ # Remove the current app name (e.g., /sentry) to get the root
71
+ if '/' in base_url:
72
+ parts = base_url.rsplit('/', 1)
73
+ if len(parts) == 2:
74
+ base_url = parts[0]
75
+
76
+ self._apps[name] = AsyncInstanceClient(
77
+ f"{base_url}/{name}/api/v1/env",
78
+ self._client.httpx_client if self._client else None,
79
+ )
80
+ return self._apps[name]
81
+
82
+ @property
83
+ def _load_client(self) -> AsyncWrapper:
84
+ if self._client is None:
85
+ raise ValueError("Client not initialized")
86
+ return self._client
59
87
 
60
88
  async def reset(
61
89
  self, seed: Optional[int] = None, timestamp: Optional[int] = None
@@ -75,7 +103,7 @@ class AsyncEnvironment(EnvironmentBase):
75
103
  return await self.instance.resources()
76
104
 
77
105
  async def close(self) -> InstanceRecord:
78
- return await _delete_instance(self._client, self.instance_id)
106
+ return await _delete_instance(self._load_client, self.instance_id)
79
107
 
80
108
  async def verify(self, validator: ValidatorType) -> ExecuteFunctionResponse:
81
109
  return await self.instance.verify(validator)
@@ -85,6 +113,41 @@ class AsyncEnvironment(EnvironmentBase):
85
113
  ) -> ExecuteFunctionResponse:
86
114
  return await self.instance.verify_raw(function_code, function_name)
87
115
 
116
+ async def check_bundle_exists(self, bundle_hash: str) -> VerifiersCheckResponse:
117
+ return await _check_bundle_exists(self._load_client, bundle_hash)
118
+
119
+ async def execute_verifier_remote(
120
+ self,
121
+ bundle_data: bytes,
122
+ bundle_sha: str,
123
+ key: str,
124
+ function_name: str,
125
+ args: tuple,
126
+ kwargs: dict,
127
+ timeout: Optional[int] = 30,
128
+ needs_upload: bool = True,
129
+ ) -> VerifiersExecuteResponse:
130
+ return await _execute_verifier_remote(
131
+ self._load_client,
132
+ bundle_data,
133
+ bundle_sha,
134
+ key,
135
+ function_name,
136
+ args,
137
+ kwargs,
138
+ timeout,
139
+ needs_upload
140
+ )
141
+
142
+ def __getstate__(self):
143
+ state = self.__dict__.copy()
144
+ state.pop("_client", None)
145
+ state.pop("_instance", None)
146
+ return state
147
+
148
+ def __setstate__(self, state):
149
+ self.__dict__.update(state)
150
+
88
151
 
89
152
  class AsyncFleet:
90
153
  def __init__(
@@ -116,7 +179,7 @@ class AsyncFleet:
116
179
 
117
180
  async def make(
118
181
  self, env_key: str, region: Optional[str] = None
119
- ) -> AsyncEnvironment:
182
+ ) -> AsyncEnv:
120
183
  if ":" in env_key:
121
184
  env_key_part, version = env_key.split(":", 1)
122
185
  if not version.startswith("v"):
@@ -133,13 +196,13 @@ class AsyncFleet:
133
196
  json=request.model_dump(),
134
197
  base_url=region_base_url,
135
198
  )
136
- instance = AsyncEnvironment(client=self.client, **response.json())
199
+ instance = AsyncEnv(client=self.client, **response.json())
137
200
  await instance.instance.load()
138
201
  return instance
139
202
 
140
203
  async def instances(
141
204
  self, status: Optional[str] = None, region: Optional[str] = None
142
- ) -> List[AsyncEnvironment]:
205
+ ) -> List[AsyncEnv]:
143
206
  params = {}
144
207
  if status:
145
208
  params["status"] = status
@@ -148,15 +211,88 @@ class AsyncFleet:
148
211
 
149
212
  response = await self.client.request("GET", "/v1/env/instances", params=params)
150
213
  return [
151
- AsyncEnvironment(client=self.client, **instance_data)
214
+ AsyncEnv(client=self.client, **instance_data)
152
215
  for instance_data in response.json()
153
216
  ]
154
217
 
155
- async def instance(self, instance_id: str) -> AsyncEnvironment:
218
+ async def instance(self, instance_id: str) -> AsyncEnv:
156
219
  response = await self.client.request("GET", f"/v1/env/instances/{instance_id}")
157
- instance = AsyncEnvironment(client=self.client, **response.json())
220
+ instance = AsyncEnv(client=self.client, **response.json())
158
221
  await instance.instance.load()
159
222
  return instance
160
223
 
224
+ async def check_bundle_exists(self, bundle_hash: str) -> VerifiersCheckResponse:
225
+ return await _check_bundle_exists(self.client, bundle_hash)
226
+
227
+ async def execute_verifier_remote(
228
+ self, bundle_data: bytes, args: tuple, kwargs: dict, timeout: Optional[int] = 30
229
+ ) -> VerifiersExecuteResponse:
230
+ return await _execute_verifier_remote(
231
+ self.client, bundle_data, args, kwargs, timeout
232
+ )
233
+
161
234
  async def delete(self, instance_id: str) -> InstanceRecord:
162
235
  return await _delete_instance(self.client, instance_id)
236
+
237
+
238
+ # Shared
239
+ async def _delete_instance(client: AsyncWrapper, instance_id: str) -> InstanceRecord:
240
+ response = await client.request("DELETE", f"/v1/env/instances/{instance_id}")
241
+ return InstanceRecord(**response.json())
242
+
243
+
244
+ async def _check_bundle_exists(
245
+ client: AsyncWrapper, bundle_hash: str
246
+ ) -> VerifiersCheckResponse:
247
+ response = await client.request("GET", f"/v1/verifiers/check?sha256={bundle_hash}")
248
+ return VerifiersCheckResponse(**response.json())
249
+
250
+
251
+ async def _execute_verifier_remote(
252
+ client: AsyncWrapper,
253
+ bundle_data: bytes,
254
+ bundle_sha: str,
255
+ key: str,
256
+ function_name: str,
257
+ args: tuple,
258
+ kwargs: dict,
259
+ timeout: Optional[int] = 30,
260
+ needs_upload: bool = True,
261
+ ) -> VerificationResponse:
262
+ # Pickle args and kwargs together
263
+ # The first arg should be None as a placeholder for env
264
+ args_with_none = (None,) + args
265
+ args_kwargs_pickled = cloudpickle.dumps({"args": args_with_none, "kwargs": kwargs})
266
+ args_kwargs_b64 = base64.b64encode(args_kwargs_pickled).decode("utf-8")
267
+
268
+ # Build request data
269
+ request_data = {
270
+ "key": key,
271
+ "sha256": bundle_sha,
272
+ "args": args_kwargs_b64,
273
+ "function_name": function_name,
274
+ "timeout": timeout,
275
+ "region": "us-west-1", # TODO: make configurable
276
+ }
277
+
278
+ # Add bundle data only if upload is needed
279
+ if needs_upload:
280
+ bundle_b64 = base64.b64encode(bundle_data).decode("utf-8")
281
+ request_data["bundle"] = bundle_b64
282
+
283
+ # Debug logging
284
+ logger.debug(f"Sending verifier execute request: key={key}, sha256={bundle_sha[:8]}..., function_name={function_name}")
285
+ logger.debug(f"Request has bundle: {needs_upload}")
286
+ logger.debug(f"Using client with base_url: {client.base_url}")
287
+ logger.debug(f"Request data keys: {list(request_data.keys())}")
288
+ logger.debug(f"Bundle size: {len(request_data.get('bundle', ''))} chars" if 'bundle' in request_data else "No bundle")
289
+
290
+ # Note: This should be called on the instance URL, not the orchestrator
291
+ # The instance has manager URLs for verifier execution
292
+ response = await client.request("POST", "/v1/verifiers/execute", json=request_data)
293
+
294
+ # Debug the response
295
+ response_json = response.json()
296
+ logger.debug(f"Verifier execute response: {response_json}")
297
+
298
+ return VerifiersExecuteResponse(**response_json)
@@ -1,9 +1,9 @@
1
- from ..client import AsyncFleet, AsyncEnvironment
1
+ from ..client import AsyncFleet, AsyncEnv
2
2
  from ...models import Environment as EnvironmentModel
3
3
  from typing import List, Optional
4
4
 
5
5
 
6
- async def make_async(env_key: str, region: Optional[str] = None) -> AsyncEnvironment:
6
+ async def make_async(env_key: str, region: Optional[str] = None) -> AsyncEnv:
7
7
  return await AsyncFleet().make(env_key, region=region)
8
8
 
9
9
 
@@ -17,9 +17,9 @@ async def list_regions_async() -> List[str]:
17
17
 
18
18
  async def list_instances_async(
19
19
  status: Optional[str] = None, region: Optional[str] = None
20
- ) -> List[AsyncEnvironment]:
20
+ ) -> List[AsyncEnv]:
21
21
  return await AsyncFleet().instances(status=status, region=region)
22
22
 
23
23
 
24
- async def get_async(instance_id: str) -> AsyncEnvironment:
24
+ async def get_async(instance_id: str) -> AsyncEnv:
25
25
  return await AsyncFleet().instance(instance_id)
@@ -12,7 +12,6 @@ from ...instance.models import (
12
12
  )
13
13
 
14
14
  __all__ = [
15
- "ValidatorType",
16
15
  "AsyncInstanceClient",
17
16
  "ResetRequest",
18
17
  "ResetResponse",
@@ -20,5 +19,5 @@ __all__ = [
20
19
  "ChromeStartRequest",
21
20
  "ChromeStartResponse",
22
21
  "ChromeStatusResponse",
23
- "ExecuteFunctionResponse"
22
+ "ExecuteFunctionResponse",
24
23
  ]
@@ -51,7 +51,8 @@ class AsyncInstanceClient:
51
51
  self.base_url = url
52
52
  self.client = AsyncWrapper(
53
53
  url=self.base_url,
54
- httpx_client=httpx_client or default_httpx_client(DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT),
54
+ httpx_client=httpx_client
55
+ or default_httpx_client(DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT),
55
56
  )
56
57
  self._resources: Optional[List[ResourceModel]] = None
57
58
  self._resources_state: Dict[str, Dict[str, Resource]] = {
@@ -136,7 +137,7 @@ class AsyncInstanceClient:
136
137
 
137
138
  self._resources = [ResourceModel(**resource) for resource in resources_list]
138
139
  for resource in self._resources:
139
- if resource.type not in self._resources_state:
140
+ if resource.type.value not in self._resources_state:
140
141
  self._resources_state[resource.type.value] = {}
141
142
  self._resources_state[resource.type.value][resource.name] = (
142
143
  RESOURCE_TYPES[resource.type](resource, self.client)
@@ -1,7 +1,7 @@
1
1
  import base64
2
2
  from typing import List, Dict, Any
3
3
  from playwright.async_api import async_playwright, Browser, Page
4
- from .client import AsyncEnvironment
4
+ from .client import AsyncEnv
5
5
 
6
6
 
7
7
  # Key mapping for computer use actions
@@ -65,7 +65,7 @@ class AsyncFleetPlaywrightWrapper:
65
65
 
66
66
  def __init__(
67
67
  self,
68
- env: AsyncEnvironment,
68
+ env: AsyncEnv,
69
69
  display_width: int = 1920,
70
70
  display_height: int = 1080,
71
71
  ):