aiverify-moonshot 0.4.0__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 (163) hide show
  1. aiverify_moonshot-0.4.0.dist-info/METADATA +249 -0
  2. aiverify_moonshot-0.4.0.dist-info/RECORD +163 -0
  3. aiverify_moonshot-0.4.0.dist-info/WHEEL +4 -0
  4. aiverify_moonshot-0.4.0.dist-info/licenses/AUTHORS.md +5 -0
  5. aiverify_moonshot-0.4.0.dist-info/licenses/LICENSE.md +201 -0
  6. aiverify_moonshot-0.4.0.dist-info/licenses/NOTICES.md +3340 -0
  7. moonshot/__init__.py +0 -0
  8. moonshot/__main__.py +198 -0
  9. moonshot/api.py +155 -0
  10. moonshot/integrations/__init__.py +0 -0
  11. moonshot/integrations/cli/__init__.py +0 -0
  12. moonshot/integrations/cli/__main__.py +25 -0
  13. moonshot/integrations/cli/active_session_cfg.py +1 -0
  14. moonshot/integrations/cli/benchmark/__init__.py +0 -0
  15. moonshot/integrations/cli/benchmark/benchmark.py +186 -0
  16. moonshot/integrations/cli/benchmark/cookbook.py +545 -0
  17. moonshot/integrations/cli/benchmark/datasets.py +164 -0
  18. moonshot/integrations/cli/benchmark/metrics.py +141 -0
  19. moonshot/integrations/cli/benchmark/recipe.py +598 -0
  20. moonshot/integrations/cli/benchmark/result.py +216 -0
  21. moonshot/integrations/cli/benchmark/run.py +140 -0
  22. moonshot/integrations/cli/benchmark/runner.py +174 -0
  23. moonshot/integrations/cli/cli.py +64 -0
  24. moonshot/integrations/cli/common/__init__.py +0 -0
  25. moonshot/integrations/cli/common/common.py +72 -0
  26. moonshot/integrations/cli/common/connectors.py +325 -0
  27. moonshot/integrations/cli/common/display_helper.py +42 -0
  28. moonshot/integrations/cli/common/prompt_template.py +94 -0
  29. moonshot/integrations/cli/initialisation/__init__.py +0 -0
  30. moonshot/integrations/cli/initialisation/initialisation.py +14 -0
  31. moonshot/integrations/cli/redteam/__init__.py +0 -0
  32. moonshot/integrations/cli/redteam/attack_module.py +70 -0
  33. moonshot/integrations/cli/redteam/context_strategy.py +147 -0
  34. moonshot/integrations/cli/redteam/prompt_template.py +67 -0
  35. moonshot/integrations/cli/redteam/redteam.py +90 -0
  36. moonshot/integrations/cli/redteam/session.py +467 -0
  37. moonshot/integrations/web_api/.env.dev +7 -0
  38. moonshot/integrations/web_api/__init__.py +0 -0
  39. moonshot/integrations/web_api/__main__.py +56 -0
  40. moonshot/integrations/web_api/app.py +125 -0
  41. moonshot/integrations/web_api/container.py +146 -0
  42. moonshot/integrations/web_api/log/.gitkeep +0 -0
  43. moonshot/integrations/web_api/logging_conf.py +114 -0
  44. moonshot/integrations/web_api/routes/__init__.py +0 -0
  45. moonshot/integrations/web_api/routes/attack_modules.py +66 -0
  46. moonshot/integrations/web_api/routes/benchmark.py +116 -0
  47. moonshot/integrations/web_api/routes/benchmark_result.py +175 -0
  48. moonshot/integrations/web_api/routes/context_strategy.py +129 -0
  49. moonshot/integrations/web_api/routes/cookbook.py +225 -0
  50. moonshot/integrations/web_api/routes/dataset.py +120 -0
  51. moonshot/integrations/web_api/routes/endpoint.py +282 -0
  52. moonshot/integrations/web_api/routes/metric.py +78 -0
  53. moonshot/integrations/web_api/routes/prompt_template.py +128 -0
  54. moonshot/integrations/web_api/routes/recipe.py +219 -0
  55. moonshot/integrations/web_api/routes/redteam.py +609 -0
  56. moonshot/integrations/web_api/routes/runner.py +239 -0
  57. moonshot/integrations/web_api/schemas/__init__.py +0 -0
  58. moonshot/integrations/web_api/schemas/benchmark_runner_dto.py +13 -0
  59. moonshot/integrations/web_api/schemas/cookbook_create_dto.py +19 -0
  60. moonshot/integrations/web_api/schemas/cookbook_response_model.py +9 -0
  61. moonshot/integrations/web_api/schemas/dataset_response_dto.py +9 -0
  62. moonshot/integrations/web_api/schemas/endpoint_create_dto.py +21 -0
  63. moonshot/integrations/web_api/schemas/endpoint_response_model.py +11 -0
  64. moonshot/integrations/web_api/schemas/prompt_response_model.py +14 -0
  65. moonshot/integrations/web_api/schemas/prompt_template_response_model.py +10 -0
  66. moonshot/integrations/web_api/schemas/recipe_create_dto.py +32 -0
  67. moonshot/integrations/web_api/schemas/recipe_response_model.py +7 -0
  68. moonshot/integrations/web_api/schemas/session_create_dto.py +16 -0
  69. moonshot/integrations/web_api/schemas/session_prompt_dto.py +7 -0
  70. moonshot/integrations/web_api/schemas/session_response_model.py +38 -0
  71. moonshot/integrations/web_api/services/__init__.py +0 -0
  72. moonshot/integrations/web_api/services/attack_module_service.py +34 -0
  73. moonshot/integrations/web_api/services/auto_red_team_test_manager.py +86 -0
  74. moonshot/integrations/web_api/services/auto_red_team_test_state.py +57 -0
  75. moonshot/integrations/web_api/services/base_service.py +8 -0
  76. moonshot/integrations/web_api/services/benchmark_result_service.py +25 -0
  77. moonshot/integrations/web_api/services/benchmark_test_manager.py +106 -0
  78. moonshot/integrations/web_api/services/benchmark_test_state.py +56 -0
  79. moonshot/integrations/web_api/services/benchmarking_service.py +31 -0
  80. moonshot/integrations/web_api/services/context_strategy_service.py +22 -0
  81. moonshot/integrations/web_api/services/cookbook_service.py +194 -0
  82. moonshot/integrations/web_api/services/dataset_service.py +20 -0
  83. moonshot/integrations/web_api/services/endpoint_service.py +65 -0
  84. moonshot/integrations/web_api/services/metric_service.py +14 -0
  85. moonshot/integrations/web_api/services/prompt_template_service.py +39 -0
  86. moonshot/integrations/web_api/services/recipe_service.py +155 -0
  87. moonshot/integrations/web_api/services/runner_service.py +147 -0
  88. moonshot/integrations/web_api/services/session_service.py +350 -0
  89. moonshot/integrations/web_api/services/utils/exceptions_handler.py +41 -0
  90. moonshot/integrations/web_api/services/utils/results_formatter.py +47 -0
  91. moonshot/integrations/web_api/status_updater/interface/benchmark_progress_callback.py +14 -0
  92. moonshot/integrations/web_api/status_updater/interface/redteam_progress_callback.py +14 -0
  93. moonshot/integrations/web_api/status_updater/moonshot_ui_webhook.py +72 -0
  94. moonshot/integrations/web_api/types/types.py +99 -0
  95. moonshot/src/__init__.py +0 -0
  96. moonshot/src/api/__init__.py +0 -0
  97. moonshot/src/api/api_connector.py +58 -0
  98. moonshot/src/api/api_connector_endpoint.py +162 -0
  99. moonshot/src/api/api_context_strategy.py +57 -0
  100. moonshot/src/api/api_cookbook.py +160 -0
  101. moonshot/src/api/api_dataset.py +46 -0
  102. moonshot/src/api/api_environment_variables.py +17 -0
  103. moonshot/src/api/api_metrics.py +51 -0
  104. moonshot/src/api/api_prompt_template.py +43 -0
  105. moonshot/src/api/api_recipe.py +182 -0
  106. moonshot/src/api/api_red_teaming.py +59 -0
  107. moonshot/src/api/api_result.py +84 -0
  108. moonshot/src/api/api_run.py +74 -0
  109. moonshot/src/api/api_runner.py +132 -0
  110. moonshot/src/api/api_session.py +290 -0
  111. moonshot/src/configs/__init__.py +0 -0
  112. moonshot/src/configs/env_variables.py +187 -0
  113. moonshot/src/connectors/__init__.py +0 -0
  114. moonshot/src/connectors/connector.py +327 -0
  115. moonshot/src/connectors/connector_prompt_arguments.py +17 -0
  116. moonshot/src/connectors_endpoints/__init__.py +0 -0
  117. moonshot/src/connectors_endpoints/connector_endpoint.py +211 -0
  118. moonshot/src/connectors_endpoints/connector_endpoint_arguments.py +54 -0
  119. moonshot/src/cookbooks/__init__.py +0 -0
  120. moonshot/src/cookbooks/cookbook.py +225 -0
  121. moonshot/src/cookbooks/cookbook_arguments.py +34 -0
  122. moonshot/src/datasets/__init__.py +0 -0
  123. moonshot/src/datasets/dataset.py +255 -0
  124. moonshot/src/datasets/dataset_arguments.py +50 -0
  125. moonshot/src/metrics/__init__.py +0 -0
  126. moonshot/src/metrics/metric.py +192 -0
  127. moonshot/src/metrics/metric_interface.py +95 -0
  128. moonshot/src/prompt_templates/__init__.py +0 -0
  129. moonshot/src/prompt_templates/prompt_template.py +103 -0
  130. moonshot/src/recipes/__init__.py +0 -0
  131. moonshot/src/recipes/recipe.py +340 -0
  132. moonshot/src/recipes/recipe_arguments.py +111 -0
  133. moonshot/src/redteaming/__init__.py +0 -0
  134. moonshot/src/redteaming/attack/__init__.py +0 -0
  135. moonshot/src/redteaming/attack/attack_module.py +618 -0
  136. moonshot/src/redteaming/attack/attack_module_arguments.py +44 -0
  137. moonshot/src/redteaming/attack/context_strategy.py +131 -0
  138. moonshot/src/redteaming/context_strategy/__init__.py +0 -0
  139. moonshot/src/redteaming/context_strategy/context_strategy_interface.py +46 -0
  140. moonshot/src/redteaming/session/__init__.py +0 -0
  141. moonshot/src/redteaming/session/chat.py +209 -0
  142. moonshot/src/redteaming/session/red_teaming_progress.py +128 -0
  143. moonshot/src/redteaming/session/red_teaming_type.py +6 -0
  144. moonshot/src/redteaming/session/session.py +775 -0
  145. moonshot/src/results/__init__.py +0 -0
  146. moonshot/src/results/result.py +119 -0
  147. moonshot/src/results/result_arguments.py +44 -0
  148. moonshot/src/runners/__init__.py +0 -0
  149. moonshot/src/runners/runner.py +476 -0
  150. moonshot/src/runners/runner_arguments.py +46 -0
  151. moonshot/src/runners/runner_type.py +6 -0
  152. moonshot/src/runs/__init__.py +0 -0
  153. moonshot/src/runs/run.py +344 -0
  154. moonshot/src/runs/run_arguments.py +162 -0
  155. moonshot/src/runs/run_progress.py +145 -0
  156. moonshot/src/runs/run_status.py +10 -0
  157. moonshot/src/storage/__init__.py +0 -0
  158. moonshot/src/storage/db_interface.py +128 -0
  159. moonshot/src/storage/io_interface.py +31 -0
  160. moonshot/src/storage/storage.py +525 -0
  161. moonshot/src/utils/__init__.py +0 -0
  162. moonshot/src/utils/import_modules.py +96 -0
  163. moonshot/src/utils/timeit.py +25 -0
@@ -0,0 +1,282 @@
1
+ from typing import Optional
2
+
3
+ from dependency_injector.wiring import Provide, inject
4
+ from fastapi import APIRouter, Depends, HTTPException
5
+
6
+ from ..container import Container
7
+ from ..schemas.endpoint_create_dto import EndpointCreateDTO, EndpointUpdateDTO
8
+ from ..schemas.endpoint_response_model import EndpointDataModel
9
+ from ..services.endpoint_service import EndpointService
10
+ from ..services.utils.exceptions_handler import ServiceException
11
+
12
+ router = APIRouter(tags=["Endpoint"])
13
+
14
+
15
+ @router.post("/api/v1/llm-endpoints")
16
+ @inject
17
+ def add_new_endpoint(
18
+ endpoint_data: EndpointCreateDTO,
19
+ endpoint_service: EndpointService = Depends(Provide[Container.endpoint_service]),
20
+ ) -> dict[str, str] | tuple[dict[str, str], int]:
21
+ """
22
+ Add a new endpoint to the database.
23
+
24
+ Args:
25
+ endpoint_data (EndpointCreateDTO): The data transfer object containing endpoint details.
26
+ endpoint_service (EndpointService): The service responsible for adding the endpoint.
27
+
28
+ Returns:
29
+ dict[str, str]: A message indicating the successful addition of the endpoint.
30
+
31
+ Raises:
32
+ HTTPException: An error with status code 404 if the file is not found.
33
+ An error with status code 400 if there is a validation error.
34
+ An error with status code 500 for any other server-side error.
35
+ """
36
+ try:
37
+ endpoint_service.add_endpoint(endpoint_data)
38
+ return {"message": "Endpoint added successfully"}
39
+ except ServiceException as e:
40
+ if e.error_code == "FileNotFound":
41
+ raise HTTPException(
42
+ status_code=404, detail=f"Failed to add endpoint: {e.msg}"
43
+ )
44
+ elif e.error_code == "ValidationError":
45
+ raise HTTPException(
46
+ status_code=400, detail=f"Failed to add endpoint: {e.msg}"
47
+ )
48
+ else:
49
+ raise HTTPException(
50
+ status_code=500, detail=f"Failed to add endpoint: {e.msg}"
51
+ )
52
+
53
+
54
+ @router.get("/api/v1/llm-endpoints")
55
+ @inject
56
+ def get_all_endpoints(
57
+ endpoint_service: EndpointService = Depends(Provide[Container.endpoint_service]),
58
+ ) -> list[Optional[EndpointDataModel]]:
59
+ """
60
+ Get all the endpoints from the database.
61
+
62
+ Args:
63
+ endpoint_service (EndpointService): The service responsible for retrieving all endpoints.
64
+
65
+ Returns:
66
+ list[Optional[EndpointDataModel]]: A list of endpoint data models,
67
+ which may contain None if an endpoint is not found.
68
+
69
+ Raises:
70
+ HTTPException: An error with status code 404 if the file is not found.
71
+ An error with status code 400 if there is a validation error.
72
+ An error with status code 500 for any other server-side error.
73
+ """
74
+ try:
75
+ endpoint_models = endpoint_service.get_all_endpoints()
76
+ for endpoint_model in endpoint_models:
77
+ endpoint_model.mask_token()
78
+ return endpoint_models
79
+ except ServiceException as e:
80
+ if e.error_code == "FileNotFound":
81
+ raise HTTPException(
82
+ status_code=404, detail=f"Failed to get endpoint: {e.msg}"
83
+ )
84
+ elif e.error_code == "ValidationError":
85
+ raise HTTPException(
86
+ status_code=400, detail=f"Failed to get endpoint: {e.msg}"
87
+ )
88
+ else:
89
+ raise HTTPException(
90
+ status_code=500, detail=f"Failed to get endpoint: {e.msg}"
91
+ )
92
+
93
+
94
+ @router.get("/api/v1/llm-endpoints/name")
95
+ @inject
96
+ def get_all_endpoints_name(
97
+ endpoint_service: EndpointService = Depends(Provide[Container.endpoint_service]),
98
+ ) -> list[Optional[str]]:
99
+ """
100
+ Get all the endpoint names from the database.
101
+
102
+ Args:
103
+ endpoint_service (EndpointService): The service responsible for retrieving all endpoint names.
104
+
105
+ Returns:
106
+ list[Optional[str]]: A list of endpoint names, which may contain None if an endpoint name is not found.
107
+
108
+ Raises:
109
+ HTTPException: An error with status code 404 if the file is not found.
110
+ An error with status code 400 if there is a validation error.
111
+ An error with status code 500 for any other server-side error.
112
+ """
113
+ try:
114
+ return endpoint_service.get_all_endpoints_names()
115
+ except ServiceException as e:
116
+ error_status_code = 500
117
+ if e.error_code == "FileNotFound":
118
+ error_status_code = 404
119
+ elif e.error_code == "ValidationError":
120
+ error_status_code = 400
121
+ raise HTTPException(
122
+ status_code=error_status_code,
123
+ detail=f"Failed to get endpoint names: {e.msg}",
124
+ )
125
+
126
+
127
+ @router.get("/api/v1/llm-endpoints/{endpoint_id}")
128
+ @inject
129
+ def get_endpoint(
130
+ endpoint_id: str,
131
+ endpoint_service: EndpointService = Depends(Provide[Container.endpoint_service]),
132
+ ) -> EndpointDataModel | None:
133
+ """
134
+ Get an endpoint from the database by its ID.
135
+
136
+ Args:
137
+ endpoint_id (str): The unique identifier of the endpoint to retrieve.
138
+ endpoint_service (EndpointService): The service responsible for retrieving the endpoint.
139
+
140
+ Returns:
141
+ EndpointDataModel | None: The endpoint data model if found, otherwise None.
142
+
143
+ Raises:
144
+ HTTPException: An error with status code 404 if the endpoint is not found.
145
+ An error with status code 400 if there is a validation error.
146
+ An error with status code 500 for any other server-side error.
147
+ """
148
+ try:
149
+ endpoint_model = endpoint_service.get_endpoint(endpoint_id)
150
+ if endpoint_model:
151
+ endpoint_model.mask_token()
152
+ return endpoint_model
153
+ except ServiceException as e:
154
+ if e.error_code == "FileNotFound":
155
+ raise HTTPException(
156
+ status_code=404, detail=f"Failed to get endpoint: {e.msg}"
157
+ )
158
+ elif e.error_code == "ValidationError":
159
+ raise HTTPException(
160
+ status_code=400, detail=f"Failed to get endpoint: {e.msg}"
161
+ )
162
+ else:
163
+ raise HTTPException(
164
+ status_code=500, detail=f"Failed to get endpoint: {e.msg}"
165
+ )
166
+
167
+
168
+ @router.put("/api/v1/llm-endpoints/{endpoint_id}")
169
+ @inject
170
+ async def update_endpoint(
171
+ endpoint_id: str,
172
+ endpoint_data: EndpointUpdateDTO,
173
+ endpoint_service: EndpointService = Depends(Provide[Container.endpoint_service]),
174
+ ) -> dict[str, str] | tuple[dict[str, str], int]:
175
+ """
176
+ Update an existing endpoint in the database by its ID.
177
+
178
+ Args:
179
+ endpoint_id (str): The unique identifier of the endpoint to update.
180
+ endpoint_data (EndpointCreateDTO): The data transfer object containing the updated endpoint details.
181
+ endpoint_service (EndpointService): The service responsible for updating the endpoint.
182
+
183
+ Returns:
184
+ dict[str, str]: A message indicating the successful update of the endpoint.
185
+
186
+ Raises:
187
+ HTTPException: An error with status code 404 if the endpoint is not found.
188
+ An error with status code 400 if there is a validation error.
189
+ An error with status code 500 for any other server-side error.
190
+ """
191
+ try:
192
+ endpoint_service.update_endpoint(endpoint_id, endpoint_data)
193
+ return {"message": "Endpoint updated successfully"}
194
+ except ServiceException as e:
195
+ if e.error_code == "FileNotFound":
196
+ raise HTTPException(
197
+ status_code=404, detail=f"Failed to update endpoint: {e.msg}"
198
+ )
199
+ elif e.error_code == "ValidationError":
200
+ raise HTTPException(
201
+ status_code=400, detail=f"Failed to update endpoint: {e.msg}"
202
+ )
203
+ else:
204
+ raise HTTPException(
205
+ status_code=500, detail=f"Failed to update endpoint: {e.msg}"
206
+ )
207
+
208
+
209
+ @router.delete("/api/v1/llm-endpoints/{endpoint_id}")
210
+ @inject
211
+ async def delete_endpoint(
212
+ endpoint_id: str,
213
+ endpoint_service: EndpointService = Depends(Provide[Container.endpoint_service]),
214
+ ) -> dict[str, str] | tuple[dict[str, str], int]:
215
+ """
216
+ Delete an existing endpoint from the database by its ID.
217
+
218
+ Args:
219
+ endpoint_id (str): The unique identifier of the endpoint to delete.
220
+ endpoint_service (EndpointService): The service responsible for deleting the endpoint.
221
+
222
+ Returns:
223
+ dict[str, str]: A message indicating the successful deletion of the endpoint.
224
+
225
+ Raises:
226
+ HTTPException: An error with status code 404 if the endpoint is not found.
227
+ An error with status code 400 if there is a validation error.
228
+ An error with status code 500 for any other server-side error.
229
+ """
230
+ try:
231
+ endpoint_service.delete_endpoint(endpoint_id)
232
+ return {"message": "Endpoint deleted successfully"}
233
+ except ServiceException as e:
234
+ if e.error_code == "FileNotFound":
235
+ raise HTTPException(
236
+ status_code=404, detail=f"Failed to delete endpoint: {e.msg}"
237
+ )
238
+ elif e.error_code == "ValidationError":
239
+ raise HTTPException(
240
+ status_code=400, detail=f"Failed to delete endpoint: {e.msg}"
241
+ )
242
+ else:
243
+ raise HTTPException(
244
+ status_code=500, detail=f"Failed to delete endpoint: {e.msg}"
245
+ )
246
+
247
+
248
+ @router.get("/api/v1/connectors")
249
+ @inject
250
+ def get_all_connectors(
251
+ endpoint_service: EndpointService = Depends(Provide[Container.endpoint_service]),
252
+ ) -> list[Optional[str]]:
253
+ """
254
+ Get all the connector types from the database.
255
+
256
+ Args:
257
+ endpoint_service (EndpointService): The service responsible for retrieving all connector types.
258
+
259
+ Returns:
260
+ list[Optional[str]]: A list of connector types, which may contain None if a connector type is not found.
261
+
262
+ Raises:
263
+ HTTPException: An error with status code 404 if the file is not found.
264
+ An error with status code 400 if there is a validation error.
265
+ An error with status code 500 for any other server-side error.
266
+ """
267
+ # TODO - type check and model validation
268
+ try:
269
+ return endpoint_service.get_all_connectors()
270
+ except ServiceException as e:
271
+ if e.error_code == "FileNotFound":
272
+ raise HTTPException(
273
+ status_code=404, detail=f"Failed to get connector types: {e.msg}"
274
+ )
275
+ elif e.error_code == "ValidationError":
276
+ raise HTTPException(
277
+ status_code=400, detail=f"Failed to get connector types: {e.msg}"
278
+ )
279
+ else:
280
+ raise HTTPException(
281
+ status_code=500, detail=f"Failed to get connector types: {e.msg}"
282
+ )
@@ -0,0 +1,78 @@
1
+ from dependency_injector.wiring import Provide, inject
2
+ from fastapi import APIRouter, Depends, HTTPException
3
+
4
+ from ..container import Container
5
+ from ..services.metric_service import MetricService
6
+ from ..services.utils.exceptions_handler import ServiceException
7
+
8
+ router = APIRouter(tags=["Metric"])
9
+
10
+
11
+ @router.get("/api/v1/metrics")
12
+ @inject
13
+ def get_all_metrics(
14
+ metric_service: MetricService = Depends(Provide[Container.metric_service]),
15
+ ) -> list[dict]:
16
+ """
17
+ Retrieve all metrics from the database.
18
+
19
+ Args:
20
+ metric_service (MetricService): The service responsible for retrieving metrics.
21
+
22
+ Returns:
23
+ list[str]: A list of all metrics.
24
+
25
+ Raises:
26
+ HTTPException: An error with status code 404 if no metrics are found.
27
+ An error with status code 400 if there is a validation error.
28
+ An error with status code 500 for any other server-side error.
29
+ """
30
+ try:
31
+ return metric_service.get_all_metric()
32
+ except ServiceException as e:
33
+ if e.error_code == "FileNotFound":
34
+ raise HTTPException(status_code=404, detail=e.msg)
35
+ elif e.error_code == "ValidationError":
36
+ raise HTTPException(status_code=400, detail=e.msg)
37
+ else:
38
+ raise HTTPException(status_code=500, detail=e.msg)
39
+
40
+
41
+ @router.delete("/api/v1/metrics/{metric_id}")
42
+ @inject
43
+ def delete_metric(
44
+ metric_id: str,
45
+ metric_service: MetricService = Depends(Provide[Container.metric_service]),
46
+ ) -> dict[str, str] | tuple[dict[str, str], int]:
47
+ """
48
+ Delete a metric from the database by its ID.
49
+
50
+ Args:
51
+ metric_id (str): The unique identifier of the metric to delete.
52
+ metric_service (MetricService): The service responsible for deleting the metric.
53
+
54
+ Returns:
55
+ dict[str, str] | tuple[dict[str, str], int]: A message indicating the successful deletion of the metric,
56
+ or an HTTPException with an appropriate status code.
57
+
58
+ Raises:
59
+ HTTPException: An error with status code 404 if the metric is not found.
60
+ An error with status code 400 if there is a validation error.
61
+ An error with status code 500 for any other server-side error.
62
+ """
63
+ try:
64
+ metric_service.delete_metric(metric_id)
65
+ return {"message": "Metric deleted successfully"}
66
+ except ServiceException as e:
67
+ if e.error_code == "FileNotFound":
68
+ raise HTTPException(
69
+ status_code=404, detail=f"Failed to delete metric: {e.msg}"
70
+ )
71
+ elif e.error_code == "ValidationError":
72
+ raise HTTPException(
73
+ status_code=400, detail=f"Failed to delete metric: {e.msg}"
74
+ )
75
+ else:
76
+ raise HTTPException(
77
+ status_code=500, detail=f"Failed to delete metric: {e.msg}"
78
+ )
@@ -0,0 +1,128 @@
1
+ from dependency_injector.wiring import Provide, inject
2
+ from fastapi import APIRouter, Depends, HTTPException
3
+
4
+ from ..container import Container
5
+ from ..schemas.prompt_template_response_model import PromptTemplatesResponseModel
6
+ from ..services.prompt_template_service import PromptTemplateService
7
+ from ..services.utils.exceptions_handler import ServiceException
8
+
9
+ router = APIRouter(tags=["Prompt Template"])
10
+
11
+
12
+ @router.get("/api/v1/prompt-templates")
13
+ @inject
14
+ def get_all_prompt_templates(
15
+ prompt_template_service: PromptTemplateService = Depends(
16
+ Provide[Container.prompt_template_service]
17
+ ),
18
+ ) -> PromptTemplatesResponseModel:
19
+ """
20
+ Retrieve all prompt templates from the database.
21
+
22
+ Args:
23
+ prompt_template_service (PromptTemplateService): The service responsible for retrieving prompt templates.
24
+
25
+ Returns:
26
+ PromptTemplatesResponseModel: A model representing all prompt templates.
27
+
28
+ Raises:
29
+ HTTPException: An error with status code 404 if no prompt templates are found.
30
+ An error with status code 400 if there is a validation error.
31
+ An error with status code 500 for any other server-side error.
32
+ """
33
+ try:
34
+ return prompt_template_service.get_prompt_templates()
35
+ except ServiceException as e:
36
+ if e.error_code == "FileNotFound":
37
+ raise HTTPException(
38
+ status_code=404, detail=f"Failed to retrieve prompt templates: {e.msg}"
39
+ )
40
+ elif e.error_code == "ValidationError":
41
+ raise HTTPException(
42
+ status_code=400, detail=f"Failed to retrieve prompt templates: {e.msg}"
43
+ )
44
+ else:
45
+ raise HTTPException(
46
+ status_code=500, detail=f"Failed to retrieve prompt templates: {e.msg}"
47
+ )
48
+
49
+
50
+ @router.get("/api/v1/prompt-templates/name")
51
+ @inject
52
+ def get_all_prompt_templates_names(
53
+ prompt_template_service: PromptTemplateService = Depends(
54
+ Provide[Container.prompt_template_service]
55
+ ),
56
+ ) -> list[str]:
57
+ """
58
+ Retrieve the names of all prompt templates from the database.
59
+
60
+ Args:
61
+ prompt_template_service (PromptTemplateService): The service responsible for retrieving prompt template names.
62
+
63
+ Returns:
64
+ list[str]: A list of prompt template names.
65
+
66
+ Raises:
67
+ HTTPException: An error with status code 404 if no prompt template names are found.
68
+ An error with status code 400 if there is a validation error.
69
+ An error with status code 500 for any other server-side error.
70
+ """
71
+ try:
72
+ return prompt_template_service.get_prompt_templates_name()
73
+ except ServiceException as e:
74
+ if e.error_code == "FileNotFound":
75
+ raise HTTPException(
76
+ status_code=404,
77
+ detail=f"Failed to retrieve prompt template names: {e.msg}",
78
+ )
79
+ elif e.error_code == "ValidationError":
80
+ raise HTTPException(
81
+ status_code=400,
82
+ detail=f"Failed to retrieve prompt template names: {e.msg}",
83
+ )
84
+ else:
85
+ raise HTTPException(
86
+ status_code=500,
87
+ detail=f"Failed to retrieve prompt template names: {e.msg}",
88
+ )
89
+
90
+ @router.delete("/api/v1/prompt-templates/{prompt_template_name}")
91
+ @inject
92
+ def delete_prompt_template(
93
+ prompt_template_name: str,
94
+ prompt_template_service: PromptTemplateService = Depends(
95
+ Provide[Container.prompt_template_service]
96
+ ),
97
+ ) -> dict[str, bool]:
98
+ """
99
+ Delete a prompt template from the database by its name.
100
+
101
+ Args:
102
+ prompt_template_name (str): The name of the prompt template to delete.
103
+ prompt_template_service (PromptTemplateService): The service responsible for deleting the prompt template.
104
+
105
+ Returns:
106
+ dict[str, bool]: A dictionary with a key 'success' indicating the result of the deletion operation.
107
+
108
+ Raises:
109
+ HTTPException: An error with status code 404 if the prompt template is not found.
110
+ An error with status code 400 if there is a validation error.
111
+ An error with status code 500 for any other server-side error.
112
+ """
113
+ try:
114
+ prompt_template_service.delete_prompt_template(prompt_template_name)
115
+ return {"success": True}
116
+ except ServiceException as e:
117
+ if e.error_code == "FileNotFound":
118
+ raise HTTPException(
119
+ status_code=404, detail=f"Failed to delete prompt template: {e.msg}"
120
+ )
121
+ elif e.error_code == "ValidationError":
122
+ raise HTTPException(
123
+ status_code=400, detail=f"Failed to delete prompt template: {e.msg}"
124
+ )
125
+ else:
126
+ raise HTTPException(
127
+ status_code=500, detail=f"Failed to delete prompt template: {e.msg}"
128
+ )