fleet-python 0.2.66b2__py3-none-any.whl → 0.2.105__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.
Files changed (70) hide show
  1. examples/export_tasks.py +16 -5
  2. examples/export_tasks_filtered.py +245 -0
  3. examples/fetch_tasks.py +230 -0
  4. examples/import_tasks.py +140 -8
  5. examples/iterate_verifiers.py +725 -0
  6. fleet/__init__.py +128 -5
  7. fleet/_async/__init__.py +27 -3
  8. fleet/_async/base.py +24 -9
  9. fleet/_async/client.py +938 -41
  10. fleet/_async/env/client.py +60 -3
  11. fleet/_async/instance/client.py +52 -7
  12. fleet/_async/models.py +15 -0
  13. fleet/_async/resources/api.py +200 -0
  14. fleet/_async/resources/sqlite.py +1801 -46
  15. fleet/_async/tasks.py +122 -25
  16. fleet/_async/verifiers/bundler.py +22 -21
  17. fleet/_async/verifiers/verifier.py +25 -19
  18. fleet/agent/__init__.py +32 -0
  19. fleet/agent/gemini_cua/Dockerfile +45 -0
  20. fleet/agent/gemini_cua/__init__.py +10 -0
  21. fleet/agent/gemini_cua/agent.py +759 -0
  22. fleet/agent/gemini_cua/mcp/main.py +108 -0
  23. fleet/agent/gemini_cua/mcp_server/__init__.py +5 -0
  24. fleet/agent/gemini_cua/mcp_server/main.py +105 -0
  25. fleet/agent/gemini_cua/mcp_server/tools.py +178 -0
  26. fleet/agent/gemini_cua/requirements.txt +5 -0
  27. fleet/agent/gemini_cua/start.sh +30 -0
  28. fleet/agent/orchestrator.py +854 -0
  29. fleet/agent/types.py +49 -0
  30. fleet/agent/utils.py +34 -0
  31. fleet/base.py +34 -9
  32. fleet/cli.py +1061 -0
  33. fleet/client.py +1060 -48
  34. fleet/config.py +1 -1
  35. fleet/env/__init__.py +16 -0
  36. fleet/env/client.py +60 -3
  37. fleet/eval/__init__.py +15 -0
  38. fleet/eval/uploader.py +231 -0
  39. fleet/exceptions.py +8 -0
  40. fleet/instance/client.py +53 -8
  41. fleet/instance/models.py +1 -0
  42. fleet/models.py +303 -0
  43. fleet/proxy/__init__.py +25 -0
  44. fleet/proxy/proxy.py +453 -0
  45. fleet/proxy/whitelist.py +244 -0
  46. fleet/resources/api.py +200 -0
  47. fleet/resources/sqlite.py +1845 -46
  48. fleet/tasks.py +113 -20
  49. fleet/utils/__init__.py +7 -0
  50. fleet/utils/http_logging.py +178 -0
  51. fleet/utils/logging.py +13 -0
  52. fleet/utils/playwright.py +440 -0
  53. fleet/verifiers/bundler.py +22 -21
  54. fleet/verifiers/db.py +985 -1
  55. fleet/verifiers/decorator.py +1 -1
  56. fleet/verifiers/verifier.py +25 -19
  57. {fleet_python-0.2.66b2.dist-info → fleet_python-0.2.105.dist-info}/METADATA +28 -1
  58. fleet_python-0.2.105.dist-info/RECORD +115 -0
  59. {fleet_python-0.2.66b2.dist-info → fleet_python-0.2.105.dist-info}/WHEEL +1 -1
  60. fleet_python-0.2.105.dist-info/entry_points.txt +2 -0
  61. tests/test_app_method.py +85 -0
  62. tests/test_expect_exactly.py +4148 -0
  63. tests/test_expect_only.py +2593 -0
  64. tests/test_instance_dispatch.py +607 -0
  65. tests/test_sqlite_resource_dual_mode.py +263 -0
  66. tests/test_sqlite_shared_memory_behavior.py +117 -0
  67. fleet_python-0.2.66b2.dist-info/RECORD +0 -81
  68. tests/test_verifier_security.py +0 -427
  69. {fleet_python-0.2.66b2.dist-info → fleet_python-0.2.105.dist-info}/licenses/LICENSE +0 -0
  70. {fleet_python-0.2.66b2.dist-info → fleet_python-0.2.105.dist-info}/top_level.txt +0 -0
@@ -49,7 +49,7 @@ class SyncVerifierFunction:
49
49
  )
50
50
 
51
51
  except Exception as e:
52
- logger.error(f"Error in verifier {self.key}: {e}")
52
+ # logger.error(f"Error in verifier {self.key}: {e}")
53
53
  # Return error score 0
54
54
  return 0.0
55
55
 
@@ -53,6 +53,7 @@ class SyncVerifierFunction:
53
53
  verifier_id: Optional[str] = None,
54
54
  sha256: Optional[str] = None,
55
55
  raw_code: Optional[str] = None,
56
+ verifier_runtime_version: Optional[str] = None,
56
57
  ):
57
58
  self.func = func
58
59
  self.key = key
@@ -63,6 +64,7 @@ class SyncVerifierFunction:
63
64
  self._bundle_data: Optional[bytes] = None # Cached bundle data
64
65
  self._raw_code: Optional[str] = raw_code # Store raw code if provided
65
66
  self._is_async = inspect.iscoroutinefunction(func)
67
+ self.verifier_runtime_version = verifier_runtime_version
66
68
 
67
69
  # Copy function metadata
68
70
  functools.update_wrapper(self, func)
@@ -90,9 +92,9 @@ class SyncVerifierFunction:
90
92
 
91
93
  self._bundle_data = zip_buffer.getvalue()
92
94
  self._bundle_sha = _get_bundle_sha(self._bundle_data)
93
- logger.debug(
94
- f"Created bundle from raw code for {self.key} with SHA: {self._bundle_sha}"
95
- )
95
+ # logger.debug(
96
+ # f"Created bundle from raw code for {self.key} with SHA: {self._bundle_sha}"
97
+ # )
96
98
  else:
97
99
  # Try to create bundle from function source
98
100
  try:
@@ -100,9 +102,9 @@ class SyncVerifierFunction:
100
102
  self.func, self.extra_requirements, self.verifier_id
101
103
  )
102
104
  self._bundle_sha = _get_bundle_sha(self._bundle_data)
103
- logger.debug(
104
- f"Created bundle for {self.key} with SHA: {self._bundle_sha}"
105
- )
105
+ # logger.debug(
106
+ # f"Created bundle for {self.key} with SHA: {self._bundle_sha}"
107
+ # )
106
108
  except OSError as e:
107
109
  # Can't create bundle - no source and no raw code
108
110
  raise OSError(f"Cannot create bundle for {self.key}: {e}")
@@ -115,20 +117,21 @@ class SyncVerifierFunction:
115
117
 
116
118
  # If bundle_data is empty, we're using server-side bundle
117
119
  if not bundle_data:
118
- logger.debug(f"Using server-side bundle {bundle_sha[:8]}...")
120
+ # logger.debug(f"Using server-side bundle {bundle_sha[:8]}...")
119
121
  return bundle_sha, False # No upload needed, server has it
120
122
 
121
123
  # Always check if bundle exists on server
122
124
  try:
123
125
  exists = env.check_bundle_exists(bundle_sha)
124
126
  if exists.success:
125
- logger.info(f"Bundle {bundle_sha[:8]}... found on server")
127
+ # logger.info(f"Bundle {bundle_sha[:8]}... found on server")
126
128
  return bundle_sha, False # Found on server, no upload needed
127
129
  except Exception as e:
128
- logger.warning(f"Failed to check bundle existence: {e}")
130
+ # logger.warning(f"Failed to check bundle existence: {e}")
131
+ pass
129
132
 
130
133
  # Bundle not found on server - upload needed
131
- logger.info(f"Bundle {bundle_sha[:8]}... needs to be uploaded")
134
+ # logger.info(f"Bundle {bundle_sha[:8]}... needs to be uploaded")
132
135
  return bundle_sha, True # Upload needed
133
136
 
134
137
  def __call__(self, env: "SyncEnv", *args, **kwargs) -> float:
@@ -158,7 +161,7 @@ class SyncVerifierFunction:
158
161
  )
159
162
 
160
163
  except Exception as e:
161
- logger.error(f"Error in verifier {self.key}: {e}")
164
+ # logger.error(f"Error in verifier {self.key}: {e}")
162
165
  # Return error score 0
163
166
  return 0.0
164
167
 
@@ -190,7 +193,7 @@ class SyncVerifierFunction:
190
193
  try:
191
194
  return float(result)
192
195
  except (ValueError, TypeError):
193
- logger.warning(f"Could not convert result to float: {result}")
196
+ # logger.warning(f"Could not convert result to float: {result}")
194
197
  return 0.0
195
198
 
196
199
  def _raise_remote_error(self, error_info: Dict[str, Any]):
@@ -249,7 +252,7 @@ Remote traceback:
249
252
 
250
253
  if needs_upload:
251
254
  # Need to upload bundle to S3
252
- logger.info(f"Uploading bundle {bundle_sha[:8]}... for {self.key}")
255
+ # logger.info(f"Uploading bundle {bundle_sha[:8]}... for {self.key}")
253
256
  bundle_data, _ = self._get_or_create_bundle()
254
257
 
255
258
  response = env.execute_verifier_remote(
@@ -261,14 +264,15 @@ Remote traceback:
261
264
  args_array=args_array,
262
265
  kwargs=kwargs,
263
266
  needs_upload=True,
267
+ verifier_runtime_version=self.verifier_runtime_version,
264
268
  )
265
269
 
266
- logger.debug(f"Bundle {bundle_sha[:8]}... uploaded successfully")
270
+ # logger.debug(f"Bundle {bundle_sha[:8]}... uploaded successfully")
267
271
  return response
268
272
 
269
273
  else:
270
274
  # Bundle already available - execute without upload
271
- logger.info(f"Bundle {bundle_sha[:8]}... already cached for {self.key}")
275
+ # logger.info(f"Bundle {bundle_sha[:8]}... already cached for {self.key}")
272
276
  response = env.execute_verifier_remote(
273
277
  bundle_data=b"", # Empty bundle since it's cached
274
278
  bundle_sha=bundle_sha,
@@ -278,15 +282,16 @@ Remote traceback:
278
282
  args_array=args_array,
279
283
  kwargs=kwargs,
280
284
  needs_upload=False,
285
+ verifier_runtime_version=self.verifier_runtime_version,
281
286
  )
282
287
  return response
283
288
 
284
289
  except Exception as e:
285
290
  # Check if error indicates bundle not found and retry with upload
286
291
  if self._is_bundle_not_found_error(e) and not needs_upload:
287
- logger.info(
288
- f"Bundle {bundle_sha[:8]}... not found on server, uploading..."
289
- )
292
+ # logger.info(
293
+ # f"Bundle {bundle_sha[:8]}... not found on server, uploading..."
294
+ # )
290
295
  bundle_data, _ = self._get_or_create_bundle()
291
296
  response = env.execute_verifier_remote(
292
297
  bundle_data=bundle_data,
@@ -297,10 +302,11 @@ Remote traceback:
297
302
  args_array=args_array,
298
303
  kwargs=kwargs,
299
304
  needs_upload=True,
305
+ verifier_runtime_version=self.verifier_runtime_version,
300
306
  )
301
307
  return response
302
308
  else:
303
- logger.error(f"Error in remote execution of {self.key}: {e}")
309
+ # logger.error(f"Error in remote execution of {self.key}: {e}")
304
310
  raise
305
311
 
306
312
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fleet-python
3
- Version: 0.2.66b2
3
+ Version: 0.2.105
4
4
  Summary: Python SDK for Fleet environments
5
5
  Author-email: Fleet AI <nic@fleet.so>
6
6
  License: Apache-2.0
@@ -26,6 +26,9 @@ Requires-Dist: httpx-retries>=0.4.0
26
26
  Requires-Dist: typing-extensions>=4.0.0
27
27
  Requires-Dist: modulegraph2>=0.2.0
28
28
  Requires-Dist: cloudpickle==3.1.1
29
+ Provides-Extra: cli
30
+ Requires-Dist: typer>=0.9.0; extra == "cli"
31
+ Requires-Dist: rich>=10.0.0; extra == "cli"
29
32
  Provides-Extra: dev
30
33
  Requires-Dist: pytest>=7.0.0; extra == "dev"
31
34
  Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
@@ -35,12 +38,22 @@ Requires-Dist: mypy>=1.0.0; extra == "dev"
35
38
  Requires-Dist: ruff>=0.1.0; extra == "dev"
36
39
  Requires-Dist: unasync>=0.6.0; extra == "dev"
37
40
  Requires-Dist: python-dotenv>=1.1.1; extra == "dev"
41
+ Requires-Dist: typer>=0.9.0; extra == "dev"
42
+ Requires-Dist: rich>=10.0.0; extra == "dev"
38
43
  Provides-Extra: playwright
39
44
  Requires-Dist: playwright>=1.40.0; extra == "playwright"
45
+ Provides-Extra: eval
46
+ Requires-Dist: aiohttp>=3.9.0; extra == "eval"
47
+ Requires-Dist: google-genai>=1.0.0; extra == "eval"
48
+ Requires-Dist: mcp==1.24.0; python_version >= "3.10" and extra == "eval"
40
49
  Dynamic: license-file
41
50
 
42
51
  # Fleet SDK
43
52
 
53
+ [![PyPI version](https://img.shields.io/pypi/v/fleet-python.svg)](https://pypi.org/project/fleet-python/)
54
+ [![Python versions](https://img.shields.io/pypi/pyversions/fleet-python.svg)](https://pypi.org/project/fleet-python/)
55
+ [![License](https://img.shields.io/pypi/l/fleet-python.svg)](https://pypi.org/project/fleet-python/)
56
+
44
57
  The Fleet Python SDK provides programmatic access to Fleet's environment infrastructure.
45
58
 
46
59
  ## Installation
@@ -51,6 +64,20 @@ Install the Fleet SDK using pip:
51
64
  pip install fleet-python
52
65
  ```
53
66
 
67
+ ### Alpha/Pre-release Versions
68
+
69
+ To install the latest alpha or pre-release version:
70
+
71
+ ```bash
72
+ pip install --pre fleet-python
73
+ ```
74
+
75
+ To install a specific alpha version:
76
+
77
+ ```bash
78
+ pip install fleet-python==0.2.64-alpha1
79
+ ```
80
+
54
81
  ## API Key Setup
55
82
 
56
83
  Fleet requires an API key for authentication. You can obtain one from the [Fleet Platform](https://fleetai.com/dashboard/api-keys).
@@ -0,0 +1,115 @@
1
+ examples/diff_example.py,sha256=iLlpBW_NBjzXBqlvYwjx74uxYZkMGJfea6s3tJhvuNY,5684
2
+ examples/dsl_example.py,sha256=yFLgM-Was4-w575xJgPk9DIBmXa34hLJsIB4XwTADOE,7252
3
+ examples/example.py,sha256=yn9mqS2yJ6896s25btnJx9-_SLLbyS-Fu-SIcas6jok,1081
4
+ examples/exampleResume.py,sha256=hzdL9QfYtwlje5geWS2cgWgjcnLX4UtXSAd-92F66Lw,7044
5
+ examples/example_account.py,sha256=t5_Tnr7DcLYfNpEAbuBySQIqsqiQQGySuiItIghCjAM,225
6
+ examples/example_action_log.py,sha256=pwvLro_Fkrw4DII002bHGuWfoZ6QRvUMDD9BnMqJgLQ,622
7
+ examples/example_client.py,sha256=M9Mfi1FcD2LtSDVk89R_-tgG98swvDYy4qx2zVayJ-0,1025
8
+ examples/example_mcp_anthropic.py,sha256=WzQipN6ryPYuiGcvYmaTget4Hn421ijMS6xDYWwrVyE,2619
9
+ examples/example_mcp_openai.py,sha256=xhqJd2-mnQs4-ZmydGrX7pPs7_X5i-YFqkO1cr3L-5g,480
10
+ examples/example_sync.py,sha256=EkuWmUzB1ZsBJQk6ZRflB793rKsuRHeSg5HJZHVhBB0,975
11
+ examples/example_task.py,sha256=dhG6STAkNsTdHs9cO1RFH9WfuvRmq5bRC211hTeFrk8,7088
12
+ examples/example_tasks.py,sha256=xTL8UWVAuolSX6swskfrAcmDrLIzn45dJ7YPWCwoEBU,514
13
+ examples/example_verifier.py,sha256=0vwNITIG3m4CkSPwIxNXcGx9TqrxEsCGqK2A8keKZMM,2392
14
+ examples/export_tasks.py,sha256=JMNCMuAPxAzBm0B0JY7BZTHRBBBqsL7WWdLo9IRrdNk,3694
15
+ examples/export_tasks_filtered.py,sha256=FypvBrtNHOqnxuYTJ-gbb13raYAdnpPQDPySs3-dAgI,7726
16
+ examples/fetch_tasks.py,sha256=3A4F0OSUTwUddTOoDNlI-CSxeOnpl3E3zHBh0Qsw9A8,6865
17
+ examples/gemini_example.py,sha256=qj9WDazQTYNiRHNeUg9Tjkp33lJMwbx8gDfpFe1sDQo,16180
18
+ examples/import_tasks.py,sha256=QaapnE3lO68nrRRr0fB5n_NaDsIsQjgv1cbH60bBdUQ,16576
19
+ examples/iterate_verifiers.py,sha256=XbMWyWKAYKJSufVPehG3C_JeSC7ZVXw2_s1KzIMnGVs,25435
20
+ examples/json_tasks_example.py,sha256=CYPESGGtOo0fmsDdLidujTfsE4QlJHw7rOhyVqPJ_Ls,5329
21
+ examples/nova_act_example.py,sha256=rH23Lp74Okf0rn8ynMdWjK2aviEf5NLPH4k_53Pyxho,831
22
+ examples/openai_example.py,sha256=dEWERrTEP5xBiGkLkQjBQGd2NqoxX6gcW6XteBPsWFQ,8231
23
+ examples/openai_simple_example.py,sha256=HmiufucrAZne7tHq9uoEsDWlEhjNC265bQAyIGBRU2o,1745
24
+ examples/query_builder_example.py,sha256=-cOMfWGNifYfYEt_Ds73XpwATZvFDL6F4KTkVxdMjzg,3951
25
+ examples/quickstart.py,sha256=1VT39IRRhemsJgxi0O0gprdpcw7HB4pYO97GAYagIcg,3788
26
+ examples/test_cdp_logging.py,sha256=AkCwQCgOTQEI8w3v0knWK_4eXMph7L9x07wj9yIYM10,2836
27
+ fleet/__init__.py,sha256=A2DiarJ8g0IABXtnH1AlTrVuSSwHXQSCexUS5i_pyqc,7798
28
+ fleet/base.py,sha256=J3joFnaxzx4Wr5UYHY0ME17ML2jRWU8VeXEniuDogx4,10066
29
+ fleet/cli.py,sha256=arX1E-fjLXtcV3tVVkPHfEXxl7FDn4zRmf0ssXlXaMg,40104
30
+ fleet/client.py,sha256=maxdDJQzs_30O0bbYRBrIXULJwr3TK2WV3ObgeQ1VK4,68855
31
+ fleet/config.py,sha256=n_wh9Sahu3gGE7nHJ7kqNFUH1qDiBtF4bgZq9MvIBMU,319
32
+ fleet/exceptions.py,sha256=YqhQonZlxGdLP1HD0DNdKs9Q9BuyeYvK3pc6Glhpl14,5352
33
+ fleet/global_client.py,sha256=frrDAFNM2ywN0JHLtlm9qbE1dQpnQJsavJpb7xSR_bU,1072
34
+ fleet/models.py,sha256=AwCAoIypInbZoz-SCI1vuPktwB5kO7k3RqNRJGU2RCY,25924
35
+ fleet/tasks.py,sha256=vWiAIvRuo-n32pdH14XYo5NVEc6yeUWkqlnC0nGcIxg,21634
36
+ fleet/types.py,sha256=L4Y82xICf1tzyCLqhLYUgEoaIIS5h9T05TyFNHSWs3s,652
37
+ fleet/_async/__init__.py,sha256=CPMG5GSFyFDN2CL1lZ_RXEoy1nWnkGqOiMhYVxNOnR4,9116
38
+ fleet/_async/base.py,sha256=jtNofzMjT8QVSuDHOGmluYi5pEW4RVwOz7338mPxw0Q,9631
39
+ fleet/_async/client.py,sha256=bXsavcwOa1kyi6AGpioDyGK2Cj4eQ4WWB4YmNNK5EQ0,65278
40
+ fleet/_async/exceptions.py,sha256=fUmPwWhnT8SR97lYsRq0kLHQHKtSh2eJS0VQ2caSzEI,5055
41
+ fleet/_async/global_client.py,sha256=4WskpLHbsDEgWW7hXMD09W-brkp4euy8w2ZJ88594rQ,1103
42
+ fleet/_async/models.py,sha256=sCpTZHEfoOvcKv0gLlXGc92XzbfskHe7CKvzEOhNvns,14176
43
+ fleet/_async/tasks.py,sha256=29ODUC-a5a5yye9B2HrIOpRwKlc2yhF8Du_KE2DSDmY,21603
44
+ fleet/_async/env/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
+ fleet/_async/env/client.py,sha256=FqetvDlABeHLaAc8UF_m_2OFEhXy4ZqH7ly_Nh8p3uA,3479
46
+ fleet/_async/instance/__init__.py,sha256=PtmJq8J8bh0SOQ2V55QURz5GJfobozwtQoqhaOk3_tI,515
47
+ fleet/_async/instance/base.py,sha256=3qUBuUR8OVS36LzdP6KyZzngtwPKYO09HoY6Ekxp-KA,1625
48
+ fleet/_async/instance/client.py,sha256=eV_KxJ-8FX1KQcQd1FIEuPax6atHcTcFbuAf5U_Q4R4,7961
49
+ fleet/_async/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
50
+ fleet/_async/resources/api.py,sha256=qlM1Ab3LNe1r7Hx27es4CRK565ZLVaJQeEtZKCe9cM0,6260
51
+ fleet/_async/resources/base.py,sha256=UfrenxUqcpL8SgYGOo8o8HgRvv2-ZO5G2Cdo91ofEdg,664
52
+ fleet/_async/resources/browser.py,sha256=oldoSiymJ1lJkADhpUG81ViOBDNyppX1jSoEwe9-W94,1369
53
+ fleet/_async/resources/mcp.py,sha256=TLEsLiFhfVfZFs0Fu_uDPm-h4FPdvqgQblYqs-PTHhc,1720
54
+ fleet/_async/resources/sqlite.py,sha256=RiSMkruGpAWzU19fWCczvx76Ht4yevFqdhcaGjTzuSM,106472
55
+ fleet/_async/verifiers/__init__.py,sha256=1WTlCNq4tIFbbXaQu5Bf2WppZq0A8suhtZbxMTSOwxI,465
56
+ fleet/_async/verifiers/bundler.py,sha256=9aWWXFsovBPcndE06IATn5jaeli5fRORAYeenF9heN0,26264
57
+ fleet/_async/verifiers/verifier.py,sha256=iSa-rO-E1R3IQTFS9Z7jbQvQVtsDkilITQP9IIQU2JA,14556
58
+ fleet/agent/__init__.py,sha256=BuiElLoL_OTq_tmEMD85Zc1x3x9iUerYM7TxLpD22aI,737
59
+ fleet/agent/orchestrator.py,sha256=ciZFctuv_MOmn_IoK021YpDsPLvuG40YLywsX-oA2j4,30308
60
+ fleet/agent/types.py,sha256=SjJbMju13EPjTPnH7igv860RhCIIKCIQnGEgc8GnHZM,1476
61
+ fleet/agent/utils.py,sha256=VNhyIFwTKizl00ccqXdhh6s3DYZxPy55PMXgYhTLNX4,1171
62
+ fleet/agent/gemini_cua/Dockerfile,sha256=hYsbLu5vJron9zsYZcFj09JgKrZ-MUXiUShg_TOmWsI,1314
63
+ fleet/agent/gemini_cua/__init__.py,sha256=EqjnPPhWWUI3Gk5FrWKfajVYPn_nlO6tTl_jPdeHSXU,205
64
+ fleet/agent/gemini_cua/agent.py,sha256=OFzivTnUHCKqHqD2iXLADxtgVlJBvMkWrYLBw5EByG8,30191
65
+ fleet/agent/gemini_cua/requirements.txt,sha256=dOM2T5EVihE6FUSQNIMtcegeKtEpir5b3KD2fF28ZF0,82
66
+ fleet/agent/gemini_cua/start.sh,sha256=KIagmkBMKAUvwZA25jOIQXju4L-lSLppfpsQvR8m7zg,888
67
+ fleet/agent/gemini_cua/mcp/main.py,sha256=yXoZoWWvHJPnGAOQz-2zkFqlm1twOXLsUSlEKTT6Su4,3413
68
+ fleet/agent/gemini_cua/mcp_server/__init__.py,sha256=AJSApqzVShZfsLLDCKhCicfys0rvsbXAQMXXH2Z7usc,131
69
+ fleet/agent/gemini_cua/mcp_server/main.py,sha256=wSUdLwdmUtLRGqBzgPQAQu62gGdx9oPDjXywW1DQG8k,3350
70
+ fleet/agent/gemini_cua/mcp_server/tools.py,sha256=wfveimMkU0sTqoquotvSbOdb_yDG7DyVeZHHWk0opGo,6462
71
+ fleet/env/__init__.py,sha256=BVPZ4AYTznL6AYNrVmjr1yLF16qBcT1U56jWwF7AJ5o,964
72
+ fleet/env/client.py,sha256=N9oF2hGSNmfVacTnyQhIEocoN3BA5fMa-arbpVeNi-E,3221
73
+ fleet/eval/__init__.py,sha256=ng9V-KTsdW-bOOyF7UUGvABA9x0npeuYzMdS3MUd4nQ,389
74
+ fleet/eval/uploader.py,sha256=UUuoWJASwEqlP-YkzscX7ssiKRSAEVqC4YcCvSBBrWQ,7210
75
+ fleet/instance/__init__.py,sha256=CyWUkbGAK-DBPw4DC4AnCW-MqqheGhZMA5QSRVu-ws4,479
76
+ fleet/instance/base.py,sha256=OYqzBwZFfTX9wlBGSG5gljqj98NbiJeKIfFJ3uj5I4s,1587
77
+ fleet/instance/client.py,sha256=LB_Tiljah91haV6-WK2Vx0XDOYx94KploOlfQDmkjok,7737
78
+ fleet/instance/models.py,sha256=AZX-8WceLtfBtu6J54_N6vq1XjLQrtI1UbnyfNyIMu4,4199
79
+ fleet/proxy/__init__.py,sha256=XoDk8k2TOTap1IU0ErfP-YUTTi7_u42xEmOzkBHZt8o,551
80
+ fleet/proxy/proxy.py,sha256=VKpTGgJ7iFfUQkfkNw1eVTqmMHhULV70Eb-iB7SpeVY,15972
81
+ fleet/proxy/whitelist.py,sha256=3lKrfwaUgf8GyXalRDpgoB9MORnmEh7Nt4LF-h-M_PY,6721
82
+ fleet/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
83
+ fleet/resources/api.py,sha256=7YQcATXjhNeEbrIDXqSMerGywxefcRz8luqrObfcsl8,6066
84
+ fleet/resources/base.py,sha256=AXZzT0_yWHkT497q3yekfr0xsD4cPGMCC6y7C43TIkk,663
85
+ fleet/resources/browser.py,sha256=hRNM0YMsVQUAraZGNi_B-KXxLpuddy4ntoEDFSw7czU,1295
86
+ fleet/resources/mcp.py,sha256=c6O4vVJnXANuHMGMe4IPxgp4zBEbFaGm6_d9e6j8Myc,1695
87
+ fleet/resources/sqlite.py,sha256=RpfAkMPAiqYQSnpB258lomPfaFtDIVVF_ERS2ycfLtU,107242
88
+ fleet/utils/__init__.py,sha256=cZdaIU4KWr_xQFDpShTC2P_XVLYrlDFSBTQwWzfDQ2o,255
89
+ fleet/utils/http_logging.py,sha256=N1qRwOHA4nTe-3JOy-2J9AK0eneWAfv9s66qnyU_Vnw,6332
90
+ fleet/utils/logging.py,sha256=-F_JbGIAaIt_WqVJC0ch4iog4WWFQDJgUS2vxg3YH0A,319
91
+ fleet/utils/playwright.py,sha256=UZrlJJC5z3deQfvSAo03g-ajNkN52b333gBjqvQ6Qa0,15546
92
+ fleet/verifiers/__init__.py,sha256=GntS8qc3xv8mm-cku1t3xjvOll5jcc5FuiVqQgR4Y6Q,458
93
+ fleet/verifiers/bundler.py,sha256=9aWWXFsovBPcndE06IATn5jaeli5fRORAYeenF9heN0,26264
94
+ fleet/verifiers/code.py,sha256=A1i_UabZspbyj1awzKVQ_HRxgMO3fU7NbkxYyTrp7So,48
95
+ fleet/verifiers/db.py,sha256=CwuEaH1xpLdzhH3OpP0Fb5PAezIp4WhAMX4Kvo1WcCU,73138
96
+ fleet/verifiers/decorator.py,sha256=RuTjjDijbicNfMSjA7HcTpKueEki5dzNOdTuHS7UoZs,3262
97
+ fleet/verifiers/parse.py,sha256=qz9AfJrTbjlg-LU-lE8Ciqi7Yt2a8-cs17FdpjTLhMk,8550
98
+ fleet/verifiers/sql_differ.py,sha256=TqTLWyK3uOyLbitT6HYzYEzuSFC39wcyhgk3rcm__k8,6525
99
+ fleet/verifiers/verifier.py,sha256=iqGevW7dSd0J5RdRQjpu-zioy_FYAXnzMfkuB3-QmO0,14601
100
+ fleet_python-0.2.105.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
101
+ scripts/fix_sync_imports.py,sha256=X9fWLTpiPGkSHsjyQUDepOJkxOqw1DPj7nd8wFlFqLQ,8368
102
+ scripts/unasync.py,sha256=vWVQxRWX8SRZO5cmzEhpvnG_REhCWXpidIGIpWmEcvI,696
103
+ tests/__init__.py,sha256=Re1SdyxH8NfyL1kjhi7SQkGP1mYeWB-D6UALqdIMd8I,35
104
+ tests/test_app_method.py,sha256=kg2IiL75cH-HmsTMS3_wDL39dAesgfv_AT6jVthd5J4,3159
105
+ tests/test_expect_exactly.py,sha256=BFw7a7REl0L_B6gGCIeOPb6seot-WIFu9kHdBjCNbgk,149614
106
+ tests/test_expect_only.py,sha256=uVAwbZYk05nqoQmrTc2FFJ9MLAGXweuVGfM_wT6rk-s,89536
107
+ tests/test_instance_dispatch.py,sha256=CvU4C3LBIqsYZdEsEFfontGjyxAZfVYyXnGwxyIvXOc,23065
108
+ tests/test_sqlite_resource_dual_mode.py,sha256=Mh8jBd-xsIGDYFsOACKKK_5DXMUYlFFS7W-jaY6AjG4,8734
109
+ tests/test_sqlite_shared_memory_behavior.py,sha256=fKx_1BmLS3b8x-9pMgjMycpnaHWY8P-2ZuXEspx6Sbw,4082
110
+ tests/test_verifier_from_string.py,sha256=Lxi3TpFHFb-hG4-UhLKZJkqo84ax9YJY8G6beO-1erM,13581
111
+ fleet_python-0.2.105.dist-info/METADATA,sha256=NwO9s7UsvR__0HlJ4HrVmePEKQk8ovLDR_64Se4cfGI,4240
112
+ fleet_python-0.2.105.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
113
+ fleet_python-0.2.105.dist-info/entry_points.txt,sha256=qKIQ326cHR5WyCd16QnrW-1DpcT0YyxVRDb3IlTyzTA,39
114
+ fleet_python-0.2.105.dist-info/top_level.txt,sha256=qb1zIbtEktyhRFZdqVytwg54l64qtoZL0wjHB4bUg3c,29
115
+ fleet_python-0.2.105.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ flt = fleet.cli:main
@@ -0,0 +1,85 @@
1
+ """Unit tests for SyncEnv.app() method URL handling."""
2
+
3
+ import pytest
4
+ from unittest.mock import Mock, patch
5
+ from fleet.client import Fleet
6
+
7
+
8
+ class TestAppMethod:
9
+ """Test SyncEnv.app() method with different URL formats."""
10
+
11
+ @pytest.fixture
12
+ def fleet_client(self):
13
+ """Create a Fleet client with mocked HTTP client."""
14
+ with patch("fleet.client.default_httpx_client") as mock_client:
15
+ mock_client.return_value = Mock()
16
+ client = Fleet(api_key="test_key")
17
+ client.client.request = Mock()
18
+ return client
19
+
20
+ def test_app_with_existing_app_path(self, fleet_client):
21
+ """Test app() with URL that already has an app path like /sentry."""
22
+ # Create instance with a URL that has an existing app path
23
+ env = fleet_client.instance("https://example.com/sentry/api/v1/env")
24
+
25
+ # Access jira app
26
+ jira_client = env.app("jira")
27
+
28
+ # Check the constructed URL
29
+ assert jira_client.base_url == "https://example.com/jira/api/v1/env", \
30
+ f"Expected https://example.com/jira/api/v1/env, got {jira_client.base_url}"
31
+
32
+ def test_app_without_app_path(self, fleet_client):
33
+ """Test app() with URL that has no app path (just /api/v1/env)."""
34
+ # Create instance with a URL without an app path
35
+ env = fleet_client.instance("https://example.com/api/v1/env")
36
+
37
+ # Access jira app
38
+ jira_client = env.app("jira")
39
+
40
+ # Check the constructed URL
41
+ assert jira_client.base_url == "https://example.com/jira/api/v1/env", \
42
+ f"Expected https://example.com/jira/api/v1/env, got {jira_client.base_url}"
43
+
44
+ def test_app_with_different_app_names(self, fleet_client):
45
+ """Test app() with multiple different app names."""
46
+ env = fleet_client.instance("https://example.com/api/v1/env")
47
+
48
+ jira = env.app("jira")
49
+ sentry = env.app("sentry")
50
+ github = env.app("github")
51
+
52
+ assert jira.base_url == "https://example.com/jira/api/v1/env"
53
+ assert sentry.base_url == "https://example.com/sentry/api/v1/env"
54
+ assert github.base_url == "https://example.com/github/api/v1/env"
55
+
56
+ def test_app_caching(self, fleet_client):
57
+ """Test that app() caches InstanceClient instances."""
58
+ env = fleet_client.instance("https://example.com/api/v1/env")
59
+
60
+ # Call app("jira") twice
61
+ jira1 = env.app("jira")
62
+ jira2 = env.app("jira")
63
+
64
+ # Should return the same cached instance
65
+ assert jira1 is jira2
66
+
67
+ def test_app_with_localhost(self, fleet_client):
68
+ """Test app() with localhost URLs."""
69
+ env = fleet_client.instance("http://localhost:8080/api/v1/env")
70
+
71
+ jira = env.app("jira")
72
+
73
+ assert jira.base_url == "http://localhost:8080/jira/api/v1/env"
74
+
75
+ def test_app_with_port(self, fleet_client):
76
+ """Test app() with URLs that include port numbers."""
77
+ env = fleet_client.instance("https://example.com:9000/api/v1/env")
78
+
79
+ jira = env.app("jira")
80
+
81
+ assert jira.base_url == "https://example.com:9000/jira/api/v1/env"
82
+
83
+
84
+ if __name__ == "__main__":
85
+ pytest.main([__file__, "-v"])