pygeai 0.6.0b7__py3-none-any.whl → 0.6.0b10__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.
- pygeai/_docs/source/conf.py +78 -6
- pygeai/_docs/source/content/api_reference/embeddings.rst +31 -1
- pygeai/_docs/source/content/api_reference/evaluation.rst +590 -0
- pygeai/_docs/source/content/api_reference/feedback.rst +237 -0
- pygeai/_docs/source/content/api_reference/files.rst +592 -0
- pygeai/_docs/source/content/api_reference/gam.rst +401 -0
- pygeai/_docs/source/content/api_reference/proxy.rst +318 -0
- pygeai/_docs/source/content/api_reference/secrets.rst +495 -0
- pygeai/_docs/source/content/api_reference/usage_limits.rst +390 -0
- pygeai/_docs/source/content/api_reference.rst +7 -0
- pygeai/_docs/source/content/debugger.rst +376 -83
- pygeai/_docs/source/content/migration.rst +528 -0
- pygeai/_docs/source/content/modules.rst +1 -1
- pygeai/_docs/source/pygeai.cli.rst +8 -0
- pygeai/_docs/source/pygeai.tests.cli.rst +16 -0
- pygeai/_docs/source/pygeai.tests.core.embeddings.rst +16 -0
- pygeai/_docs/source/pygeai.tests.snippets.chat.rst +40 -0
- pygeai/_docs/source/pygeai.tests.snippets.dbg.rst +45 -0
- pygeai/_docs/source/pygeai.tests.snippets.embeddings.rst +40 -0
- pygeai/_docs/source/pygeai.tests.snippets.evaluation.dataset.rst +197 -0
- pygeai/_docs/source/pygeai.tests.snippets.evaluation.plan.rst +133 -0
- pygeai/_docs/source/pygeai.tests.snippets.evaluation.result.rst +37 -0
- pygeai/_docs/source/pygeai.tests.snippets.evaluation.rst +10 -0
- pygeai/_docs/source/pygeai.tests.snippets.rst +1 -0
- pygeai/admin/clients.py +5 -0
- pygeai/assistant/clients.py +7 -0
- pygeai/assistant/data_analyst/clients.py +2 -0
- pygeai/assistant/rag/clients.py +11 -0
- pygeai/chat/clients.py +191 -25
- pygeai/chat/endpoints.py +2 -1
- pygeai/cli/commands/chat.py +227 -1
- pygeai/cli/commands/embeddings.py +56 -8
- pygeai/cli/commands/migrate.py +994 -434
- pygeai/cli/error_handler.py +116 -0
- pygeai/cli/geai.py +28 -10
- pygeai/cli/parsers.py +8 -2
- pygeai/core/base/clients.py +3 -1
- pygeai/core/common/exceptions.py +11 -10
- pygeai/core/embeddings/__init__.py +19 -0
- pygeai/core/embeddings/clients.py +17 -2
- pygeai/core/embeddings/mappers.py +16 -2
- pygeai/core/embeddings/responses.py +9 -2
- pygeai/core/feedback/clients.py +1 -0
- pygeai/core/files/clients.py +5 -7
- pygeai/core/files/managers.py +42 -0
- pygeai/core/llm/clients.py +4 -0
- pygeai/core/plugins/clients.py +1 -0
- pygeai/core/rerank/clients.py +1 -0
- pygeai/core/secrets/clients.py +6 -0
- pygeai/core/services/rest.py +1 -1
- pygeai/dbg/__init__.py +3 -0
- pygeai/dbg/debugger.py +565 -70
- pygeai/evaluation/clients.py +1 -1
- pygeai/evaluation/dataset/clients.py +45 -44
- pygeai/evaluation/plan/clients.py +27 -26
- pygeai/evaluation/result/clients.py +37 -5
- pygeai/gam/clients.py +4 -0
- pygeai/health/clients.py +1 -0
- pygeai/lab/agents/clients.py +8 -1
- pygeai/lab/models.py +3 -3
- pygeai/lab/processes/clients.py +21 -0
- pygeai/lab/strategies/clients.py +4 -0
- pygeai/lab/tools/clients.py +1 -0
- pygeai/migration/__init__.py +31 -0
- pygeai/migration/strategies.py +404 -155
- pygeai/migration/tools.py +170 -3
- pygeai/organization/clients.py +13 -0
- pygeai/organization/limits/clients.py +15 -0
- pygeai/proxy/clients.py +3 -1
- pygeai/tests/admin/test_clients.py +16 -11
- pygeai/tests/assistants/rag/test_clients.py +35 -23
- pygeai/tests/assistants/test_clients.py +22 -15
- pygeai/tests/auth/test_clients.py +14 -6
- pygeai/tests/chat/test_clients.py +211 -1
- pygeai/tests/cli/commands/test_embeddings.py +32 -9
- pygeai/tests/cli/commands/test_evaluation.py +7 -0
- pygeai/tests/cli/commands/test_migrate.py +112 -243
- pygeai/tests/cli/test_error_handler.py +225 -0
- pygeai/tests/cli/test_geai_driver.py +154 -0
- pygeai/tests/cli/test_parsers.py +5 -5
- pygeai/tests/core/embeddings/test_clients.py +144 -0
- pygeai/tests/core/embeddings/test_managers.py +171 -0
- pygeai/tests/core/embeddings/test_mappers.py +142 -0
- pygeai/tests/core/feedback/test_clients.py +2 -0
- pygeai/tests/core/files/test_clients.py +1 -0
- pygeai/tests/core/llm/test_clients.py +14 -9
- pygeai/tests/core/plugins/test_clients.py +5 -3
- pygeai/tests/core/rerank/test_clients.py +1 -0
- pygeai/tests/core/secrets/test_clients.py +19 -13
- pygeai/tests/dbg/test_debugger.py +453 -75
- pygeai/tests/evaluation/dataset/test_clients.py +3 -1
- pygeai/tests/evaluation/plan/test_clients.py +4 -2
- pygeai/tests/evaluation/result/test_clients.py +7 -5
- pygeai/tests/gam/test_clients.py +1 -1
- pygeai/tests/health/test_clients.py +1 -0
- pygeai/tests/lab/agents/test_clients.py +9 -0
- pygeai/tests/lab/processes/test_clients.py +36 -0
- pygeai/tests/lab/processes/test_mappers.py +3 -0
- pygeai/tests/lab/strategies/test_clients.py +14 -9
- pygeai/tests/migration/test_strategies.py +45 -218
- pygeai/tests/migration/test_tools.py +133 -9
- pygeai/tests/organization/limits/test_clients.py +17 -0
- pygeai/tests/organization/test_clients.py +22 -0
- pygeai/tests/proxy/test_clients.py +2 -0
- pygeai/tests/proxy/test_integration.py +1 -0
- pygeai/tests/snippets/chat/chat_completion_with_reasoning_effort.py +18 -0
- pygeai/tests/snippets/chat/get_response.py +15 -0
- pygeai/tests/snippets/chat/get_response_streaming.py +20 -0
- pygeai/tests/snippets/chat/get_response_with_files.py +16 -0
- pygeai/tests/snippets/chat/get_response_with_tools.py +36 -0
- pygeai/tests/snippets/dbg/__init__.py +0 -0
- pygeai/tests/snippets/dbg/basic_debugging.py +32 -0
- pygeai/tests/snippets/dbg/breakpoint_management.py +48 -0
- pygeai/tests/snippets/dbg/stack_navigation.py +45 -0
- pygeai/tests/snippets/dbg/stepping_example.py +40 -0
- pygeai/tests/snippets/embeddings/cache_example.py +31 -0
- pygeai/tests/snippets/embeddings/cohere_example.py +41 -0
- pygeai/tests/snippets/embeddings/openai_base64_example.py +27 -0
- pygeai/tests/snippets/embeddings/openai_example.py +30 -0
- pygeai/tests/snippets/embeddings/similarity_example.py +42 -0
- pygeai/tests/snippets/evaluation/dataset/__init__.py +0 -0
- pygeai/tests/snippets/evaluation/dataset/complete_workflow_example.py +195 -0
- pygeai/tests/snippets/evaluation/dataset/create_dataset.py +26 -0
- pygeai/tests/snippets/evaluation/dataset/create_dataset_from_file.py +11 -0
- pygeai/tests/snippets/evaluation/dataset/create_dataset_row.py +17 -0
- pygeai/tests/snippets/evaluation/dataset/create_expected_source.py +18 -0
- pygeai/tests/snippets/evaluation/dataset/create_filter_variable.py +19 -0
- pygeai/tests/snippets/evaluation/dataset/delete_dataset.py +9 -0
- pygeai/tests/snippets/evaluation/dataset/delete_dataset_row.py +10 -0
- pygeai/tests/snippets/evaluation/dataset/delete_expected_source.py +15 -0
- pygeai/tests/snippets/evaluation/dataset/delete_filter_variable.py +15 -0
- pygeai/tests/snippets/evaluation/dataset/get_dataset.py +9 -0
- pygeai/tests/snippets/evaluation/dataset/get_dataset_row.py +10 -0
- pygeai/tests/snippets/evaluation/dataset/get_expected_source.py +15 -0
- pygeai/tests/snippets/evaluation/dataset/get_filter_variable.py +15 -0
- pygeai/tests/snippets/evaluation/dataset/list_dataset_rows.py +9 -0
- pygeai/tests/snippets/evaluation/dataset/list_datasets.py +6 -0
- pygeai/tests/snippets/evaluation/dataset/list_expected_sources.py +10 -0
- pygeai/tests/snippets/evaluation/dataset/list_filter_variables.py +10 -0
- pygeai/tests/snippets/evaluation/dataset/update_dataset.py +15 -0
- pygeai/tests/snippets/evaluation/dataset/update_dataset_row.py +20 -0
- pygeai/tests/snippets/evaluation/dataset/update_expected_source.py +18 -0
- pygeai/tests/snippets/evaluation/dataset/update_filter_variable.py +19 -0
- pygeai/tests/snippets/evaluation/dataset/upload_dataset_rows_file.py +10 -0
- pygeai/tests/snippets/evaluation/plan/__init__.py +0 -0
- pygeai/tests/snippets/evaluation/plan/add_plan_system_metric.py +13 -0
- pygeai/tests/snippets/evaluation/plan/complete_workflow_example.py +136 -0
- pygeai/tests/snippets/evaluation/plan/create_evaluation_plan.py +24 -0
- pygeai/tests/snippets/evaluation/plan/create_rag_evaluation_plan.py +22 -0
- pygeai/tests/snippets/evaluation/plan/delete_evaluation_plan.py +9 -0
- pygeai/tests/snippets/evaluation/plan/delete_plan_system_metric.py +13 -0
- pygeai/tests/snippets/evaluation/plan/execute_evaluation_plan.py +11 -0
- pygeai/tests/snippets/evaluation/plan/get_evaluation_plan.py +9 -0
- pygeai/tests/snippets/evaluation/plan/get_plan_system_metric.py +13 -0
- pygeai/tests/snippets/evaluation/plan/get_system_metric.py +9 -0
- pygeai/tests/snippets/evaluation/plan/list_evaluation_plans.py +7 -0
- pygeai/tests/snippets/evaluation/plan/list_plan_system_metrics.py +9 -0
- pygeai/tests/snippets/evaluation/plan/list_system_metrics.py +7 -0
- pygeai/tests/snippets/evaluation/plan/update_evaluation_plan.py +22 -0
- pygeai/tests/snippets/evaluation/plan/update_plan_system_metric.py +14 -0
- pygeai/tests/snippets/evaluation/result/__init__.py +0 -0
- pygeai/tests/snippets/evaluation/result/complete_workflow_example.py +150 -0
- pygeai/tests/snippets/evaluation/result/get_evaluation_result.py +26 -0
- pygeai/tests/snippets/evaluation/result/list_evaluation_results.py +17 -0
- pygeai/tests/snippets/migrate/__init__.py +45 -0
- pygeai/tests/snippets/migrate/agent_migration.py +110 -0
- pygeai/tests/snippets/migrate/assistant_migration.py +64 -0
- pygeai/tests/snippets/migrate/orchestrator_examples.py +179 -0
- pygeai/tests/snippets/migrate/process_migration.py +64 -0
- pygeai/tests/snippets/migrate/project_migration.py +42 -0
- pygeai/tests/snippets/migrate/tool_migration.py +64 -0
- pygeai/tests/snippets/organization/create_project.py +2 -2
- {pygeai-0.6.0b7.dist-info → pygeai-0.6.0b10.dist-info}/METADATA +1 -1
- {pygeai-0.6.0b7.dist-info → pygeai-0.6.0b10.dist-info}/RECORD +178 -96
- {pygeai-0.6.0b7.dist-info → pygeai-0.6.0b10.dist-info}/WHEEL +0 -0
- {pygeai-0.6.0b7.dist-info → pygeai-0.6.0b10.dist-info}/entry_points.txt +0 -0
- {pygeai-0.6.0b7.dist-info → pygeai-0.6.0b10.dist-info}/licenses/LICENSE +0 -0
- {pygeai-0.6.0b7.dist-info → pygeai-0.6.0b10.dist-info}/top_level.txt +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import unittest
|
|
2
2
|
from unittest.mock import Mock
|
|
3
3
|
|
|
4
|
-
from pygeai.migration.tools import MigrationTool
|
|
4
|
+
from pygeai.migration.tools import MigrationTool, MigrationPlan, MigrationOrchestrator
|
|
5
5
|
from pygeai.migration.strategies import MigrationStrategy
|
|
6
6
|
|
|
7
7
|
|
|
@@ -11,25 +11,149 @@ class TestMigrationTool(unittest.TestCase):
|
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
13
|
def setUp(self):
|
|
14
|
-
"""Set up test fixtures"""
|
|
15
14
|
self.mock_strategy = Mock(spec=MigrationStrategy)
|
|
16
15
|
|
|
17
16
|
def test_migration_tool_initialization(self):
|
|
18
|
-
"""Test MigrationTool initialization with a strategy"""
|
|
19
17
|
tool = MigrationTool(self.mock_strategy)
|
|
20
|
-
self.assertEqual(tool.
|
|
18
|
+
self.assertEqual(tool._strategy, self.mock_strategy)
|
|
21
19
|
|
|
22
20
|
def test_migration_tool_set_strategy(self):
|
|
23
|
-
"""Test setting a new strategy on MigrationTool"""
|
|
24
21
|
tool = MigrationTool(self.mock_strategy)
|
|
25
22
|
new_strategy = Mock(spec=MigrationStrategy)
|
|
26
23
|
tool.set_strategy(new_strategy)
|
|
27
|
-
|
|
28
|
-
self.assertEqual(tool.strategy, new_strategy)
|
|
24
|
+
self.assertEqual(tool._strategy, new_strategy)
|
|
29
25
|
|
|
30
26
|
def test_migration_tool_run_migration(self):
|
|
31
|
-
"""Test running migration with the strategy"""
|
|
32
27
|
tool = MigrationTool(self.mock_strategy)
|
|
33
28
|
tool.run_migration()
|
|
29
|
+
self.mock_strategy.migrate.assert_called_once()
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class TestMigrationPlan(unittest.TestCase):
|
|
33
|
+
"""
|
|
34
|
+
python -m unittest pygeai.tests.migration.test_tools.TestMigrationPlan
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
def test_migration_plan_initialization(self):
|
|
38
|
+
strategies = [Mock(spec=MigrationStrategy), Mock(spec=MigrationStrategy)]
|
|
39
|
+
plan = MigrationPlan(strategies=strategies)
|
|
40
|
+
self.assertEqual(len(plan.strategies), 2)
|
|
41
|
+
self.assertEqual(plan.dependencies, {})
|
|
42
|
+
self.assertFalse(plan.dry_run)
|
|
43
|
+
self.assertTrue(plan.stop_on_error)
|
|
44
|
+
|
|
45
|
+
def test_migration_plan_with_dependencies(self):
|
|
46
|
+
strategies = [Mock(spec=MigrationStrategy), Mock(spec=MigrationStrategy)]
|
|
47
|
+
dependencies = {1: [0]}
|
|
48
|
+
plan = MigrationPlan(strategies=strategies, dependencies=dependencies)
|
|
49
|
+
self.assertEqual(plan.dependencies, {1: [0]})
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class TestMigrationOrchestrator(unittest.TestCase):
|
|
53
|
+
"""
|
|
54
|
+
python -m unittest pygeai.tests.migration.test_tools.TestMigrationOrchestrator
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
def setUp(self):
|
|
58
|
+
self.strategy1 = Mock(spec=MigrationStrategy)
|
|
59
|
+
self.strategy2 = Mock(spec=MigrationStrategy)
|
|
60
|
+
self.strategy3 = Mock(spec=MigrationStrategy)
|
|
61
|
+
|
|
62
|
+
def test_orchestrator_simple_execution(self):
|
|
63
|
+
plan = MigrationPlan(strategies=[self.strategy1, self.strategy2])
|
|
64
|
+
orchestrator = MigrationOrchestrator(plan)
|
|
65
|
+
|
|
66
|
+
result = orchestrator.execute()
|
|
67
|
+
|
|
68
|
+
self.strategy1.migrate.assert_called_once()
|
|
69
|
+
self.strategy2.migrate.assert_called_once()
|
|
70
|
+
self.assertEqual(result['total'], 2)
|
|
71
|
+
self.assertEqual(result['completed'], 2)
|
|
72
|
+
self.assertEqual(result['failed'], 0)
|
|
73
|
+
self.assertEqual(result['success_rate'], 1.0)
|
|
74
|
+
|
|
75
|
+
def test_orchestrator_with_dependencies(self):
|
|
76
|
+
plan = MigrationPlan(
|
|
77
|
+
strategies=[self.strategy1, self.strategy2, self.strategy3],
|
|
78
|
+
dependencies={1: [0], 2: [1]}
|
|
79
|
+
)
|
|
80
|
+
orchestrator = MigrationOrchestrator(plan)
|
|
81
|
+
|
|
82
|
+
result = orchestrator.execute()
|
|
83
|
+
|
|
84
|
+
self.assertEqual(result['completed'], 3)
|
|
85
|
+
self.assertEqual(result['completed_indices'], [0, 1, 2])
|
|
86
|
+
|
|
87
|
+
def test_orchestrator_stop_on_error(self):
|
|
88
|
+
self.strategy1.migrate.side_effect = Exception("Migration failed")
|
|
89
|
+
plan = MigrationPlan(
|
|
90
|
+
strategies=[self.strategy1, self.strategy2],
|
|
91
|
+
stop_on_error=True
|
|
92
|
+
)
|
|
93
|
+
orchestrator = MigrationOrchestrator(plan)
|
|
94
|
+
|
|
95
|
+
with self.assertRaises(ValueError) as context:
|
|
96
|
+
orchestrator.execute()
|
|
97
|
+
|
|
98
|
+
self.assertIn("Migration failed at strategy", str(context.exception))
|
|
99
|
+
self.strategy1.migrate.assert_called_once()
|
|
100
|
+
self.strategy2.migrate.assert_not_called()
|
|
101
|
+
|
|
102
|
+
def test_orchestrator_continue_on_error(self):
|
|
103
|
+
self.strategy1.migrate.side_effect = Exception("Migration failed")
|
|
104
|
+
plan = MigrationPlan(
|
|
105
|
+
strategies=[self.strategy1, self.strategy2],
|
|
106
|
+
stop_on_error=False
|
|
107
|
+
)
|
|
108
|
+
orchestrator = MigrationOrchestrator(plan)
|
|
109
|
+
|
|
110
|
+
result = orchestrator.execute()
|
|
111
|
+
|
|
112
|
+
self.strategy1.migrate.assert_called_once()
|
|
113
|
+
self.strategy2.migrate.assert_called_once()
|
|
114
|
+
self.assertEqual(result['completed'], 1)
|
|
115
|
+
self.assertEqual(result['failed'], 1)
|
|
116
|
+
self.assertEqual(result['success_rate'], 0.5)
|
|
117
|
+
|
|
118
|
+
def test_orchestrator_dry_run(self):
|
|
119
|
+
plan = MigrationPlan(
|
|
120
|
+
strategies=[self.strategy1, self.strategy2],
|
|
121
|
+
dry_run=True
|
|
122
|
+
)
|
|
123
|
+
orchestrator = MigrationOrchestrator(plan)
|
|
124
|
+
|
|
125
|
+
result = orchestrator.execute()
|
|
126
|
+
|
|
127
|
+
self.strategy1.migrate.assert_not_called()
|
|
128
|
+
self.strategy2.migrate.assert_not_called()
|
|
129
|
+
self.assertTrue(result['valid'])
|
|
130
|
+
self.assertEqual(result['execution_order'], [0, 1])
|
|
131
|
+
|
|
132
|
+
def test_orchestrator_circular_dependency(self):
|
|
133
|
+
plan = MigrationPlan(
|
|
134
|
+
strategies=[self.strategy1, self.strategy2],
|
|
135
|
+
dependencies={0: [1], 1: [0]}
|
|
136
|
+
)
|
|
137
|
+
orchestrator = MigrationOrchestrator(plan)
|
|
138
|
+
|
|
139
|
+
with self.assertRaises(ValueError) as context:
|
|
140
|
+
orchestrator.execute()
|
|
141
|
+
|
|
142
|
+
self.assertIn("Circular dependency", str(context.exception))
|
|
143
|
+
|
|
144
|
+
def test_orchestrator_dry_run_circular_dependency(self):
|
|
145
|
+
plan = MigrationPlan(
|
|
146
|
+
strategies=[self.strategy1, self.strategy2],
|
|
147
|
+
dependencies={0: [1], 1: [0]},
|
|
148
|
+
dry_run=True
|
|
149
|
+
)
|
|
150
|
+
orchestrator = MigrationOrchestrator(plan)
|
|
151
|
+
|
|
152
|
+
result = orchestrator.execute()
|
|
153
|
+
|
|
154
|
+
self.assertFalse(result['valid'])
|
|
155
|
+
self.assertIn("Circular dependency", result['error'])
|
|
156
|
+
|
|
34
157
|
|
|
35
|
-
|
|
158
|
+
if __name__ == '__main__':
|
|
159
|
+
unittest.main()
|
|
@@ -47,6 +47,7 @@ class TestUsageLimitClient(unittest.TestCase):
|
|
|
47
47
|
def test_set_organization_usage_limit_success(self, mock_post):
|
|
48
48
|
mock_response = mock_post.return_value
|
|
49
49
|
mock_response.json.return_value = self.valid_response
|
|
50
|
+
mock_response.status_code = 200
|
|
50
51
|
|
|
51
52
|
result = self.client.set_organization_usage_limit(self.organization, self.valid_usage_limit)
|
|
52
53
|
|
|
@@ -79,6 +80,7 @@ class TestUsageLimitClient(unittest.TestCase):
|
|
|
79
80
|
invalid_usage_limit["renewalStatus"] = "InvalidStatus"
|
|
80
81
|
mock_response = mock_post.return_value
|
|
81
82
|
mock_response.json.return_value = {"error": "Invalid renewal status"}
|
|
83
|
+
mock_response.status_code = 200
|
|
82
84
|
|
|
83
85
|
result = self.client.set_organization_usage_limit(self.organization, invalid_usage_limit)
|
|
84
86
|
|
|
@@ -94,6 +96,7 @@ class TestUsageLimitClient(unittest.TestCase):
|
|
|
94
96
|
def test_get_organization_latest_usage_limit_success(self, mock_get):
|
|
95
97
|
mock_response = mock_get.return_value
|
|
96
98
|
mock_response.json.return_value = self.valid_response
|
|
99
|
+
mock_response.status_code = 200
|
|
97
100
|
|
|
98
101
|
result = self.client.get_organization_latest_usage_limit(self.organization)
|
|
99
102
|
|
|
@@ -123,6 +126,7 @@ class TestUsageLimitClient(unittest.TestCase):
|
|
|
123
126
|
response = {"limits": [self.valid_response]}
|
|
124
127
|
mock_response = mock_get.return_value
|
|
125
128
|
mock_response.json.return_value = response
|
|
129
|
+
mock_response.status_code = 200
|
|
126
130
|
|
|
127
131
|
result = self.client.get_all_usage_limits_from_organization(self.organization)
|
|
128
132
|
|
|
@@ -153,6 +157,7 @@ class TestUsageLimitClient(unittest.TestCase):
|
|
|
153
157
|
response = {"status": "deleted"}
|
|
154
158
|
mock_response = mock_delete.return_value
|
|
155
159
|
mock_response.json.return_value = response
|
|
160
|
+
mock_response.status_code = 200
|
|
156
161
|
|
|
157
162
|
result = self.client.delete_usage_limit_from_organization(self.organization, self.limit_id)
|
|
158
163
|
|
|
@@ -183,6 +188,7 @@ class TestUsageLimitClient(unittest.TestCase):
|
|
|
183
188
|
response["hardLimit"] = hard_limit
|
|
184
189
|
mock_response = mock_put.return_value
|
|
185
190
|
mock_response.json.return_value = response
|
|
191
|
+
mock_response.status_code = 200
|
|
186
192
|
|
|
187
193
|
result = self.client.set_organization_hard_limit(self.organization, self.limit_id, hard_limit)
|
|
188
194
|
|
|
@@ -217,6 +223,7 @@ class TestUsageLimitClient(unittest.TestCase):
|
|
|
217
223
|
response["softLimit"] = soft_limit
|
|
218
224
|
mock_response = mock_put.return_value
|
|
219
225
|
mock_response.json.return_value = response
|
|
226
|
+
mock_response.status_code = 200
|
|
220
227
|
|
|
221
228
|
result = self.client.set_organization_soft_limit(self.organization, self.limit_id, soft_limit)
|
|
222
229
|
|
|
@@ -251,6 +258,7 @@ class TestUsageLimitClient(unittest.TestCase):
|
|
|
251
258
|
response["renewalStatus"] = renewal_status
|
|
252
259
|
mock_response = mock_put.return_value
|
|
253
260
|
mock_response.json.return_value = response
|
|
261
|
+
mock_response.status_code = 200
|
|
254
262
|
|
|
255
263
|
result = self.client.set_organization_renewal_status(self.organization, self.limit_id, renewal_status)
|
|
256
264
|
|
|
@@ -282,6 +290,7 @@ class TestUsageLimitClient(unittest.TestCase):
|
|
|
282
290
|
def test_set_project_usage_limit_success(self, mock_post):
|
|
283
291
|
mock_response = mock_post.return_value
|
|
284
292
|
mock_response.json.return_value = self.valid_response
|
|
293
|
+
mock_response.status_code = 200
|
|
285
294
|
|
|
286
295
|
result = self.client.set_project_usage_limit(self.organization, self.project, self.valid_usage_limit)
|
|
287
296
|
|
|
@@ -314,6 +323,7 @@ class TestUsageLimitClient(unittest.TestCase):
|
|
|
314
323
|
invalid_usage_limit["subscriptionType"] = "InvalidType"
|
|
315
324
|
mock_response = mock_post.return_value
|
|
316
325
|
mock_response.json.return_value = {"error": "Invalid subscription type"}
|
|
326
|
+
mock_response.status_code = 200
|
|
317
327
|
|
|
318
328
|
result = self.client.set_project_usage_limit(self.organization, self.project, invalid_usage_limit)
|
|
319
329
|
|
|
@@ -330,6 +340,7 @@ class TestUsageLimitClient(unittest.TestCase):
|
|
|
330
340
|
response = {"limits": [self.valid_response]}
|
|
331
341
|
mock_response = mock_get.return_value
|
|
332
342
|
mock_response.json.return_value = response
|
|
343
|
+
mock_response.status_code = 200
|
|
333
344
|
|
|
334
345
|
result = self.client.get_all_usage_limits_from_project(self.organization, self.project)
|
|
335
346
|
|
|
@@ -359,6 +370,7 @@ class TestUsageLimitClient(unittest.TestCase):
|
|
|
359
370
|
def test_get_latest_usage_limit_from_project_success(self, mock_get):
|
|
360
371
|
mock_response = mock_get.return_value
|
|
361
372
|
mock_response.json.return_value = self.valid_response
|
|
373
|
+
mock_response.status_code = 200
|
|
362
374
|
|
|
363
375
|
result = self.client.get_latest_usage_limit_from_project(self.organization, self.project)
|
|
364
376
|
|
|
@@ -387,6 +399,7 @@ class TestUsageLimitClient(unittest.TestCase):
|
|
|
387
399
|
def test_get_active_usage_limit_from_project_success(self, mock_get):
|
|
388
400
|
mock_response = mock_get.return_value
|
|
389
401
|
mock_response.json.return_value = self.valid_response
|
|
402
|
+
mock_response.status_code = 200
|
|
390
403
|
|
|
391
404
|
result = self.client.get_active_usage_limit_from_project(self.organization, self.project)
|
|
392
405
|
|
|
@@ -416,6 +429,7 @@ class TestUsageLimitClient(unittest.TestCase):
|
|
|
416
429
|
response = {"status": "deleted"}
|
|
417
430
|
mock_response = mock_delete.return_value
|
|
418
431
|
mock_response.json.return_value = response
|
|
432
|
+
mock_response.status_code = 200
|
|
419
433
|
|
|
420
434
|
result = self.client.delete_usage_limit_from_project(self.organization, self.project, self.limit_id)
|
|
421
435
|
|
|
@@ -446,6 +460,7 @@ class TestUsageLimitClient(unittest.TestCase):
|
|
|
446
460
|
response["hardLimit"] = hard_limit
|
|
447
461
|
mock_response = mock_put.return_value
|
|
448
462
|
mock_response.json.return_value = response
|
|
463
|
+
mock_response.status_code = 200
|
|
449
464
|
|
|
450
465
|
result = self.client.set_hard_limit_for_active_usage_limit_from_project(
|
|
451
466
|
self.organization, self.project, self.limit_id, hard_limit
|
|
@@ -484,6 +499,7 @@ class TestUsageLimitClient(unittest.TestCase):
|
|
|
484
499
|
response["softLimit"] = soft_limit
|
|
485
500
|
mock_response = mock_put.return_value
|
|
486
501
|
mock_response.json.return_value = response
|
|
502
|
+
mock_response.status_code = 200
|
|
487
503
|
|
|
488
504
|
result = self.client.set_soft_limit_for_active_usage_limit_from_project(
|
|
489
505
|
self.organization, self.project, self.limit_id, soft_limit
|
|
@@ -522,6 +538,7 @@ class TestUsageLimitClient(unittest.TestCase):
|
|
|
522
538
|
response["renewalStatus"] = renewal_status
|
|
523
539
|
mock_response = mock_put.return_value
|
|
524
540
|
mock_response.json.return_value = response
|
|
541
|
+
mock_response.status_code = 200
|
|
525
542
|
|
|
526
543
|
result = self.client.set_project_renewal_status(self.organization, self.project, self.limit_id, renewal_status)
|
|
527
544
|
|
|
@@ -21,6 +21,7 @@ class TestOrganizationClient(unittest.TestCase):
|
|
|
21
21
|
def test_get_assistant_list_success(self, mock_get):
|
|
22
22
|
mock_response = mock_get.return_value
|
|
23
23
|
mock_response.json.return_value = {"assistants": [{"name": "assistant1"}, {"name": "assistant2"}]}
|
|
24
|
+
mock_response.status_code = 200
|
|
24
25
|
|
|
25
26
|
result = self.client.get_assistant_list(detail="summary")
|
|
26
27
|
|
|
@@ -47,6 +48,7 @@ class TestOrganizationClient(unittest.TestCase):
|
|
|
47
48
|
def test_get_project_list_success(self, mock_get):
|
|
48
49
|
mock_response = mock_get.return_value
|
|
49
50
|
mock_response.json.return_value = {"projects": [{"name": "project1"}, {"name": "project2"}]}
|
|
51
|
+
mock_response.status_code = 200
|
|
50
52
|
|
|
51
53
|
result = self.client.get_project_list(detail="summary")
|
|
52
54
|
|
|
@@ -60,6 +62,7 @@ class TestOrganizationClient(unittest.TestCase):
|
|
|
60
62
|
def test_get_project_list_with_name(self, mock_get):
|
|
61
63
|
mock_response = mock_get.return_value
|
|
62
64
|
mock_response.json.return_value = {"projects": [{"name": "specific_project"}]}
|
|
65
|
+
mock_response.status_code = 200
|
|
63
66
|
|
|
64
67
|
result = self.client.get_project_list(detail="full", name="specific_project")
|
|
65
68
|
|
|
@@ -88,6 +91,7 @@ class TestOrganizationClient(unittest.TestCase):
|
|
|
88
91
|
def test_get_project_data_success(self, mock_get):
|
|
89
92
|
mock_response = mock_get.return_value
|
|
90
93
|
mock_response.json.return_value = {"project": {"id": "123", "name": "project1"}}
|
|
94
|
+
mock_response.status_code = 200
|
|
91
95
|
|
|
92
96
|
result = self.client.get_project_data(project_id="123")
|
|
93
97
|
|
|
@@ -112,6 +116,7 @@ class TestOrganizationClient(unittest.TestCase):
|
|
|
112
116
|
def test_create_project_success(self, mock_post):
|
|
113
117
|
mock_response = mock_post.return_value
|
|
114
118
|
mock_response.json.return_value = {"project": {"id": "123", "name": "project1"}}
|
|
119
|
+
mock_response.status_code = 200
|
|
115
120
|
|
|
116
121
|
result = self.client.create_project(name="project1", email="admin@example.com", description="A test project")
|
|
117
122
|
|
|
@@ -130,6 +135,7 @@ class TestOrganizationClient(unittest.TestCase):
|
|
|
130
135
|
def test_create_project_with_usage_limit(self, mock_post):
|
|
131
136
|
mock_response = mock_post.return_value
|
|
132
137
|
mock_response.json.return_value = {"project": {"id": "123", "name": "project1"}}
|
|
138
|
+
mock_response.status_code = 200
|
|
133
139
|
|
|
134
140
|
usage_limit = {"type": "Requests", "threshold": 1000}
|
|
135
141
|
result = self.client.create_project(
|
|
@@ -172,6 +178,7 @@ class TestOrganizationClient(unittest.TestCase):
|
|
|
172
178
|
def test_update_project_success(self, mock_put):
|
|
173
179
|
mock_response = mock_put.return_value
|
|
174
180
|
mock_response.json.return_value = {"project": {"id": "123", "name": "updated_project"}}
|
|
181
|
+
mock_response.status_code = 200
|
|
175
182
|
|
|
176
183
|
result = self.client.update_project(project_id="123", name="updated_project", description="Updated description")
|
|
177
184
|
|
|
@@ -202,6 +209,7 @@ class TestOrganizationClient(unittest.TestCase):
|
|
|
202
209
|
def test_delete_project_success(self, mock_delete):
|
|
203
210
|
mock_response = mock_delete.return_value
|
|
204
211
|
mock_response.json.return_value = {"status": "deleted"}
|
|
212
|
+
mock_response.status_code = 200
|
|
205
213
|
|
|
206
214
|
result = self.client.delete_project(project_id="123")
|
|
207
215
|
|
|
@@ -226,6 +234,7 @@ class TestOrganizationClient(unittest.TestCase):
|
|
|
226
234
|
def test_get_project_tokens_success(self, mock_get):
|
|
227
235
|
mock_response = mock_get.return_value
|
|
228
236
|
mock_response.json.return_value = {"tokens": ["token1", "token2"]}
|
|
237
|
+
mock_response.status_code = 200
|
|
229
238
|
|
|
230
239
|
result = self.client.get_project_tokens(project_id="123")
|
|
231
240
|
|
|
@@ -252,6 +261,7 @@ class TestOrganizationClient(unittest.TestCase):
|
|
|
252
261
|
def test_export_request_data_success(self, mock_get):
|
|
253
262
|
mock_response = mock_get.return_value
|
|
254
263
|
mock_response.json.return_value = {"requests": [{"id": "1", "status": "pending"}]}
|
|
264
|
+
mock_response.status_code = 200
|
|
255
265
|
|
|
256
266
|
result = self.client.export_request_data()
|
|
257
267
|
|
|
@@ -267,6 +277,7 @@ class TestOrganizationClient(unittest.TestCase):
|
|
|
267
277
|
def test_export_request_data_with_params(self, mock_get):
|
|
268
278
|
mock_response = mock_get.return_value
|
|
269
279
|
mock_response.json.return_value = {"requests": [{"id": "1", "status": "completed"}]}
|
|
280
|
+
mock_response.status_code = 200
|
|
270
281
|
|
|
271
282
|
result = self.client.export_request_data(assistant_name="assistant1", status="completed", skip=10, count=5)
|
|
272
283
|
|
|
@@ -298,6 +309,7 @@ class TestOrganizationClient(unittest.TestCase):
|
|
|
298
309
|
def test_get_memberships_success(self, mock_get):
|
|
299
310
|
mock_response = mock_get.return_value
|
|
300
311
|
mock_response.json.return_value = {
|
|
312
|
+
|
|
301
313
|
"count": 1,
|
|
302
314
|
"pages": 1,
|
|
303
315
|
"organizationsMemberships": [
|
|
@@ -308,6 +320,7 @@ class TestOrganizationClient(unittest.TestCase):
|
|
|
308
320
|
}
|
|
309
321
|
]
|
|
310
322
|
}
|
|
323
|
+
mock_response.status_code = 200
|
|
311
324
|
|
|
312
325
|
result = self.client.get_memberships()
|
|
313
326
|
|
|
@@ -322,6 +335,7 @@ class TestOrganizationClient(unittest.TestCase):
|
|
|
322
335
|
def test_get_memberships_with_params(self, mock_get):
|
|
323
336
|
mock_response = mock_get.return_value
|
|
324
337
|
mock_response.json.return_value = {"count": 0, "pages": 0, "organizationsMemberships": []}
|
|
338
|
+
mock_response.status_code = 200
|
|
325
339
|
|
|
326
340
|
result = self.client.get_memberships(
|
|
327
341
|
email="test@example.com",
|
|
@@ -361,6 +375,7 @@ class TestOrganizationClient(unittest.TestCase):
|
|
|
361
375
|
def test_get_project_memberships_success(self, mock_get):
|
|
362
376
|
mock_response = mock_get.return_value
|
|
363
377
|
mock_response.json.return_value = {
|
|
378
|
+
|
|
364
379
|
"count": 1,
|
|
365
380
|
"pages": 1,
|
|
366
381
|
"projectsMemberships": [
|
|
@@ -373,6 +388,7 @@ class TestOrganizationClient(unittest.TestCase):
|
|
|
373
388
|
}
|
|
374
389
|
]
|
|
375
390
|
}
|
|
391
|
+
mock_response.status_code = 200
|
|
376
392
|
|
|
377
393
|
result = self.client.get_project_memberships()
|
|
378
394
|
|
|
@@ -399,10 +415,12 @@ class TestOrganizationClient(unittest.TestCase):
|
|
|
399
415
|
def test_get_project_roles_success(self, mock_get):
|
|
400
416
|
mock_response = mock_get.return_value
|
|
401
417
|
mock_response.json.return_value = {
|
|
418
|
+
|
|
402
419
|
"roles": [
|
|
403
420
|
{"id": "role-1", "name": "Admin", "externalId": "admin-ext", "type": "backend", "origin": "system"}
|
|
404
421
|
]
|
|
405
422
|
}
|
|
423
|
+
mock_response.status_code = 200
|
|
406
424
|
|
|
407
425
|
result = self.client.get_project_roles(project_id="proj-123")
|
|
408
426
|
|
|
@@ -426,10 +444,12 @@ class TestOrganizationClient(unittest.TestCase):
|
|
|
426
444
|
def test_get_project_members_success(self, mock_get):
|
|
427
445
|
mock_response = mock_get.return_value
|
|
428
446
|
mock_response.json.return_value = {
|
|
447
|
+
|
|
429
448
|
"members": [
|
|
430
449
|
{"email": "user@example.com", "roles": []}
|
|
431
450
|
]
|
|
432
451
|
}
|
|
452
|
+
mock_response.status_code = 200
|
|
433
453
|
|
|
434
454
|
result = self.client.get_project_members(project_id="proj-123")
|
|
435
455
|
|
|
@@ -453,10 +473,12 @@ class TestOrganizationClient(unittest.TestCase):
|
|
|
453
473
|
def test_get_organization_members_success(self, mock_get):
|
|
454
474
|
mock_response = mock_get.return_value
|
|
455
475
|
mock_response.json.return_value = {
|
|
476
|
+
|
|
456
477
|
"members": [
|
|
457
478
|
{"email": "user@example.com", "roles": []}
|
|
458
479
|
]
|
|
459
480
|
}
|
|
481
|
+
mock_response.status_code = 200
|
|
460
482
|
|
|
461
483
|
result = self.client.get_organization_members(organization_id="org-123")
|
|
462
484
|
|
|
@@ -247,6 +247,7 @@ class TestProxyClient(unittest.TestCase):
|
|
|
247
247
|
"""Test successful request."""
|
|
248
248
|
mock_response = Mock()
|
|
249
249
|
mock_response.json.return_value = {"status": "success"}
|
|
250
|
+
mock_response.status_code = 200
|
|
250
251
|
mock_response.raise_for_status.return_value = None
|
|
251
252
|
mock_session.return_value.request.return_value = mock_response
|
|
252
253
|
|
|
@@ -311,6 +312,7 @@ class TestProxyClient(unittest.TestCase):
|
|
|
311
312
|
mock_response = Mock()
|
|
312
313
|
mock_response.json.side_effect = ValueError("Invalid JSON")
|
|
313
314
|
mock_response.text = "plain text response"
|
|
315
|
+
mock_response.status_code = 200
|
|
314
316
|
mock_response.raise_for_status.return_value = None
|
|
315
317
|
mock_session.return_value.request.return_value = mock_response
|
|
316
318
|
|
|
@@ -230,6 +230,7 @@ class TestProxyIntegration(unittest.IsolatedAsyncioTestCase):
|
|
|
230
230
|
# Mock response
|
|
231
231
|
mock_response = Mock()
|
|
232
232
|
mock_response.json.return_value = {"status": "success", "data": "test_data"}
|
|
233
|
+
mock_response.status_code = 200
|
|
233
234
|
mock_response.raise_for_status.return_value = None
|
|
234
235
|
mock_session.return_value.request.return_value = mock_response
|
|
235
236
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from pygeai.chat.clients import ChatClient
|
|
2
|
+
|
|
3
|
+
client = ChatClient()
|
|
4
|
+
|
|
5
|
+
messages = [
|
|
6
|
+
{
|
|
7
|
+
"role": "user",
|
|
8
|
+
"content": "Explain quantum computing in simple terms"
|
|
9
|
+
}
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
response = client.chat_completion(
|
|
13
|
+
model="openai/gpt-4o",
|
|
14
|
+
messages=messages,
|
|
15
|
+
reasoning_effort="high"
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
print(response)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from pygeai.chat.clients import ChatClient
|
|
2
|
+
|
|
3
|
+
client = ChatClient()
|
|
4
|
+
|
|
5
|
+
model = "openai/o1-pro"
|
|
6
|
+
input_text = "What is the weather like in Paris today?"
|
|
7
|
+
|
|
8
|
+
response = client.get_response(
|
|
9
|
+
model=model,
|
|
10
|
+
input=input_text,
|
|
11
|
+
temperature=0.7,
|
|
12
|
+
max_output_tokens=1000
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
print(response)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from pygeai.chat.clients import ChatClient
|
|
2
|
+
|
|
3
|
+
client = ChatClient()
|
|
4
|
+
|
|
5
|
+
model = "openai/o1-pro"
|
|
6
|
+
input_text = "Tell me a short story about a robot"
|
|
7
|
+
|
|
8
|
+
response = client.get_response(
|
|
9
|
+
model=model,
|
|
10
|
+
input=input_text,
|
|
11
|
+
stream=True,
|
|
12
|
+
temperature=0.7,
|
|
13
|
+
max_output_tokens=500
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
print("Streaming response:")
|
|
17
|
+
for chunk in response:
|
|
18
|
+
print(chunk, end='', flush=True)
|
|
19
|
+
|
|
20
|
+
print("\n\nStreaming complete!")
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from pygeai.chat.clients import ChatClient
|
|
2
|
+
|
|
3
|
+
client = ChatClient()
|
|
4
|
+
|
|
5
|
+
model = "openai/o1-pro"
|
|
6
|
+
input_text = "Please analyze this image and describe what you see"
|
|
7
|
+
files = ["files/image.svg", "files/document.pdf"]
|
|
8
|
+
|
|
9
|
+
response = client.get_response(
|
|
10
|
+
model=model,
|
|
11
|
+
input=input_text,
|
|
12
|
+
files=files,
|
|
13
|
+
temperature=0.7
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
print(response)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from pygeai.chat.clients import ChatClient
|
|
2
|
+
|
|
3
|
+
client = ChatClient()
|
|
4
|
+
|
|
5
|
+
model = "openai/o1-pro"
|
|
6
|
+
input_text = "What is the weather like in Paris today?"
|
|
7
|
+
|
|
8
|
+
tools = [
|
|
9
|
+
{
|
|
10
|
+
"type": "function",
|
|
11
|
+
"name": "get_weather",
|
|
12
|
+
"description": "Get current temperature for a given location.",
|
|
13
|
+
"parameters": {
|
|
14
|
+
"type": "object",
|
|
15
|
+
"properties": {
|
|
16
|
+
"location": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"description": "City and country e.g. Paris, France"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"required": ["location"],
|
|
22
|
+
"additionalProperties": False
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
response = client.get_response(
|
|
28
|
+
model=model,
|
|
29
|
+
input=input_text,
|
|
30
|
+
tools=tools,
|
|
31
|
+
tool_choice="auto",
|
|
32
|
+
temperature=1.0,
|
|
33
|
+
reasoning={"effort": "medium"}
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
print(response)
|
|
File without changes
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Basic debugging example with geai-dbg.
|
|
3
|
+
|
|
4
|
+
This demonstrates setting breakpoints and inspecting variables.
|
|
5
|
+
"""
|
|
6
|
+
from pygeai.dbg.debugger import Debugger
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def example_function(x, y):
|
|
10
|
+
"""A simple function to debug."""
|
|
11
|
+
result = x + y
|
|
12
|
+
print(f"Result: {result}")
|
|
13
|
+
return result
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def main():
|
|
17
|
+
"""Main entry point."""
|
|
18
|
+
a = 10
|
|
19
|
+
b = 20
|
|
20
|
+
c = example_function(a, b)
|
|
21
|
+
print(f"Final value: {c}")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
if __name__ == "__main__":
|
|
25
|
+
dbg = Debugger(target=main, module_filter="__main__")
|
|
26
|
+
dbg.add_breakpoint(module="__main__", function_name="example_function")
|
|
27
|
+
|
|
28
|
+
print("Starting debugger...")
|
|
29
|
+
print("Type 'h' for help")
|
|
30
|
+
print("Try commands like: 'p x', 'p y', 'locals', 's', 'n', 'c'")
|
|
31
|
+
|
|
32
|
+
dbg.run()
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Demonstrates breakpoint management (add, list, remove, enable/disable).
|
|
3
|
+
"""
|
|
4
|
+
from pygeai.dbg.debugger import Debugger
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def func_a():
|
|
8
|
+
"""Function A."""
|
|
9
|
+
print("In function A")
|
|
10
|
+
return "A"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def func_b():
|
|
14
|
+
"""Function B."""
|
|
15
|
+
print("In function B")
|
|
16
|
+
return "B"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def func_c():
|
|
20
|
+
"""Function C."""
|
|
21
|
+
print("In function C")
|
|
22
|
+
return "C"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def main():
|
|
26
|
+
"""Main entry point."""
|
|
27
|
+
results = []
|
|
28
|
+
results.append(func_a())
|
|
29
|
+
results.append(func_b())
|
|
30
|
+
results.append(func_c())
|
|
31
|
+
print(f"Results: {results}")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
if __name__ == "__main__":
|
|
35
|
+
dbg = Debugger(target=main, module_filter="__main__")
|
|
36
|
+
|
|
37
|
+
print("Starting debugger...")
|
|
38
|
+
print("No breakpoints set initially. At first function, try:")
|
|
39
|
+
print(" 'b func_b' - add breakpoint on func_b")
|
|
40
|
+
print(" 'b __main__:func_c' - add breakpoint on specific module:function")
|
|
41
|
+
print(" 'b' - list all breakpoints")
|
|
42
|
+
print(" 'dis func_b' - disable breakpoint on func_b")
|
|
43
|
+
print(" 'en func_b' - enable breakpoint on func_b")
|
|
44
|
+
print(" 'cl func_b' - remove breakpoint on func_b")
|
|
45
|
+
print(" 'c' - continue to next breakpoint")
|
|
46
|
+
|
|
47
|
+
dbg.add_breakpoint(module="__main__", function_name="func_a")
|
|
48
|
+
dbg.run()
|