Skip to content

Commit 1753e74

Browse files
authored
fix(annotations): ensure user identifiers are stable (#7414)
1 parent 999fb2e commit 1753e74

File tree

2 files changed

+16
-28
lines changed

2 files changed

+16
-28
lines changed

src/phoenix/server/api/mutations/span_annotations_mutations.py

+8-14
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from sqlalchemy import delete, insert, select
66
from starlette.requests import Request
77
from strawberry import UNSET, Info
8+
from strawberry.relay import GlobalID
89

910
from phoenix.db import models
1011
from phoenix.server.api.auth import IsLocked, IsNotReadOnly
@@ -62,16 +63,13 @@ async def create_span_annotations(
6263

6364
async with info.context.db() as session:
6465
for idx, (span_rowid, annotation_input) in enumerate(zip(span_rowids, input)):
65-
resolved_identifier = annotation_input.identifier or ""
66-
if annotation_input.source == AnnotationSource.APP:
66+
resolved_identifier = ""
67+
if annotation_input.identifier:
68+
resolved_identifier = annotation_input.identifier
69+
elif annotation_input.source == AnnotationSource.APP and user_id is not None:
6770
# Ensure that the annotation has a per-user identifier if submitted via the UI
68-
if user_id is not None:
69-
username = await session.scalar(
70-
select(models.User.username).where(models.User.id == user_id)
71-
)
72-
resolved_identifier = f"px-app:{username}"
73-
else:
74-
resolved_identifier = "px-app"
71+
user_gid = str(GlobalID(type_name="User", node_id=str(user_id)))
72+
resolved_identifier = f"px-app:{user_gid}"
7573
values = {
7674
"span_rowid": span_rowid,
7775
"name": annotation_input.name,
@@ -90,12 +88,8 @@ async def create_span_annotations(
9088
q = select(models.SpanAnnotation).where(
9189
models.SpanAnnotation.span_rowid == span_rowid,
9290
models.SpanAnnotation.name == annotation_input.name,
91+
models.SpanAnnotation.identifier == resolved_identifier,
9392
)
94-
if resolved_identifier is None:
95-
q = q.where(models.SpanAnnotation.identifier.is_(None))
96-
else:
97-
q = q.where(models.SpanAnnotation.identifier == resolved_identifier)
98-
9993
existing_annotation = await session.scalar(q)
10094

10195
if existing_annotation:

src/phoenix/server/api/mutations/trace_annotations_mutations.py

+8-14
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from sqlalchemy import delete, insert, select
55
from starlette.requests import Request
66
from strawberry import UNSET, Info
7+
from strawberry.relay.types import GlobalID
78

89
from phoenix.db import models
910
from phoenix.server.api.auth import IsLocked, IsNotReadOnly
@@ -55,16 +56,13 @@ async def create_trace_annotations(
5556

5657
async with info.context.db() as session:
5758
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:
6063
# 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}"
6866
values = {
6967
"trace_rowid": trace_rowid,
7068
"name": annotation_input.name,
@@ -84,12 +82,8 @@ async def create_trace_annotations(
8482
q = select(models.TraceAnnotation).where(
8583
models.TraceAnnotation.trace_rowid == trace_rowid,
8684
models.TraceAnnotation.name == annotation_input.name,
85+
models.TraceAnnotation.identifier == resolved_identifier,
8786
)
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-
9387
existing_annotation = await session.scalar(q)
9488

9589
if existing_annotation:

0 commit comments

Comments
 (0)