fleet-python 0.2.28__py3-none-any.whl → 0.2.32__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 (61) hide show
  1. examples/diff_example.py +30 -20
  2. examples/dsl_example.py +12 -7
  3. examples/example.py +4 -4
  4. examples/example_account.py +8 -0
  5. examples/example_action_log.py +2 -2
  6. examples/example_client.py +2 -2
  7. examples/example_mcp_anthropic.py +8 -5
  8. examples/example_mcp_openai.py +2 -2
  9. examples/example_sync.py +4 -4
  10. examples/example_task.py +16 -6
  11. examples/example_tasks.py +3 -6
  12. examples/example_verifier.py +16 -3
  13. examples/gemini_example.py +6 -6
  14. examples/json_tasks_example.py +2 -2
  15. examples/nova_act_example.py +2 -2
  16. examples/openai_example.py +3 -3
  17. examples/openai_simple_example.py +3 -3
  18. examples/query_builder_example.py +11 -7
  19. fleet/__init__.py +60 -5
  20. fleet/_async/__init__.py +258 -1
  21. fleet/_async/base.py +2 -1
  22. fleet/_async/client.py +194 -127
  23. fleet/_async/env/client.py +5 -1
  24. fleet/_async/global_client.py +43 -0
  25. fleet/_async/instance/client.py +1 -1
  26. fleet/_async/models.py +172 -171
  27. fleet/_async/resources/base.py +1 -1
  28. fleet/_async/resources/mcp.py +55 -0
  29. fleet/_async/resources/sqlite.py +141 -130
  30. fleet/_async/tasks.py +71 -16
  31. fleet/_async/verifiers/__init__.py +2 -2
  32. fleet/_async/verifiers/bundler.py +18 -14
  33. fleet/_async/verifiers/verifier.py +77 -71
  34. fleet/base.py +2 -1
  35. fleet/client.py +176 -136
  36. fleet/config.py +3 -2
  37. fleet/env/__init__.py +10 -1
  38. fleet/env/client.py +5 -1
  39. fleet/global_client.py +43 -0
  40. fleet/instance/__init__.py +1 -1
  41. fleet/instance/client.py +2 -4
  42. fleet/models.py +172 -171
  43. fleet/resources/base.py +1 -1
  44. fleet/resources/mcp.py +27 -33
  45. fleet/resources/sqlite.py +136 -131
  46. fleet/tasks.py +197 -16
  47. fleet/types.py +1 -1
  48. fleet/verifiers/__init__.py +2 -2
  49. fleet/verifiers/bundler.py +18 -14
  50. fleet/verifiers/code.py +1 -1
  51. fleet/verifiers/decorator.py +25 -34
  52. fleet/verifiers/parse.py +98 -68
  53. fleet/verifiers/verifier.py +77 -78
  54. {fleet_python-0.2.28.dist-info → fleet_python-0.2.32.dist-info}/METADATA +9 -9
  55. fleet_python-0.2.32.dist-info/RECORD +74 -0
  56. scripts/fix_sync_imports.py +87 -59
  57. scripts/unasync.py +10 -9
  58. fleet_python-0.2.28.dist-info/RECORD +0 -70
  59. {fleet_python-0.2.28.dist-info → fleet_python-0.2.32.dist-info}/WHEEL +0 -0
  60. {fleet_python-0.2.28.dist-info → fleet_python-0.2.32.dist-info}/licenses/LICENSE +0 -0
  61. {fleet_python-0.2.28.dist-info → fleet_python-0.2.32.dist-info}/top_level.txt +0 -0
fleet/__init__.py CHANGED
@@ -14,6 +14,8 @@
14
14
 
15
15
  """Fleet Python SDK - Environment-based AI agent interactions."""
16
16
 
17
+ from typing import Optional, List
18
+
17
19
  from .exceptions import (
18
20
  FleetError,
19
21
  FleetAPIError,
@@ -52,6 +54,8 @@ from .types import VerifierFunction
52
54
 
53
55
  # Create a module-level env attribute for convenient access
54
56
  from . import env
57
+ from . import global_client as _global_client
58
+ from ._async import global_client as _async_global_client
55
59
 
56
60
  __version__ = "0.1.0"
57
61
 
@@ -63,7 +67,7 @@ __all__ = [
63
67
  "AsyncEnv",
64
68
  # Models
65
69
  "InstanceResponse",
66
- "SyncEnv",
70
+ "SyncEnv",
67
71
  "Resource",
68
72
  "ResetResponse",
69
73
  # Task models
@@ -71,21 +75,72 @@ __all__ = [
71
75
  "VerifierFunction",
72
76
  # Exceptions
73
77
  "FleetError",
74
- "FleetAPIError",
78
+ "FleetAPIError",
75
79
  "FleetTimeoutError",
76
80
  "FleetConfigurationError",
77
81
  # Verifiers (async is default)
78
82
  "verifier",
79
- "verifier_sync",
83
+ "verifier_sync",
80
84
  "AsyncVerifierFunction",
81
85
  "SyncVerifierFunction",
82
86
  "DatabaseSnapshot",
83
- "IgnoreConfig",
87
+ "IgnoreConfig",
84
88
  "SnapshotDiff",
85
89
  "TASK_FAILED_SCORE",
86
90
  "TASK_SUCCESSFUL_SCORE",
87
91
  # Environment module
88
92
  "env",
93
+ # Global client helpers
94
+ "configure",
95
+ "get_client",
96
+ "reset_client",
89
97
  # Version
90
98
  "__version__",
91
- ]
99
+ ]
100
+
101
+
102
+ def load_tasks(env_key: Optional[str] = None) -> List[Task]:
103
+ """Load tasks without explicitly creating a client.
104
+
105
+ Example:
106
+ tasks = fleet.load_tasks(env_key="fira")
107
+ """
108
+ # Use global client by default so users can configure once
109
+ return _global_client.get_client().load_tasks(env_key=env_key)
110
+
111
+
112
+ def configure(
113
+ api_key: Optional[str] = None,
114
+ base_url: Optional[str] = None,
115
+ max_retries: int | None = None,
116
+ timeout: float | None = None,
117
+ ):
118
+ """Configure global clients (sync and async) once per process.
119
+
120
+ Both sync and async default clients will be (re)created with the provided settings.
121
+ """
122
+ if max_retries is None:
123
+ from .config import DEFAULT_MAX_RETRIES as _MR
124
+
125
+ max_retries = _MR
126
+ if timeout is None:
127
+ from .config import DEFAULT_TIMEOUT as _TO
128
+
129
+ timeout = _TO
130
+ _global_client.configure(
131
+ api_key=api_key, base_url=base_url, max_retries=max_retries, timeout=timeout
132
+ )
133
+ _async_global_client.configure(
134
+ api_key=api_key, base_url=base_url, max_retries=max_retries, timeout=timeout
135
+ )
136
+
137
+
138
+ def get_client() -> Fleet:
139
+ """Get the global sync client."""
140
+ return _global_client.get_client()
141
+
142
+
143
+ def reset_client():
144
+ """Reset both sync and async global clients."""
145
+ _global_client.reset_client()
146
+ _async_global_client.reset_client()
fleet/_async/__init__.py CHANGED
@@ -1 +1,258 @@
1
- # This file makes the _async directory a proper Python package
1
+ # Copyright 2025 Fleet AI
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Fleet Python SDK - Async Environment-based AI agent interactions."""
16
+
17
+ from typing import Optional, List
18
+
19
+ from ..exceptions import (
20
+ FleetError,
21
+ FleetAPIError,
22
+ FleetTimeoutError,
23
+ FleetRateLimitError,
24
+ FleetInstanceLimitError,
25
+ FleetConfigurationError,
26
+ )
27
+ from .client import AsyncFleet, AsyncEnv
28
+ from ..models import InstanceResponse, Environment, AccountResponse
29
+ from ..instance.models import Resource, ResetResponse
30
+
31
+ # Import async verifiers
32
+ from .verifiers import (
33
+ verifier,
34
+ AsyncVerifierFunction,
35
+ )
36
+
37
+ # Import async tasks
38
+ from .tasks import Task
39
+
40
+ # Import shared types
41
+ from ..types import VerifierFunction
42
+
43
+ # Create a module-level env attribute for convenient access
44
+ from .. import env
45
+ from . import global_client as _async_global_client
46
+
47
+ __version__ = "0.1.0"
48
+
49
+ __all__ = [
50
+ # Core classes
51
+ "AsyncFleet",
52
+ "AsyncEnv",
53
+ # Models
54
+ "InstanceResponse",
55
+ "Resource",
56
+ "ResetResponse",
57
+ # Task models
58
+ "Task",
59
+ "VerifierFunction",
60
+ # Exceptions
61
+ "FleetError",
62
+ "FleetAPIError",
63
+ "FleetTimeoutError",
64
+ "FleetConfigurationError",
65
+ # Verifiers
66
+ "verifier",
67
+ "AsyncVerifierFunction",
68
+ # Environment module
69
+ "env",
70
+ # Global client helpers
71
+ "configure",
72
+ "get_client",
73
+ "reset_client",
74
+ # Module-level functions
75
+ "load_tasks",
76
+ "list_envs",
77
+ "list_regions",
78
+ "environment",
79
+ "make",
80
+ "make_for_task",
81
+ "instances",
82
+ "instance",
83
+ "delete",
84
+ "load_tasks_from_file",
85
+ "load_task_array_from_string",
86
+ "load_task_from_string",
87
+ "load_task_from_json",
88
+ "export_tasks",
89
+ "import_tasks",
90
+ "account",
91
+ # Version
92
+ "__version__",
93
+ ]
94
+
95
+
96
+ async def load_tasks(
97
+ env_key: Optional[str] = None,
98
+ keys: Optional[List[str]] = None,
99
+ version: Optional[str] = None,
100
+ team_id: Optional[str] = None
101
+ ) -> List[Task]:
102
+ """Load tasks with optional filtering.
103
+
104
+ Args:
105
+ env_key: Optional environment key to filter tasks by
106
+ keys: Optional list of task keys to filter by
107
+ version: Optional version to filter tasks by
108
+
109
+ Examples:
110
+ tasks = await fleet.load_tasks(env_key="fira")
111
+ tasks = await fleet.load_tasks(keys=["task1", "task2"])
112
+ tasks = await fleet.load_tasks(env_key="fira", version="v1.0")
113
+ """
114
+ # Use global client by default so users can configure once
115
+ return await _async_global_client.get_client().load_tasks(
116
+ env_key=env_key,
117
+ keys=keys,
118
+ version=version,
119
+ team_id=team_id
120
+ )
121
+
122
+
123
+ async def list_envs() -> List[Environment]:
124
+ """List all available environments."""
125
+ return await _async_global_client.get_client().list_envs()
126
+
127
+
128
+ async def list_regions() -> List[str]:
129
+ """List all available regions."""
130
+ return await _async_global_client.get_client().list_regions()
131
+
132
+
133
+ async def environment(env_key: str) -> Environment:
134
+ """Get environment details by key."""
135
+ return await _async_global_client.get_client().environment(env_key)
136
+
137
+
138
+ async def make(env_key: str, region: Optional[str] = None) -> AsyncEnv:
139
+ """Create a new environment instance.
140
+
141
+ Example:
142
+ env = await fleet.make("fira")
143
+ """
144
+ return await _async_global_client.get_client().make(env_key, region)
145
+
146
+
147
+ async def make_for_task(task: Task) -> AsyncEnv:
148
+ """Create an environment instance for a specific task."""
149
+ return await _async_global_client.get_client().make_for_task(task)
150
+
151
+
152
+ async def instances(status: Optional[str] = None, region: Optional[str] = None) -> List[AsyncEnv]:
153
+ """List existing environment instances."""
154
+ return await _async_global_client.get_client().instances(status, region)
155
+
156
+
157
+ async def instance(instance_id: str) -> AsyncEnv:
158
+ """Get an existing environment instance by ID."""
159
+ return await _async_global_client.get_client().instance(instance_id)
160
+
161
+
162
+ async def delete(instance_id: str) -> InstanceResponse:
163
+ """Delete an environment instance."""
164
+ return await _async_global_client.get_client().delete(instance_id)
165
+
166
+
167
+ async def load_tasks_from_file(filename: str) -> List[Task]:
168
+ """Load tasks from a JSON file.
169
+
170
+ Example:
171
+ tasks = await fleet.load_tasks_from_file("my_tasks.json")
172
+ """
173
+ return await _async_global_client.get_client().load_tasks_from_file(filename)
174
+
175
+
176
+ async def load_task_array_from_string(serialized_tasks: str) -> List[Task]:
177
+ """Load tasks from a JSON string containing an array of tasks.
178
+
179
+ Example:
180
+ tasks = await fleet.load_task_array_from_string(json_string)
181
+ """
182
+ return await _async_global_client.get_client().load_task_array_from_string(serialized_tasks)
183
+
184
+
185
+ async def load_task_from_string(task_string: str) -> Task:
186
+ """Load a single task from a JSON string.
187
+
188
+ Example:
189
+ task = await fleet.load_task_from_string(task_json_string)
190
+ """
191
+ return await _async_global_client.get_client().load_task_from_string(task_string)
192
+
193
+
194
+ async def load_task_from_json(task_json: dict) -> Task:
195
+ """Load a single task from a dictionary.
196
+
197
+ Example:
198
+ task = await fleet.load_task_from_json(task_dict)
199
+ """
200
+ return await _async_global_client.get_client().load_task_from_json(task_json)
201
+
202
+
203
+ async def export_tasks(env_key: Optional[str] = None, filename: Optional[str] = None) -> Optional[str]:
204
+ """Export tasks to a JSON file.
205
+
206
+ Example:
207
+ await fleet.export_tasks("fira", "fira_tasks.json")
208
+ """
209
+ return await _async_global_client.get_client().export_tasks(env_key, filename)
210
+
211
+
212
+ async def import_tasks(filename: str):
213
+ """Import tasks from a JSON file.
214
+
215
+ Example:
216
+ await fleet.import_tasks("tasks.json")
217
+ """
218
+ return await _async_global_client.get_client().import_tasks(filename)
219
+
220
+
221
+ async def account() -> AccountResponse:
222
+ """Get account information including instance limits and usage."""
223
+ return await _async_global_client.get_client().account()
224
+
225
+
226
+ def configure(
227
+ api_key: Optional[str] = None,
228
+ base_url: Optional[str] = None,
229
+ max_retries: int | None = None,
230
+ timeout: float | None = None,
231
+ ):
232
+ """Configure global async client once per process.
233
+
234
+ Args:
235
+ api_key: API key for authentication
236
+ base_url: Base URL for the API
237
+ max_retries: Maximum number of retries
238
+ timeout: Request timeout in seconds
239
+ """
240
+ if max_retries is None:
241
+ from ..config import DEFAULT_MAX_RETRIES as _MR
242
+ max_retries = _MR
243
+ if timeout is None:
244
+ from ..config import DEFAULT_TIMEOUT as _TO
245
+ timeout = _TO
246
+ _async_global_client.configure(
247
+ api_key=api_key, base_url=base_url, max_retries=max_retries, timeout=timeout
248
+ )
249
+
250
+
251
+ def get_client() -> AsyncFleet:
252
+ """Get the global async client."""
253
+ return _async_global_client.get_client()
254
+
255
+
256
+ def reset_client():
257
+ """Reset the async global client."""
258
+ _async_global_client.reset_client()
fleet/_async/base.py CHANGED
@@ -46,6 +46,7 @@ class BaseWrapper:
46
46
  headers["Authorization"] = f"Bearer {self.api_key}"
47
47
  # Debug log
48
48
  import logging
49
+
49
50
  logger = logging.getLogger(__name__)
50
51
  logger.debug(f"Headers being sent: {headers}")
51
52
  return headers
@@ -89,7 +90,7 @@ class AsyncWrapper(BaseWrapper):
89
90
  def _handle_error_response(self, response: httpx.Response) -> None:
90
91
  """Handle HTTP error responses and convert to appropriate Fleet exceptions."""
91
92
  status_code = response.status_code
92
-
93
+
93
94
  # Debug log 500 errors
94
95
  if status_code == 500:
95
96
  logger.error(f"Got 500 error from {response.url}")