fleet-python 0.2.66b2__tar.gz → 0.2.66b3__tar.gz
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.
- {fleet_python-0.2.66b2/fleet_python.egg-info → fleet_python-0.2.66b3}/PKG-INFO +1 -1
- fleet_python-0.2.66b3/fleet/verifiers/parsing.py +106 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3/fleet_python.egg-info}/PKG-INFO +1 -1
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet_python.egg-info/SOURCES.txt +1 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/pyproject.toml +1 -1
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/LICENSE +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/README.md +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/examples/diff_example.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/examples/dsl_example.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/examples/example.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/examples/exampleResume.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/examples/example_account.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/examples/example_action_log.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/examples/example_client.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/examples/example_mcp_anthropic.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/examples/example_mcp_openai.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/examples/example_sync.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/examples/example_task.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/examples/example_tasks.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/examples/example_verifier.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/examples/export_tasks.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/examples/gemini_example.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/examples/import_tasks.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/examples/json_tasks_example.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/examples/nova_act_example.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/examples/openai_example.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/examples/openai_simple_example.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/examples/query_builder_example.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/examples/quickstart.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/examples/test_cdp_logging.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/__init__.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/_async/__init__.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/_async/base.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/_async/client.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/_async/env/__init__.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/_async/env/client.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/_async/exceptions.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/_async/global_client.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/_async/instance/__init__.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/_async/instance/base.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/_async/instance/client.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/_async/models.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/_async/resources/__init__.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/_async/resources/base.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/_async/resources/browser.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/_async/resources/mcp.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/_async/resources/sqlite.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/_async/tasks.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/_async/verifiers/__init__.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/_async/verifiers/bundler.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/_async/verifiers/verifier.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/base.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/client.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/config.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/env/__init__.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/env/client.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/exceptions.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/global_client.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/instance/__init__.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/instance/base.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/instance/client.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/instance/models.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/models.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/resources/__init__.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/resources/base.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/resources/browser.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/resources/mcp.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/resources/sqlite.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/tasks.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/types.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/verifiers/__init__.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/verifiers/bundler.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/verifiers/code.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/verifiers/db.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/verifiers/decorator.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/verifiers/parse.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/verifiers/sql_differ.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet/verifiers/verifier.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet_python.egg-info/dependency_links.txt +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet_python.egg-info/requires.txt +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/fleet_python.egg-info/top_level.txt +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/scripts/fix_sync_imports.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/scripts/unasync.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/setup.cfg +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/tests/__init__.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/tests/test_verifier_from_string.py +0 -0
- {fleet_python-0.2.66b2 → fleet_python-0.2.66b3}/tests/test_verifier_security.py +0 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"""Verifier code parsing and validation utilities."""
|
|
2
|
+
|
|
3
|
+
import ast
|
|
4
|
+
from typing import Set
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def parse_and_validate_verifier(code: str) -> str:
|
|
8
|
+
"""Parse and validate verifier code, returning the first function name.
|
|
9
|
+
|
|
10
|
+
This function ensures that the verifier code only contains safe declarative
|
|
11
|
+
statements and does not execute arbitrary code during import.
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
code: Python code string containing the verifier function
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
Name of the first function found in the code
|
|
18
|
+
|
|
19
|
+
Raises:
|
|
20
|
+
ValueError: If code is invalid or contains unsafe statements
|
|
21
|
+
SyntaxError: If code has syntax errors
|
|
22
|
+
"""
|
|
23
|
+
try:
|
|
24
|
+
tree = ast.parse(code)
|
|
25
|
+
except SyntaxError as e:
|
|
26
|
+
raise SyntaxError(f"Syntax error in verifier code: {e}")
|
|
27
|
+
|
|
28
|
+
first_function_name = None
|
|
29
|
+
|
|
30
|
+
for node in tree.body:
|
|
31
|
+
# Check for function definitions
|
|
32
|
+
if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
|
|
33
|
+
# Validate that decorators don't contain function calls
|
|
34
|
+
for decorator in node.decorator_list:
|
|
35
|
+
if _contains_call(decorator):
|
|
36
|
+
raise ValueError(
|
|
37
|
+
f"Line {node.lineno}: Function decorators with function calls "
|
|
38
|
+
f"are not allowed. Decorators execute during import and could "
|
|
39
|
+
f"run arbitrary code."
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
if first_function_name is None:
|
|
43
|
+
first_function_name = node.name
|
|
44
|
+
continue
|
|
45
|
+
|
|
46
|
+
# Allow imports
|
|
47
|
+
if isinstance(node, (ast.Import, ast.ImportFrom)):
|
|
48
|
+
continue
|
|
49
|
+
|
|
50
|
+
# Allow class definitions
|
|
51
|
+
if isinstance(node, ast.ClassDef):
|
|
52
|
+
continue
|
|
53
|
+
|
|
54
|
+
# Allow docstrings and other expression statements (but not calls)
|
|
55
|
+
if isinstance(node, ast.Expr):
|
|
56
|
+
if isinstance(node.value, ast.Constant):
|
|
57
|
+
# Docstring or constant expression - safe
|
|
58
|
+
continue
|
|
59
|
+
else:
|
|
60
|
+
# Check if it's a call or other dangerous expression
|
|
61
|
+
raise ValueError(
|
|
62
|
+
f"Line {node.lineno}: Expression statements that are not "
|
|
63
|
+
f"constants are not allowed at module level. Found: {ast.dump(node.value)}"
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
# Allow variable assignments, but check the value
|
|
67
|
+
if isinstance(node, (ast.Assign, ast.AnnAssign)):
|
|
68
|
+
# Check if the assignment value contains any function calls
|
|
69
|
+
if _contains_call(node.value if isinstance(node, ast.AnnAssign) else node.value):
|
|
70
|
+
raise ValueError(
|
|
71
|
+
f"Line {node.lineno}: Variable assignments with function calls "
|
|
72
|
+
f"are not allowed at module level. This prevents arbitrary code "
|
|
73
|
+
f"execution during import."
|
|
74
|
+
)
|
|
75
|
+
continue
|
|
76
|
+
|
|
77
|
+
# If we get here, it's an unsupported statement type
|
|
78
|
+
raise ValueError(
|
|
79
|
+
f"Line {node.lineno}: Unsupported statement type at module level: "
|
|
80
|
+
f"{node.__class__.__name__}. Only imports, function/class definitions, "
|
|
81
|
+
f"and constant assignments are allowed."
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
if first_function_name is None:
|
|
85
|
+
raise ValueError("No function found in verifier code")
|
|
86
|
+
|
|
87
|
+
return first_function_name
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def _contains_call(node: ast.AST) -> bool:
|
|
91
|
+
"""Recursively check if an AST node contains any Call nodes.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
node: AST node to check
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
True if the node or any of its children is a Call node
|
|
98
|
+
"""
|
|
99
|
+
if isinstance(node, ast.Call):
|
|
100
|
+
return True
|
|
101
|
+
|
|
102
|
+
for child in ast.walk(node):
|
|
103
|
+
if isinstance(child, ast.Call):
|
|
104
|
+
return True
|
|
105
|
+
|
|
106
|
+
return False
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|