4
4
from sqlalchemy import delete , insert , select
5
5
from starlette .requests import Request
6
6
from strawberry import UNSET , Info
7
+ from strawberry .relay .types import GlobalID
7
8
8
9
from phoenix .db import models
9
10
from phoenix .server .api .auth import IsLocked , IsNotReadOnly
@@ -55,16 +56,13 @@ async def create_trace_annotations(
55
56
56
57
async with info .context .db () as session :
57
58
for idx , (trace_rowid , annotation_input ) in enumerate (zip (trace_rowids , input )):
58
- resolved_identifier = annotation_input .identifier or ""
59
- if annotation_input .source == AnnotationSource .APP :
59
+ resolved_identifier = ""
60
+ if annotation_input .identifier :
61
+ resolved_identifier = annotation_input .identifier
62
+ elif annotation_input .source == AnnotationSource .APP and user_id is not None :
60
63
# Ensure that the annotation has a per-user identifier if submitted via the UI
61
- if user_id is not None :
62
- username = await session .scalar (
63
- select (models .User .username ).where (models .User .id == user_id )
64
- )
65
- resolved_identifier = f"px-app:{ username } "
66
- else :
67
- resolved_identifier = "px-app"
64
+ user_gid = str (GlobalID (type_name = "User" , node_id = str (user_id )))
65
+ resolved_identifier = f"px-app:{ user_gid } "
68
66
values = {
69
67
"trace_rowid" : trace_rowid ,
70
68
"name" : annotation_input .name ,
@@ -84,12 +82,8 @@ async def create_trace_annotations(
84
82
q = select (models .TraceAnnotation ).where (
85
83
models .TraceAnnotation .trace_rowid == trace_rowid ,
86
84
models .TraceAnnotation .name == annotation_input .name ,
85
+ models .TraceAnnotation .identifier == resolved_identifier ,
87
86
)
88
- if resolved_identifier is None :
89
- q = q .where (models .TraceAnnotation .identifier .is_ (None ))
90
- else :
91
- q = q .where (models .TraceAnnotation .identifier == resolved_identifier )
92
-
93
87
existing_annotation = await session .scalar (q )
94
88
95
89
if existing_annotation :
0 commit comments