arize-phoenix 11.23.1__py3-none-any.whl → 12.28.1__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.
- {arize_phoenix-11.23.1.dist-info → arize_phoenix-12.28.1.dist-info}/METADATA +61 -36
- {arize_phoenix-11.23.1.dist-info → arize_phoenix-12.28.1.dist-info}/RECORD +212 -162
- {arize_phoenix-11.23.1.dist-info → arize_phoenix-12.28.1.dist-info}/WHEEL +1 -1
- {arize_phoenix-11.23.1.dist-info → arize_phoenix-12.28.1.dist-info}/licenses/IP_NOTICE +1 -1
- phoenix/__generated__/__init__.py +0 -0
- phoenix/__generated__/classification_evaluator_configs/__init__.py +20 -0
- phoenix/__generated__/classification_evaluator_configs/_document_relevance_classification_evaluator_config.py +17 -0
- phoenix/__generated__/classification_evaluator_configs/_hallucination_classification_evaluator_config.py +17 -0
- phoenix/__generated__/classification_evaluator_configs/_models.py +18 -0
- phoenix/__generated__/classification_evaluator_configs/_tool_selection_classification_evaluator_config.py +17 -0
- phoenix/__init__.py +2 -1
- phoenix/auth.py +27 -2
- phoenix/config.py +1594 -81
- phoenix/db/README.md +546 -28
- phoenix/db/bulk_inserter.py +119 -116
- phoenix/db/engines.py +140 -33
- phoenix/db/facilitator.py +22 -1
- phoenix/db/helpers.py +818 -65
- phoenix/db/iam_auth.py +64 -0
- phoenix/db/insertion/dataset.py +133 -1
- phoenix/db/insertion/document_annotation.py +9 -6
- phoenix/db/insertion/evaluation.py +2 -3
- phoenix/db/insertion/helpers.py +2 -2
- phoenix/db/insertion/session_annotation.py +176 -0
- phoenix/db/insertion/span_annotation.py +3 -4
- phoenix/db/insertion/trace_annotation.py +3 -4
- phoenix/db/insertion/types.py +41 -18
- phoenix/db/migrations/versions/01a8342c9cdf_add_user_id_on_datasets.py +40 -0
- phoenix/db/migrations/versions/0df286449799_add_session_annotations_table.py +105 -0
- phoenix/db/migrations/versions/272b66ff50f8_drop_single_indices.py +119 -0
- phoenix/db/migrations/versions/58228d933c91_dataset_labels.py +67 -0
- phoenix/db/migrations/versions/699f655af132_experiment_tags.py +57 -0
- phoenix/db/migrations/versions/735d3d93c33e_add_composite_indices.py +41 -0
- phoenix/db/migrations/versions/ab513d89518b_add_user_id_on_dataset_versions.py +40 -0
- phoenix/db/migrations/versions/d0690a79ea51_users_on_experiments.py +40 -0
- phoenix/db/migrations/versions/deb2c81c0bb2_dataset_splits.py +139 -0
- phoenix/db/migrations/versions/e76cbd66ffc3_add_experiments_dataset_examples.py +87 -0
- phoenix/db/models.py +364 -56
- phoenix/db/pg_config.py +10 -0
- phoenix/db/types/trace_retention.py +7 -6
- phoenix/experiments/functions.py +69 -19
- phoenix/inferences/inferences.py +1 -2
- phoenix/server/api/auth.py +9 -0
- phoenix/server/api/auth_messages.py +46 -0
- phoenix/server/api/context.py +60 -0
- phoenix/server/api/dataloaders/__init__.py +36 -0
- phoenix/server/api/dataloaders/annotation_summaries.py +60 -8
- phoenix/server/api/dataloaders/average_experiment_repeated_run_group_latency.py +50 -0
- phoenix/server/api/dataloaders/average_experiment_run_latency.py +17 -24
- phoenix/server/api/dataloaders/cache/two_tier_cache.py +1 -2
- phoenix/server/api/dataloaders/dataset_dataset_splits.py +52 -0
- phoenix/server/api/dataloaders/dataset_example_revisions.py +0 -1
- phoenix/server/api/dataloaders/dataset_example_splits.py +40 -0
- phoenix/server/api/dataloaders/dataset_examples_and_versions_by_experiment_run.py +47 -0
- phoenix/server/api/dataloaders/dataset_labels.py +36 -0
- phoenix/server/api/dataloaders/document_evaluation_summaries.py +2 -2
- phoenix/server/api/dataloaders/document_evaluations.py +6 -9
- phoenix/server/api/dataloaders/experiment_annotation_summaries.py +88 -34
- phoenix/server/api/dataloaders/experiment_dataset_splits.py +43 -0
- phoenix/server/api/dataloaders/experiment_error_rates.py +21 -28
- phoenix/server/api/dataloaders/experiment_repeated_run_group_annotation_summaries.py +77 -0
- phoenix/server/api/dataloaders/experiment_repeated_run_groups.py +57 -0
- phoenix/server/api/dataloaders/experiment_runs_by_experiment_and_example.py +44 -0
- phoenix/server/api/dataloaders/latency_ms_quantile.py +40 -8
- phoenix/server/api/dataloaders/record_counts.py +37 -10
- phoenix/server/api/dataloaders/session_annotations_by_session.py +29 -0
- phoenix/server/api/dataloaders/span_cost_summary_by_experiment_repeated_run_group.py +64 -0
- phoenix/server/api/dataloaders/span_cost_summary_by_project.py +28 -14
- phoenix/server/api/dataloaders/span_costs.py +3 -9
- phoenix/server/api/dataloaders/table_fields.py +2 -2
- phoenix/server/api/dataloaders/token_prices_by_model.py +30 -0
- phoenix/server/api/dataloaders/trace_annotations_by_trace.py +27 -0
- phoenix/server/api/exceptions.py +5 -1
- phoenix/server/api/helpers/playground_clients.py +263 -83
- phoenix/server/api/helpers/playground_spans.py +2 -1
- phoenix/server/api/helpers/playground_users.py +26 -0
- phoenix/server/api/helpers/prompts/conversions/google.py +103 -0
- phoenix/server/api/helpers/prompts/models.py +61 -19
- phoenix/server/api/input_types/{SpanAnnotationFilter.py → AnnotationFilter.py} +22 -14
- phoenix/server/api/input_types/ChatCompletionInput.py +3 -0
- phoenix/server/api/input_types/CreateProjectSessionAnnotationInput.py +37 -0
- phoenix/server/api/input_types/DatasetFilter.py +5 -2
- phoenix/server/api/input_types/ExperimentRunSort.py +237 -0
- phoenix/server/api/input_types/GenerativeModelInput.py +3 -0
- phoenix/server/api/input_types/ProjectSessionSort.py +158 -1
- phoenix/server/api/input_types/PromptVersionInput.py +47 -1
- phoenix/server/api/input_types/SpanSort.py +3 -2
- phoenix/server/api/input_types/UpdateAnnotationInput.py +34 -0
- phoenix/server/api/input_types/UserRoleInput.py +1 -0
- phoenix/server/api/mutations/__init__.py +8 -0
- phoenix/server/api/mutations/annotation_config_mutations.py +8 -8
- phoenix/server/api/mutations/api_key_mutations.py +15 -20
- phoenix/server/api/mutations/chat_mutations.py +106 -37
- phoenix/server/api/mutations/dataset_label_mutations.py +243 -0
- phoenix/server/api/mutations/dataset_mutations.py +21 -16
- phoenix/server/api/mutations/dataset_split_mutations.py +351 -0
- phoenix/server/api/mutations/experiment_mutations.py +2 -2
- phoenix/server/api/mutations/export_events_mutations.py +3 -3
- phoenix/server/api/mutations/model_mutations.py +11 -9
- phoenix/server/api/mutations/project_mutations.py +4 -4
- phoenix/server/api/mutations/project_session_annotations_mutations.py +158 -0
- phoenix/server/api/mutations/project_trace_retention_policy_mutations.py +8 -4
- phoenix/server/api/mutations/prompt_label_mutations.py +74 -65
- phoenix/server/api/mutations/prompt_mutations.py +65 -129
- phoenix/server/api/mutations/prompt_version_tag_mutations.py +11 -8
- phoenix/server/api/mutations/span_annotations_mutations.py +15 -10
- phoenix/server/api/mutations/trace_annotations_mutations.py +13 -8
- phoenix/server/api/mutations/trace_mutations.py +3 -3
- phoenix/server/api/mutations/user_mutations.py +55 -26
- phoenix/server/api/queries.py +501 -617
- phoenix/server/api/routers/__init__.py +2 -2
- phoenix/server/api/routers/auth.py +141 -87
- phoenix/server/api/routers/ldap.py +229 -0
- phoenix/server/api/routers/oauth2.py +349 -101
- phoenix/server/api/routers/v1/__init__.py +22 -4
- phoenix/server/api/routers/v1/annotation_configs.py +19 -30
- phoenix/server/api/routers/v1/annotations.py +455 -13
- phoenix/server/api/routers/v1/datasets.py +355 -68
- phoenix/server/api/routers/v1/documents.py +142 -0
- phoenix/server/api/routers/v1/evaluations.py +20 -28
- phoenix/server/api/routers/v1/experiment_evaluations.py +16 -6
- phoenix/server/api/routers/v1/experiment_runs.py +335 -59
- phoenix/server/api/routers/v1/experiments.py +475 -47
- phoenix/server/api/routers/v1/projects.py +16 -50
- phoenix/server/api/routers/v1/prompts.py +50 -39
- phoenix/server/api/routers/v1/sessions.py +108 -0
- phoenix/server/api/routers/v1/spans.py +156 -96
- phoenix/server/api/routers/v1/traces.py +51 -77
- phoenix/server/api/routers/v1/users.py +64 -24
- phoenix/server/api/routers/v1/utils.py +3 -7
- phoenix/server/api/subscriptions.py +257 -93
- phoenix/server/api/types/Annotation.py +90 -23
- phoenix/server/api/types/ApiKey.py +13 -17
- phoenix/server/api/types/AuthMethod.py +1 -0
- phoenix/server/api/types/ChatCompletionSubscriptionPayload.py +1 -0
- phoenix/server/api/types/Dataset.py +199 -72
- phoenix/server/api/types/DatasetExample.py +88 -18
- phoenix/server/api/types/DatasetExperimentAnnotationSummary.py +10 -0
- phoenix/server/api/types/DatasetLabel.py +57 -0
- phoenix/server/api/types/DatasetSplit.py +98 -0
- phoenix/server/api/types/DatasetVersion.py +49 -4
- phoenix/server/api/types/DocumentAnnotation.py +212 -0
- phoenix/server/api/types/Experiment.py +215 -68
- phoenix/server/api/types/ExperimentComparison.py +3 -9
- phoenix/server/api/types/ExperimentRepeatedRunGroup.py +155 -0
- phoenix/server/api/types/ExperimentRepeatedRunGroupAnnotationSummary.py +9 -0
- phoenix/server/api/types/ExperimentRun.py +120 -70
- phoenix/server/api/types/ExperimentRunAnnotation.py +158 -39
- phoenix/server/api/types/GenerativeModel.py +95 -42
- phoenix/server/api/types/GenerativeProvider.py +1 -1
- phoenix/server/api/types/ModelInterface.py +7 -2
- phoenix/server/api/types/PlaygroundModel.py +12 -2
- phoenix/server/api/types/Project.py +218 -185
- phoenix/server/api/types/ProjectSession.py +146 -29
- phoenix/server/api/types/ProjectSessionAnnotation.py +187 -0
- phoenix/server/api/types/ProjectTraceRetentionPolicy.py +1 -1
- phoenix/server/api/types/Prompt.py +119 -39
- phoenix/server/api/types/PromptLabel.py +42 -25
- phoenix/server/api/types/PromptVersion.py +11 -8
- phoenix/server/api/types/PromptVersionTag.py +65 -25
- phoenix/server/api/types/Span.py +130 -123
- phoenix/server/api/types/SpanAnnotation.py +189 -42
- phoenix/server/api/types/SystemApiKey.py +65 -1
- phoenix/server/api/types/Trace.py +184 -53
- phoenix/server/api/types/TraceAnnotation.py +149 -50
- phoenix/server/api/types/User.py +128 -33
- phoenix/server/api/types/UserApiKey.py +73 -26
- phoenix/server/api/types/node.py +10 -0
- phoenix/server/api/types/pagination.py +11 -2
- phoenix/server/app.py +154 -36
- phoenix/server/authorization.py +5 -4
- phoenix/server/bearer_auth.py +13 -5
- phoenix/server/cost_tracking/cost_model_lookup.py +42 -14
- phoenix/server/cost_tracking/model_cost_manifest.json +1085 -194
- phoenix/server/daemons/generative_model_store.py +61 -9
- phoenix/server/daemons/span_cost_calculator.py +10 -8
- phoenix/server/dml_event.py +13 -0
- phoenix/server/email/sender.py +29 -2
- phoenix/server/grpc_server.py +9 -9
- phoenix/server/jwt_store.py +8 -6
- phoenix/server/ldap.py +1449 -0
- phoenix/server/main.py +9 -3
- phoenix/server/oauth2.py +330 -12
- phoenix/server/prometheus.py +43 -6
- phoenix/server/rate_limiters.py +4 -9
- phoenix/server/retention.py +33 -20
- phoenix/server/session_filters.py +49 -0
- phoenix/server/static/.vite/manifest.json +51 -53
- phoenix/server/static/assets/components-BreFUQQa.js +6702 -0
- phoenix/server/static/assets/{index-BPCwGQr8.js → index-CTQoemZv.js} +42 -35
- phoenix/server/static/assets/pages-DBE5iYM3.js +9524 -0
- phoenix/server/static/assets/vendor-BGzfc4EU.css +1 -0
- phoenix/server/static/assets/vendor-DCE4v-Ot.js +920 -0
- phoenix/server/static/assets/vendor-codemirror-D5f205eT.js +25 -0
- phoenix/server/static/assets/{vendor-recharts-Bw30oz1A.js → vendor-recharts-V9cwpXsm.js} +7 -7
- phoenix/server/static/assets/{vendor-shiki-DZajAPeq.js → vendor-shiki-Do--csgv.js} +1 -1
- phoenix/server/static/assets/vendor-three-CmB8bl_y.js +3840 -0
- phoenix/server/templates/index.html +7 -1
- phoenix/server/thread_server.py +1 -2
- phoenix/server/utils.py +74 -0
- phoenix/session/client.py +55 -1
- phoenix/session/data_extractor.py +5 -0
- phoenix/session/evaluation.py +8 -4
- phoenix/session/session.py +44 -8
- phoenix/settings.py +2 -0
- phoenix/trace/attributes.py +80 -13
- phoenix/trace/dsl/query.py +2 -0
- phoenix/trace/projects.py +5 -0
- phoenix/utilities/template_formatters.py +1 -1
- phoenix/version.py +1 -1
- phoenix/server/api/types/Evaluation.py +0 -39
- phoenix/server/static/assets/components-D0DWAf0l.js +0 -5650
- phoenix/server/static/assets/pages-Creyamao.js +0 -8612
- phoenix/server/static/assets/vendor-CU36oj8y.js +0 -905
- phoenix/server/static/assets/vendor-CqDb5u4o.css +0 -1
- phoenix/server/static/assets/vendor-arizeai-Ctgw0e1G.js +0 -168
- phoenix/server/static/assets/vendor-codemirror-Cojjzqb9.js +0 -25
- phoenix/server/static/assets/vendor-three-BLWp5bic.js +0 -2998
- phoenix/utilities/deprecation.py +0 -31
- {arize_phoenix-11.23.1.dist-info → arize_phoenix-12.28.1.dist-info}/entry_points.txt +0 -0
- {arize_phoenix-11.23.1.dist-info → arize_phoenix-12.28.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
from fastapi import APIRouter, Depends, HTTPException, Request
|
|
2
2
|
from fastapi.security import APIKeyHeader
|
|
3
|
-
from starlette.status import HTTP_403_FORBIDDEN
|
|
4
3
|
|
|
5
|
-
from phoenix.server.bearer_auth import is_authenticated
|
|
4
|
+
from phoenix.server.bearer_auth import PhoenixUser, is_authenticated
|
|
6
5
|
|
|
7
6
|
from .annotation_configs import router as annotation_configs_router
|
|
8
7
|
from .annotations import router as annotations_router
|
|
9
8
|
from .datasets import router as datasets_router
|
|
9
|
+
from .documents import router as documents_router
|
|
10
10
|
from .evaluations import router as evaluations_router
|
|
11
11
|
from .experiment_evaluations import router as experiment_evaluations_router
|
|
12
12
|
from .experiment_runs import router as experiment_runs_router
|
|
13
13
|
from .experiments import router as experiments_router
|
|
14
14
|
from .projects import router as projects_router
|
|
15
15
|
from .prompts import router as prompts_router
|
|
16
|
+
from .sessions import router as sessions_router
|
|
16
17
|
from .spans import router as spans_router
|
|
17
18
|
from .traces import router as traces_router
|
|
18
19
|
from .users import router as users_router
|
|
@@ -28,7 +29,21 @@ async def prevent_access_in_read_only_mode(request: Request) -> None:
|
|
|
28
29
|
if request.app.state.read_only:
|
|
29
30
|
raise HTTPException(
|
|
30
31
|
detail="The Phoenix REST API is disabled in read-only mode.",
|
|
31
|
-
status_code=
|
|
32
|
+
status_code=403,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
async def restrict_access_by_viewers(request: Request) -> None:
|
|
37
|
+
"""
|
|
38
|
+
Prevents access to the REST API for viewers, except for GET requests
|
|
39
|
+
and specific allowed POST routes.
|
|
40
|
+
"""
|
|
41
|
+
if request.method == "GET":
|
|
42
|
+
return
|
|
43
|
+
if isinstance(request.user, PhoenixUser) and request.user.is_viewer:
|
|
44
|
+
raise HTTPException(
|
|
45
|
+
status_code=403,
|
|
46
|
+
detail="Viewers cannot perform this action.",
|
|
32
47
|
)
|
|
33
48
|
|
|
34
49
|
|
|
@@ -49,13 +64,14 @@ def create_v1_router(authentication_enabled: bool) -> APIRouter:
|
|
|
49
64
|
)
|
|
50
65
|
)
|
|
51
66
|
dependencies.append(Depends(is_authenticated))
|
|
67
|
+
dependencies.append(Depends(restrict_access_by_viewers))
|
|
52
68
|
|
|
53
69
|
router = APIRouter(
|
|
54
70
|
prefix="/v1",
|
|
55
71
|
dependencies=dependencies,
|
|
56
72
|
responses=add_errors_to_responses(
|
|
57
73
|
[
|
|
58
|
-
|
|
74
|
+
403 # adds a 403 response to routes in the generated OpenAPI schema
|
|
59
75
|
]
|
|
60
76
|
),
|
|
61
77
|
)
|
|
@@ -70,5 +86,7 @@ def create_v1_router(authentication_enabled: bool) -> APIRouter:
|
|
|
70
86
|
router.include_router(evaluations_router)
|
|
71
87
|
router.include_router(prompts_router)
|
|
72
88
|
router.include_router(projects_router)
|
|
89
|
+
router.include_router(sessions_router)
|
|
90
|
+
router.include_router(documents_router)
|
|
73
91
|
router.include_router(users_router)
|
|
74
92
|
return router
|
|
@@ -7,11 +7,6 @@ from sqlalchemy import delete, select
|
|
|
7
7
|
from sqlalchemy.exc import IntegrityError as PostgreSQLIntegrityError
|
|
8
8
|
from sqlean.dbapi2 import IntegrityError as SQLiteIntegrityError # type: ignore[import-untyped]
|
|
9
9
|
from starlette.requests import Request
|
|
10
|
-
from starlette.status import (
|
|
11
|
-
HTTP_400_BAD_REQUEST,
|
|
12
|
-
HTTP_404_NOT_FOUND,
|
|
13
|
-
HTTP_409_CONFLICT,
|
|
14
|
-
)
|
|
15
10
|
from strawberry.relay import GlobalID
|
|
16
11
|
from typing_extensions import TypeAlias, assert_never
|
|
17
12
|
|
|
@@ -206,7 +201,7 @@ async def list_annotation_configs(
|
|
|
206
201
|
except ValueError:
|
|
207
202
|
raise HTTPException(
|
|
208
203
|
detail=f"Invalid cursor: {cursor}",
|
|
209
|
-
status_code=
|
|
204
|
+
status_code=400,
|
|
210
205
|
)
|
|
211
206
|
if cursor_gid.type_name not in (
|
|
212
207
|
CategoricalAnnotationConfigType.__name__,
|
|
@@ -215,7 +210,7 @@ async def list_annotation_configs(
|
|
|
215
210
|
):
|
|
216
211
|
raise HTTPException(
|
|
217
212
|
detail=f"Invalid cursor: {cursor}",
|
|
218
|
-
status_code=
|
|
213
|
+
status_code=400,
|
|
219
214
|
)
|
|
220
215
|
cursor_id = int(cursor_gid.node_id)
|
|
221
216
|
|
|
@@ -261,9 +256,7 @@ async def get_annotation_config_by_name_or_id(
|
|
|
261
256
|
query = query.where(models.AnnotationConfig.name == config_identifier)
|
|
262
257
|
config = await session.scalar(query)
|
|
263
258
|
if not config:
|
|
264
|
-
raise HTTPException(
|
|
265
|
-
status_code=HTTP_404_NOT_FOUND, detail="Annotation configuration not found"
|
|
266
|
-
)
|
|
259
|
+
raise HTTPException(status_code=404, detail="Annotation configuration not found")
|
|
267
260
|
return GetAnnotationConfigResponseBody(data=db_to_api_annotation_config(config))
|
|
268
261
|
|
|
269
262
|
|
|
@@ -282,7 +275,7 @@ async def create_annotation_config(
|
|
|
282
275
|
try:
|
|
283
276
|
db_config = _to_db_annotation_config(input_config)
|
|
284
277
|
except ValueError as error:
|
|
285
|
-
raise HTTPException(status_code=
|
|
278
|
+
raise HTTPException(status_code=400, detail=str(error))
|
|
286
279
|
|
|
287
280
|
async with request.app.state.db() as session:
|
|
288
281
|
annotation_config = models.AnnotationConfig(
|
|
@@ -294,7 +287,7 @@ async def create_annotation_config(
|
|
|
294
287
|
await session.commit()
|
|
295
288
|
except (PostgreSQLIntegrityError, SQLiteIntegrityError):
|
|
296
289
|
raise HTTPException(
|
|
297
|
-
status_code=
|
|
290
|
+
status_code=409,
|
|
298
291
|
detail="The name of the annotation configuration is already taken",
|
|
299
292
|
)
|
|
300
293
|
return CreateAnnotationConfigResponseBody(
|
|
@@ -321,22 +314,18 @@ async def update_annotation_config(
|
|
|
321
314
|
ContinuousAnnotationConfigType.__name__,
|
|
322
315
|
FreeformAnnotationConfigType.__name__,
|
|
323
316
|
):
|
|
324
|
-
raise HTTPException(
|
|
325
|
-
status_code=HTTP_400_BAD_REQUEST, detail="Invalid annotation configuration ID"
|
|
326
|
-
)
|
|
317
|
+
raise HTTPException(status_code=400, detail="Invalid annotation configuration ID")
|
|
327
318
|
config_rowid = int(config_gid.node_id)
|
|
328
319
|
|
|
329
320
|
try:
|
|
330
321
|
db_config = _to_db_annotation_config(input_config)
|
|
331
322
|
except ValueError as error:
|
|
332
|
-
raise HTTPException(status_code=
|
|
323
|
+
raise HTTPException(status_code=400, detail=str(error))
|
|
333
324
|
|
|
334
325
|
async with request.app.state.db() as session:
|
|
335
326
|
existing_config = await session.get(models.AnnotationConfig, config_rowid)
|
|
336
327
|
if not existing_config:
|
|
337
|
-
raise HTTPException(
|
|
338
|
-
status_code=HTTP_404_NOT_FOUND, detail="Annotation configuration not found"
|
|
339
|
-
)
|
|
328
|
+
raise HTTPException(status_code=404, detail="Annotation configuration not found")
|
|
340
329
|
|
|
341
330
|
existing_config.name = input_config.name
|
|
342
331
|
existing_config.config = db_config
|
|
@@ -345,7 +334,7 @@ async def update_annotation_config(
|
|
|
345
334
|
await session.commit()
|
|
346
335
|
except (PostgreSQLIntegrityError, SQLiteIntegrityError):
|
|
347
336
|
raise HTTPException(
|
|
348
|
-
status_code=
|
|
337
|
+
status_code=409,
|
|
349
338
|
detail="The name of the annotation configuration is already taken",
|
|
350
339
|
)
|
|
351
340
|
|
|
@@ -360,15 +349,19 @@ async def delete_annotation_config(
|
|
|
360
349
|
request: Request,
|
|
361
350
|
config_id: str = Path(..., description="ID of the annotation configuration"),
|
|
362
351
|
) -> DeleteAnnotationConfigResponseBody:
|
|
363
|
-
|
|
352
|
+
try:
|
|
353
|
+
config_gid = GlobalID.from_id(config_id)
|
|
354
|
+
except Exception:
|
|
355
|
+
raise HTTPException(
|
|
356
|
+
status_code=422,
|
|
357
|
+
detail=f"Invalid annotation configuration ID format: {config_id}",
|
|
358
|
+
)
|
|
364
359
|
if config_gid.type_name not in (
|
|
365
360
|
CategoricalAnnotationConfigType.__name__,
|
|
366
361
|
ContinuousAnnotationConfigType.__name__,
|
|
367
362
|
FreeformAnnotationConfigType.__name__,
|
|
368
363
|
):
|
|
369
|
-
raise HTTPException(
|
|
370
|
-
status_code=HTTP_400_BAD_REQUEST, detail="Invalid annotation configuration ID"
|
|
371
|
-
)
|
|
364
|
+
raise HTTPException(status_code=400, detail="Invalid annotation configuration ID")
|
|
372
365
|
config_rowid = int(config_gid.node_id)
|
|
373
366
|
async with request.app.state.db() as session:
|
|
374
367
|
stmt = (
|
|
@@ -378,9 +371,7 @@ async def delete_annotation_config(
|
|
|
378
371
|
)
|
|
379
372
|
annotation_config = await session.scalar(stmt)
|
|
380
373
|
if annotation_config is None:
|
|
381
|
-
raise HTTPException(
|
|
382
|
-
status_code=HTTP_404_NOT_FOUND, detail="Annotation configuration not found"
|
|
383
|
-
)
|
|
374
|
+
raise HTTPException(status_code=404, detail="Annotation configuration not found")
|
|
384
375
|
await session.commit()
|
|
385
376
|
return DeleteAnnotationConfigResponseBody(data=db_to_api_annotation_config(annotation_config))
|
|
386
377
|
|
|
@@ -400,9 +391,7 @@ def _get_annotation_config_db_id(config_gid: str) -> int:
|
|
|
400
391
|
def _reserve_note_annotation_name(data: AnnotationConfigData) -> str:
|
|
401
392
|
name = data.name
|
|
402
393
|
if name == "note":
|
|
403
|
-
raise HTTPException(
|
|
404
|
-
status_code=HTTP_409_CONFLICT, detail="The name 'note' is reserved for span notes"
|
|
405
|
-
)
|
|
394
|
+
raise HTTPException(status_code=409, detail="The name 'note' is reserved for span notes")
|
|
406
395
|
return name
|
|
407
396
|
|
|
408
397
|
|