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

@@ -0,0 +1,16 @@
1
+ import asyncio
2
+ import fleet
3
+ from dotenv import load_dotenv
4
+
5
+ load_dotenv()
6
+
7
+
8
+ async def main():
9
+ print(f"Importing tasks... {(await fleet.env.account_async()).team_name}")
10
+ await fleet._async.import_tasks(
11
+ "6bb6c6b6-36a8-4407-ba66-6908e42069c8.json", project_key="amazon"
12
+ )
13
+
14
+
15
+ if __name__ == "__main__":
16
+ asyncio.run(main())
fleet/__init__.py CHANGED
@@ -51,10 +51,17 @@ from ._async.tasks import (
51
51
  Task,
52
52
  load_tasks as load_tasks_async,
53
53
  load_tasks_from_file as load_tasks_from_file_async,
54
+ import_task as import_task_async,
55
+ import_tasks as import_tasks_async,
54
56
  )
55
57
 
56
- # Import sync load_tasks function
57
- from .tasks import load_tasks, load_tasks_from_file
58
+ # Import sync task functions
59
+ from .tasks import (
60
+ load_tasks,
61
+ load_tasks_from_file,
62
+ import_task,
63
+ import_tasks,
64
+ )
58
65
 
59
66
  # Import shared types
60
67
  from .types import VerifierFunction
@@ -104,6 +111,12 @@ __all__ = [
104
111
  # Module-level functions (async is default)
105
112
  "load_tasks",
106
113
  "load_tasks_async",
114
+ "load_tasks_from_file",
115
+ "load_tasks_from_file_async",
116
+ "import_task",
117
+ "import_task_async",
118
+ "import_tasks",
119
+ "import_tasks_async",
107
120
  # Version
108
121
  "__version__",
109
122
  ]
fleet/_async/__init__.py CHANGED
@@ -86,6 +86,7 @@ __all__ = [
86
86
  "load_task_from_string",
87
87
  "load_task_from_json",
88
88
  "export_tasks",
89
+ "import_task",
89
90
  "import_tasks",
90
91
  "account",
91
92
  # Version
@@ -193,6 +194,21 @@ async def export_tasks(
193
194
  return await _async_global_client.get_client().export_tasks(env_key, filename)
194
195
 
195
196
 
197
+ async def import_task(task, project_key: Optional[str] = None):
198
+ """Import a single task.
199
+
200
+ Args:
201
+ task: Task object to import
202
+ project_key: Optional project key to associate with the task
203
+
204
+ Example:
205
+ task = fleet.Task(key="my-task", prompt="Do something", env_id="my-env")
206
+ await fleet.import_task(task)
207
+ await fleet.import_task(task, project_key="my-project")
208
+ """
209
+ return await _async_global_client.get_client().import_single_task(task, project_key)
210
+
211
+
196
212
  async def import_tasks(filename: str, project_key: Optional[str] = None):
197
213
  """Import tasks from a JSON file.
198
214
 
fleet/_async/client.py CHANGED
@@ -328,7 +328,9 @@ class AsyncFleet:
328
328
  task_json = json.loads(task_string)
329
329
  return await self.load_task_from_json(task_json)
330
330
 
331
- async def load_task_from_json(self, task_json: Dict) -> Task:
331
+ async def load_task_from_json(
332
+ self, task_json: Dict, raise_on_verifier_error: bool = False
333
+ ) -> Task:
332
334
  verifier = None
333
335
  verifier_code = task_json.get("verifier_func") or task_json.get("verifier_code")
334
336
 
@@ -356,9 +358,11 @@ class AsyncFleet:
356
358
  verifier_sha=task_json.get("verifier_sha", ""),
357
359
  )
358
360
  except Exception as e:
359
- logger.warning(
360
- f"Failed to create verifier {task_json.get('key', task_json.get('id'))}: {e}"
361
- )
361
+ error_msg = f"Failed to create verifier {task_json.get('key', task_json.get('id'))}: {e}"
362
+ if raise_on_verifier_error:
363
+ raise ValueError(error_msg) from e
364
+ else:
365
+ logger.warning(error_msg)
362
366
 
363
367
  task = Task(
364
368
  key=task_json.get("key", task_json.get("id")),
@@ -571,6 +575,13 @@ class AsyncFleet:
571
575
  Response from the API, or None if the import failed
572
576
  """
573
577
  try:
578
+ # Validate that verifier_func exists
579
+ if not task.verifier_func:
580
+ raise ValueError(
581
+ f"Task {task.key} is missing verifier_func. "
582
+ "All tasks must have a verifier_func to be imported."
583
+ )
584
+
574
585
  params = {}
575
586
  if project_key:
576
587
  params["project_key"] = project_key
@@ -591,14 +602,33 @@ class AsyncFleet:
591
602
 
592
603
  Returns:
593
604
  List[Task] containing imported Task objects
605
+
606
+ Raises:
607
+ ValueError: If any task is missing verifier_func or has invalid verifier code
594
608
  """
595
609
  with open(filename, "r", encoding="utf-8") as f:
596
610
  tasks_data = json.load(f)
597
611
 
598
- # Create tasks from the loaded data
612
+ # Create tasks from the loaded data using load_task_from_json
613
+ # This will validate and create verifiers properly
599
614
  tasks = []
600
615
  for task_data in tasks_data:
601
- task = Task(**task_data)
616
+ # Validate that verifier_func exists
617
+ verifier_code = task_data.get("verifier_func") or task_data.get(
618
+ "verifier_code"
619
+ )
620
+ if not verifier_code:
621
+ task_key = task_data.get("key", task_data.get("id", "unknown"))
622
+ raise ValueError(
623
+ f"Task {task_key} is missing verifier_func. "
624
+ "All tasks must have a verifier_func to be imported."
625
+ )
626
+
627
+ # Use load_task_from_json to properly create and validate the task
628
+ # Pass raise_on_verifier_error=True to fail fast on invalid verifier code
629
+ task = await self.load_task_from_json(
630
+ task_data, raise_on_verifier_error=True
631
+ )
602
632
  tasks.append(task)
603
633
 
604
634
  # Use semaphore to limit concurrency to 20
fleet/_async/tasks.py CHANGED
@@ -332,3 +332,44 @@ async def update_task(
332
332
  return await client.update_task(
333
333
  task_key=task_key, prompt=prompt, verifier_code=verifier_code
334
334
  )
335
+
336
+
337
+ async def import_task(task: Task, project_key: Optional[str] = None):
338
+ """Convenience function to import a single task.
339
+
340
+ Args:
341
+ task: Task object to import
342
+ project_key: Optional project key to associate with the task
343
+
344
+ Returns:
345
+ Response from the API, or None if the import failed
346
+
347
+ Examples:
348
+ task = fleet.Task(key="my-task", prompt="Do something", env_id="my-env")
349
+ response = await fleet.import_task(task)
350
+ response = await fleet.import_task(task, project_key="my-project")
351
+ """
352
+ from .global_client import get_client
353
+
354
+ client = get_client()
355
+ return await client.import_single_task(task, project_key=project_key)
356
+
357
+
358
+ async def import_tasks(filename: str, project_key: Optional[str] = None):
359
+ """Convenience function to import tasks from a JSON file.
360
+
361
+ Args:
362
+ filename: Path to the JSON file of Task objects to import
363
+ project_key: Optional project key to associate with the tasks
364
+
365
+ Returns:
366
+ List of responses from the API for successfully imported tasks
367
+
368
+ Examples:
369
+ responses = await fleet.import_tasks("tasks.json")
370
+ responses = await fleet.import_tasks("tasks.json", project_key="my-project")
371
+ """
372
+ from .global_client import get_client
373
+
374
+ client = get_client()
375
+ return await client.import_tasks(filename, project_key=project_key)
fleet/client.py CHANGED
@@ -326,7 +326,9 @@ class Fleet:
326
326
  task_json = json.loads(task_string)
327
327
  return self.load_task_from_json(task_json)
328
328
 
329
- def load_task_from_json(self, task_json: Dict) -> Task:
329
+ def load_task_from_json(
330
+ self, task_json: Dict, raise_on_verifier_error: bool = False
331
+ ) -> Task:
330
332
  verifier = None
331
333
  verifier_code = task_json.get("verifier_func") or task_json.get("verifier_code")
332
334
 
@@ -354,9 +356,11 @@ class Fleet:
354
356
  verifier_sha=task_json.get("verifier_sha", ""),
355
357
  )
356
358
  except Exception as e:
357
- logger.warning(
358
- f"Failed to create verifier {task_json.get('key', task_json.get('id'))}: {e}"
359
- )
359
+ error_msg = f"Failed to create verifier {task_json.get('key', task_json.get('id'))}: {e}"
360
+ if raise_on_verifier_error:
361
+ raise ValueError(error_msg) from e
362
+ else:
363
+ logger.warning(error_msg)
360
364
 
361
365
  task = Task(
362
366
  key=task_json.get("key", task_json.get("id")),
@@ -577,10 +581,19 @@ class Fleet:
577
581
  Response from the API, or None if the import failed
578
582
  """
579
583
  try:
584
+ # Validate that verifier_func exists
585
+ if not task.verifier_func:
586
+ raise ValueError(
587
+ f"Task {task.key} is missing verifier_func. "
588
+ "All tasks must have a verifier_func to be imported."
589
+ )
590
+
580
591
  params = {}
581
592
  if project_key:
582
593
  params["project_key"] = project_key
583
- response = self.client.request("POST", "/v1/tasks", json=task.model_dump(), params=params)
594
+ response = self.client.request(
595
+ "POST", "/v1/tasks", json=task.model_dump(), params=params
596
+ )
584
597
  return response
585
598
  except Exception as e:
586
599
  logger.error(f"Failed to import task {task.key}: {e}")
@@ -595,19 +608,38 @@ class Fleet:
595
608
 
596
609
  Returns:
597
610
  List[Task] containing imported Task objects
611
+
612
+ Raises:
613
+ ValueError: If any task is missing verifier_func or has invalid verifier code
598
614
  """
599
615
  with open(filename, "r", encoding="utf-8") as f:
600
616
  tasks_data = json.load(f)
601
617
 
602
- # Create tasks from the loaded data
618
+ # Create tasks from the loaded data using load_task_from_json
619
+ # This will validate and create verifiers properly
603
620
  tasks = []
604
621
  for task_data in tasks_data:
605
- task = Task(**task_data)
622
+ # Validate that verifier_func exists
623
+ verifier_code = task_data.get("verifier_func") or task_data.get(
624
+ "verifier_code"
625
+ )
626
+ if not verifier_code:
627
+ task_key = task_data.get("key", task_data.get("id", "unknown"))
628
+ raise ValueError(
629
+ f"Task {task_key} is missing verifier_func. "
630
+ "All tasks must have a verifier_func to be imported."
631
+ )
632
+
633
+ # Use load_task_from_json to properly create and validate the task
634
+ # Pass raise_on_verifier_error=True to fail fast on invalid verifier code
635
+ task = self.load_task_from_json(task_data, raise_on_verifier_error=True)
606
636
  tasks.append(task)
607
637
 
608
638
  # Use ThreadPoolExecutor to parallelize the imports with max 20 workers
609
639
  with concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor:
610
- responses = list(executor.map(lambda t: self.import_single_task(t, project_key), tasks))
640
+ responses = list(
641
+ executor.map(lambda t: self.import_single_task(t, project_key), tasks)
642
+ )
611
643
 
612
644
  # Filter out None values (failed imports)
613
645
  return [r for r in responses if r is not None]
fleet/tasks.py CHANGED
@@ -335,3 +335,44 @@ def update_task(
335
335
  return client.update_task(
336
336
  task_key=task_key, prompt=prompt, verifier_code=verifier_code
337
337
  )
338
+
339
+
340
+ def import_task(task: Task, project_key: Optional[str] = None):
341
+ """Convenience function to import a single task.
342
+
343
+ Args:
344
+ task: Task object to import
345
+ project_key: Optional project key to associate with the task
346
+
347
+ Returns:
348
+ Response from the API, or None if the import failed
349
+
350
+ Examples:
351
+ task = fleet.Task(key="my-task", prompt="Do something", env_id="my-env")
352
+ response = fleet.import_task(task)
353
+ response = fleet.import_task(task, project_key="my-project")
354
+ """
355
+ from .global_client import get_client
356
+
357
+ client = get_client()
358
+ return client.import_single_task(task, project_key=project_key)
359
+
360
+
361
+ def import_tasks(filename: str, project_key: Optional[str] = None):
362
+ """Convenience function to import tasks from a JSON file.
363
+
364
+ Args:
365
+ filename: Path to the JSON file of Task objects to import
366
+ project_key: Optional project key to associate with the tasks
367
+
368
+ Returns:
369
+ List of responses from the API for successfully imported tasks
370
+
371
+ Examples:
372
+ responses = fleet.import_tasks("tasks.json")
373
+ responses = fleet.import_tasks("tasks.json", project_key="my-project")
374
+ """
375
+ from .global_client import get_client
376
+
377
+ client = get_client()
378
+ return client.import_tasks(filename, project_key=project_key)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fleet-python
3
- Version: 0.2.53
3
+ Version: 0.2.54
4
4
  Summary: Python SDK for Fleet environments
5
5
  Author-email: Fleet AI <nic@fleet.so>
6
6
  License: Apache-2.0
@@ -12,6 +12,7 @@ examples/example_task.py,sha256=dhG6STAkNsTdHs9cO1RFH9WfuvRmq5bRC211hTeFrk8,7088
12
12
  examples/example_tasks.py,sha256=xTL8UWVAuolSX6swskfrAcmDrLIzn45dJ7YPWCwoEBU,514
13
13
  examples/example_verifier.py,sha256=0vwNITIG3m4CkSPwIxNXcGx9TqrxEsCGqK2A8keKZMM,2392
14
14
  examples/gemini_example.py,sha256=qj9WDazQTYNiRHNeUg9Tjkp33lJMwbx8gDfpFe1sDQo,16180
15
+ examples/import_tasks.py,sha256=InZdnnL8KfTy8JkuZPlsgFvdU7h2LrdpQNa2XA9VR88,343
15
16
  examples/json_tasks_example.py,sha256=CYPESGGtOo0fmsDdLidujTfsE4QlJHw7rOhyVqPJ_Ls,5329
16
17
  examples/nova_act_example.py,sha256=rH23Lp74Okf0rn8ynMdWjK2aviEf5NLPH4k_53Pyxho,831
17
18
  examples/openai_example.py,sha256=dEWERrTEP5xBiGkLkQjBQGd2NqoxX6gcW6XteBPsWFQ,8231
@@ -19,22 +20,22 @@ examples/openai_simple_example.py,sha256=HmiufucrAZne7tHq9uoEsDWlEhjNC265bQAyIGB
19
20
  examples/query_builder_example.py,sha256=-cOMfWGNifYfYEt_Ds73XpwATZvFDL6F4KTkVxdMjzg,3951
20
21
  examples/quickstart.py,sha256=1VT39IRRhemsJgxi0O0gprdpcw7HB4pYO97GAYagIcg,3788
21
22
  examples/test_cdp_logging.py,sha256=AkCwQCgOTQEI8w3v0knWK_4eXMph7L9x07wj9yIYM10,2836
22
- fleet/__init__.py,sha256=Mkdeh45N47lnSv73Eehj92cGU-AImUitvDWJLFhEp0Y,3844
23
+ fleet/__init__.py,sha256=fwIcuaJPPdLMdKPsazfz4EAPeJchl9MBN4nxs0YlOjw,4117
23
24
  fleet/base.py,sha256=bc-340sTpq_DJs7yQ9d2pDWnmJFmA1SwDB9Lagvqtb4,9182
24
- fleet/client.py,sha256=zu05ApXhJrKX7UiMF8TOY1yNWiHRGlYRAMBmhaCsOSo,27806
25
+ fleet/client.py,sha256=qG2nowkeDqitqDhAbYwoGtnXkau3nTwmkUGzN0iPgOk,29201
25
26
  fleet/config.py,sha256=uY02ZKxVoXqVDta-0IMWaYJeE1CTXF_fA9NI6QUutmU,319
26
27
  fleet/exceptions.py,sha256=fUmPwWhnT8SR97lYsRq0kLHQHKtSh2eJS0VQ2caSzEI,5055
27
28
  fleet/global_client.py,sha256=frrDAFNM2ywN0JHLtlm9qbE1dQpnQJsavJpb7xSR_bU,1072
28
29
  fleet/models.py,sha256=d9eish0KO3t4VCNu8h8Q_6K1Xj-crYo5Fejtle0Ur28,13056
29
- fleet/tasks.py,sha256=uR94wq7SG4ymJYLq24F2iYn0el58C2Czb2oK-8rIs8s,12344
30
+ fleet/tasks.py,sha256=uzGKwbLDKlNpuPjUTeF7N2FG_tez3JwiyHYLYt5rBSI,13660
30
31
  fleet/types.py,sha256=L4Y82xICf1tzyCLqhLYUgEoaIIS5h9T05TyFNHSWs3s,652
31
- fleet/_async/__init__.py,sha256=x2esWn8yf2AMfzHRmSHtFkXcxbrSSXCZdJyrFnJldEo,7033
32
+ fleet/_async/__init__.py,sha256=ruGtdMl9BRQRsJygNszPT89ZbMy6AYv1mmeYoB--r60,7557
32
33
  fleet/_async/base.py,sha256=oisVTQsx0M_yTmyQJc3oij63uKZ97MHz-xYFsWXxQE8,9202
33
- fleet/_async/client.py,sha256=TZJsEg43IiYPnSA3S48GRpwAYg1fehcHVbYHA3yUHXY,28266
34
+ fleet/_async/client.py,sha256=SbateFBfFDRju-gHtFr8TQdR0thBNA0rWt0RuUse9s0,29637
34
35
  fleet/_async/exceptions.py,sha256=fUmPwWhnT8SR97lYsRq0kLHQHKtSh2eJS0VQ2caSzEI,5055
35
36
  fleet/_async/global_client.py,sha256=4WskpLHbsDEgWW7hXMD09W-brkp4euy8w2ZJ88594rQ,1103
36
37
  fleet/_async/models.py,sha256=GX-sRciZDenW2O7Qx9w_ftOkJyE4ph1-92WMq6lynHE,12856
37
- fleet/_async/tasks.py,sha256=hrtvKlqepQOFnlJv6h5S06UWNWtn2hQlgSp3eYj5m30,12226
38
+ fleet/_async/tasks.py,sha256=t51pK4gBZZOmtJs35wjEorxKIgDeIvPxwCtGRs00Tpg,13590
38
39
  fleet/_async/env/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
39
40
  fleet/_async/env/client.py,sha256=C5WG5Ir_McXaFPZNdkQjj0w4V7xMIcw3QyVP5g-3kVk,1237
40
41
  fleet/_async/instance/__init__.py,sha256=PtmJq8J8bh0SOQ2V55QURz5GJfobozwtQoqhaOk3_tI,515
@@ -67,10 +68,10 @@ fleet/verifiers/decorator.py,sha256=nAP3O8szXu7md_kpwpz91hGSUNEVLYjwZQZTkQlV1DM,
67
68
  fleet/verifiers/parse.py,sha256=qz9AfJrTbjlg-LU-lE8Ciqi7Yt2a8-cs17FdpjTLhMk,8550
68
69
  fleet/verifiers/sql_differ.py,sha256=TqTLWyK3uOyLbitT6HYzYEzuSFC39wcyhgk3rcm__k8,6525
69
70
  fleet/verifiers/verifier.py,sha256=_lcxXVm8e0xRrK2gNJy9up7pW1zOkPRY5n5lQ85S8jg,14197
70
- fleet_python-0.2.53.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
71
+ fleet_python-0.2.54.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
71
72
  scripts/fix_sync_imports.py,sha256=X9fWLTpiPGkSHsjyQUDepOJkxOqw1DPj7nd8wFlFqLQ,8368
72
73
  scripts/unasync.py,sha256=vWVQxRWX8SRZO5cmzEhpvnG_REhCWXpidIGIpWmEcvI,696
73
- fleet_python-0.2.53.dist-info/METADATA,sha256=SaC_PN_pQ1GG1g3RdaitFUy0PJWpD-1-hCIOT4sqcn8,3304
74
- fleet_python-0.2.53.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
75
- fleet_python-0.2.53.dist-info/top_level.txt,sha256=_3DSmTohvSDf3AIP_BYfGzhwO1ECFwuzg83X-wHCx3Y,23
76
- fleet_python-0.2.53.dist-info/RECORD,,
74
+ fleet_python-0.2.54.dist-info/METADATA,sha256=tkesOoS66aveH_fYtJvJoYi2ErjrkiApcXbx1bUh1Eo,3304
75
+ fleet_python-0.2.54.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
76
+ fleet_python-0.2.54.dist-info/top_level.txt,sha256=_3DSmTohvSDf3AIP_BYfGzhwO1ECFwuzg83X-wHCx3Y,23
77
+ fleet_python-0.2.54.dist-info/RECORD,,