arize-phoenix 4.22.1__py3-none-any.whl → 4.23.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.

Potentially problematic release.


This version of arize-phoenix might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: arize-phoenix
3
- Version: 4.22.1
3
+ Version: 4.23.0
4
4
  Summary: AI Observability and Evaluation
5
5
  Project-URL: Documentation, https://docs.arize.com/phoenix/
6
6
  Project-URL: Issues, https://github.com/Arize-ai/phoenix/issues
@@ -5,7 +5,7 @@ phoenix/exceptions.py,sha256=n2L2KKuecrdflB9MsCdAYCiSEvGJptIsfRkXMoJle7A,169
5
5
  phoenix/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
6
6
  phoenix/services.py,sha256=aTxhcOA1pZHB6U-B3TEcp6fqDF5oT0xCUvEUNMZVTUQ,5175
7
7
  phoenix/settings.py,sha256=cO-qgis_S27nHirTobYI9hHPfZH18R--WMmxNdsVUwc,273
8
- phoenix/version.py,sha256=o6NOndzGr8AzXGIlB0Kpj1jAyiWB77iB92rO-Vlh2y0,23
8
+ phoenix/version.py,sha256=TTTHw1vEKS6ovQizZmeh57pUpbxus30U324Wg3Hwd6s,23
9
9
  phoenix/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
10
  phoenix/core/embedding_dimension.py,sha256=zKGbcvwOXgLf-yrJBpQyKtd-LEOPRKHnUToyAU8Owis,87
11
11
  phoenix/core/model.py,sha256=km_a--PBHOuA337ClRw9xqhOHhrUT6Rl9pz_zV0JYkQ,4843
@@ -68,11 +68,11 @@ phoenix/pointcloud/pointcloud.py,sha256=4zAIkKs2xOUbchpj4XDAV-iPMXrfAJ15TG6rlIYG
68
68
  phoenix/pointcloud/projectors.py,sha256=zO_RrtDYSv2rqVOfIP2_9Cv11Dc8EmcZR94xhFcBYPU,1057
69
69
  phoenix/pointcloud/umap_parameters.py,sha256=3UQSjrysVOvq2V4KNpTMqNqNiK0BsTZnPBHWZ4fyJtQ,1708
70
70
  phoenix/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
71
- phoenix/server/app.py,sha256=fZYS5Jttj70iHnyDMivXs74oZMAx_gQgdWyNUXs59jE,19407
71
+ phoenix/server/app.py,sha256=A0IIC7ONjBlRWqfAjoCqfoVS0xcnPfWk3gmxphgAjcM,19674
72
72
  phoenix/server/dml_event.py,sha256=MpjCFqljxvgb9OB5Cez9vJesb3oHb3XxXictynBfcis,2851
73
73
  phoenix/server/dml_event_handler.py,sha256=6p-PucctivelVHfO-_9zNxWZYPr_eGjDF3bKjLtc5co,8251
74
74
  phoenix/server/grpc_server.py,sha256=jllxDNkpLQxDkvej4RhTokobowbvydF-SU8gSw1MTCc,3378
75
- phoenix/server/main.py,sha256=dvjv3g8ANpkvSGCUN02S2Yse643Nlwrp_bj4iXBSVTE,11082
75
+ phoenix/server/main.py,sha256=xxG650qi2bIX6HCcfSiLd1QyImiBoWbsVJ55m21GyNg,11471
76
76
  phoenix/server/prometheus.py,sha256=j9DHB2fERuq_ZKmwVaqR-9wx5WcPPuU1Cm5Bhg5241Y,2996
77
77
  phoenix/server/telemetry.py,sha256=T_2OKrxNViAeaANlNspEekg_Y5uZIFWvKAnpz8Aoqvk,2762
78
78
  phoenix/server/thread_server.py,sha256=RwXQGP_QhGD7le6WB7xEygEEuwBl5Ck_Zo8xGIYGi9M,2135
@@ -80,7 +80,7 @@ phoenix/server/types.py,sha256=UCCkwEzUAbRdu-hZpG7A2hdPM09onBezaXNtWX4A7og,3431
80
80
  phoenix/server/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
81
81
  phoenix/server/api/context.py,sha256=2-kJpoix-OISxyAhoI5FFEnQMt9ad-3HQ3VOFCjdbxU,2799
82
82
  phoenix/server/api/interceptor.py,sha256=ykDnoC_apUd-llVli3m1CW18kNSIgjz2qZ6m5JmPDu8,1294
83
- phoenix/server/api/queries.py,sha256=Nuw74Nh1XhDkLNV8hTO3WPPNeqcSlNhUF76r5HaytGc,20268
83
+ phoenix/server/api/queries.py,sha256=c5beyU1JUYZTFySg4KJv0x8rbGk2x_fnY-jUHruYv-U,21341
84
84
  phoenix/server/api/schema.py,sha256=BcxdqO5CSGqpKd-AAJHMjFlzaK9oJA8GJuxmMfcdjn4,434
85
85
  phoenix/server/api/utils.py,sha256=Kl47G-1A7QKTDrc75BU2QK6HupsG6MWuXxy351FOfKQ,858
86
86
  phoenix/server/api/dataloaders/__init__.py,sha256=TrOGnU_SD_vEIxOE_dm8HrD5C2ScLFQ4xQ7f8r-E76s,3064
@@ -139,7 +139,7 @@ phoenix/server/api/input_types/TraceAnnotationSort.py,sha256=BzwiUnMh2VsgQYnhDlb
139
139
  phoenix/server/api/input_types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
140
140
  phoenix/server/api/mutations/__init__.py,sha256=UKUAhD5NY-ZI7XONnRRkaHoFuuU3idmE4fk6Sjgy18M,776
141
141
  phoenix/server/api/mutations/auth.py,sha256=vPRFoj7J6PV6QeODewG4K0PhoOebS5AfMRpbi_wuhyQ,311
142
- phoenix/server/api/mutations/dataset_mutations.py,sha256=p3cqYCLb6zf_Dx8ju0R8FMLT5ZBW_ZQXDyP1iw1zA3E,25280
142
+ phoenix/server/api/mutations/dataset_mutations.py,sha256=0feBUW_07FEIx6uzepjxfRVhk5lAck0AkrqS1GVdoF4,27041
143
143
  phoenix/server/api/mutations/experiment_mutations.py,sha256=OXtLYdLA33RGy1MFctfv6ug2sODcDElhJph_J9vkIjk,3157
144
144
  phoenix/server/api/mutations/export_events_mutations.py,sha256=t_wYBxaqvBJYRoHslh3Bmoxmwlzoy0u8SsBKWIKN5hE,4028
145
145
  phoenix/server/api/mutations/project_mutations.py,sha256=MLm7I97lJ85hTuc1tq8sdYA8Ps5WKMV-bGqeeN-Ey90,2279
@@ -205,12 +205,13 @@ phoenix/server/api/types/Retrieval.py,sha256=OhMK2ncjoyp5h1yjKhjlKpoTbQrMHuxmgSF
205
205
  phoenix/server/api/types/ScalarDriftMetricEnum.py,sha256=IUAcRPpgL41WdoIgK6cNk2Te38SspXGyEs-S1fY23_A,232
206
206
  phoenix/server/api/types/Segments.py,sha256=m2yoegrxA1Tn7ZAy1rMjjD1isc752MaAXMoffkBlvrM,2921
207
207
  phoenix/server/api/types/SortDir.py,sha256=OUpXhlCzCxPoXSDkJJygEs9Rw9pMymfaZUG5zPTrw4Y,152
208
- phoenix/server/api/types/Span.py,sha256=ypzCF70a22QH7e7N8UQbO3FPtsPnAUxqqnq7UlcdGV4,14373
208
+ phoenix/server/api/types/Span.py,sha256=NzO1khZQS9LRoY23RciUaxLUR9WJF5pcV-pv8cnQPJA,15053
209
209
  phoenix/server/api/types/SpanAnnotation.py,sha256=6b5G-b_OoRvDL2ayWk7MkbqarLK-F-pQMx21CpUuNGY,1168
210
210
  phoenix/server/api/types/TimeSeries.py,sha256=wjzuxHFqCey0O7Ys25qiXyuqXK8an-osyNWUE8A_8G4,5227
211
211
  phoenix/server/api/types/Trace.py,sha256=-nh3A-S_BlQK1VSSOTWqM85l-WwJsRHifxeDi0sFWZE,3246
212
212
  phoenix/server/api/types/TraceAnnotation.py,sha256=OW6A2zr1gomOuG0XQe55dk15XXX2DSM0DzatRbHWH5A,1256
213
213
  phoenix/server/api/types/UMAPPoints.py,sha256=5sOuruzM8saXa8C2XiyUfk2XPrkVGmhqKpclMYRw1dk,1656
214
+ phoenix/server/api/types/User.py,sha256=bq2bW7h-7zWoJduzAw9-uAH1-fxTN1Y3-cbW4kKIPhc,249
214
215
  phoenix/server/api/types/ValidationResult.py,sha256=pHwdYk4J7SJ5xhlWWHg_6qWkfk4rjOx-bSkGHvkDE3Q,142
215
216
  phoenix/server/api/types/VectorDriftMetricEnum.py,sha256=etiJM5ZjQuD-oE7sY-FbdIKY050jk3IU49IMwmfJbEc,188
216
217
  phoenix/server/api/types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -227,23 +228,23 @@ phoenix/server/static/apple-touch-icon-76x76.png,sha256=CT_xT12I0u2i0WU8JzBZBuOQ
227
228
  phoenix/server/static/apple-touch-icon.png,sha256=fOfpjqGpWYbJ0eAurKsyoZP1EAs6ZVooBJ_SGk2ZkDs,3801
228
229
  phoenix/server/static/favicon.ico,sha256=bY0vvCKRftemZfPShwZtE93DiiQdaYaozkPGwNFr6H8,34494
229
230
  phoenix/server/static/modernizr.js,sha256=mvK-XtkNqjOral-QvzoqsyOMECXIMu5BQwSVN_wcU9c,2564
230
- phoenix/server/static/.vite/manifest.json,sha256=D9OZ5VZQ3XozxyFU4FF1fd4MmUGkyB_xa67tlUi1NWI,1929
231
- phoenix/server/static/assets/components-BC3-LP_a.js,sha256=LnC6sDg6caKtsMyIno5Dw7Ure5BGAReRrsn5XBCcP50,187118
232
- phoenix/server/static/assets/index-BjJvafYL.js,sha256=dz-kVZPp63OEi2l0SYVU5PeimOsUgW3VQQdYdnoZLQE,7362
233
- phoenix/server/static/assets/pages--n2933VW.js,sha256=WJZ6L_bWgzgJc3EAcbwbzuGADKEcZfMBwSVjDHhKslQ,452799
234
- phoenix/server/static/assets/vendor-BMWfu6zp.js,sha256=AAVTM5SjGUI_CmAWFUFmhpp5VDhvCD-MrEoh-pXXADY,1355423
231
+ phoenix/server/static/.vite/manifest.json,sha256=E4foEp6f2D90C8OLyqi729mCx3uwE_Ylkzv0cJqxOy0,1929
232
+ phoenix/server/static/assets/components-DBYPF96c.js,sha256=C5UB6W8UwlM5rP2BpvS1JXhXBXtSa3B39kYsF_u5ahE,187160
233
+ phoenix/server/static/assets/index-DNxu4viw.js,sha256=g-zFucEZZvso7zPns7fKmWq1-eYMktUep4tWW4sSzn0,7466
234
+ phoenix/server/static/assets/pages-BhOnrUmC.js,sha256=riUthPfmrbayRnoDakz47MmNrnUTVaaygrZXdkL-Q00,456974
235
+ phoenix/server/static/assets/vendor-CIqy43_9.js,sha256=YclKUblIZ8JB6hhl36BtG_7FEsrNYbgnsW0d0w6zIxk,1355423
235
236
  phoenix/server/static/assets/vendor-DxkFTwjz.css,sha256=nZrkr0u6NNElFGvpWHk9GTHeGoibCXCli1bE7mXZGZg,1816
236
- phoenix/server/static/assets/vendor-arizeai-Sj74jm5V.js,sha256=9lD4YeMt5WtyfrqIApcH9WFQxyJJUtth0syWabkzX-I,304008
237
- phoenix/server/static/assets/vendor-codemirror-DO3VqEcD.js,sha256=M7t6xd6WpgKes25OOeGyxT1MU1dDrEKdmUBHgy5zslw,503031
238
- phoenix/server/static/assets/vendor-recharts-BGN0SxgJ.js,sha256=L9LAYSjuf0GHh1_PQh9bF4l9euWCDVQcnQN1RgMDMBw,282859
237
+ phoenix/server/static/assets/vendor-arizeai-B1YgcWL8.js,sha256=b-Q3bHiEkWo29daqYevZItyECmgFu0LMjYgpbDK3mSc,304008
238
+ phoenix/server/static/assets/vendor-codemirror-_bcwCA1C.js,sha256=oqAOjM0IviW-Si9fscZsSTR3_aj2vdp8H6acoyIFzek,503031
239
+ phoenix/server/static/assets/vendor-recharts-C3pM_Wlg.js,sha256=gnMIx0IktJjLzrgDehKdRebp3EkFAGli_067pIMVXFY,282859
239
240
  phoenix/server/static/assets/vendor-three-DwGkEfCM.js,sha256=0D12ZgKzfKCTSdSTKJBFR2RZO_xxeMXrqDp0AszZqHY,620972
240
241
  phoenix/server/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
241
- phoenix/server/templates/index.html,sha256=gVpjB8pCMiubdMh2DA9mTCtV5AVTXJH_9u5PmG2t7Vk,4238
242
+ phoenix/server/templates/index.html,sha256=dAm0IClgJUdT5AOmjZvtgMg8F_xGrRGv95SAkUyx_kg,4325
242
243
  phoenix/session/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
243
244
  phoenix/session/client.py,sha256=C-NpmDkcyGZHR0vv5gWtteUi01cIorjWnqie9WuZb9s,32663
244
245
  phoenix/session/data_extractor.py,sha256=gkEM3WWZAlWGMfRgQopAQlid4cSi6GNco-sdrGir0qc,2788
245
246
  phoenix/session/evaluation.py,sha256=aKeV8UVOyq3b7CYOwt3cWuLz0xzvMjX7vlEPILJ_fcs,5311
246
- phoenix/session/session.py,sha256=l10fiotlO1b-SFehcm8N3aVupdFUYYLiLSBrOCJO9as,26911
247
+ phoenix/session/session.py,sha256=LOdcO7_XMArUMnyRlikLMZq41jgZ0Vl_BxDEpYxF4UU,26953
247
248
  phoenix/trace/__init__.py,sha256=ujk_uYjM8gmm-YqnyXxF-kekfwid0bcaPMTtNNcaw6U,407
248
249
  phoenix/trace/attributes.py,sha256=B_OrzVaxZwFkrAFXZyicYoIti1UdUysURsvUS2GyW1U,12488
249
250
  phoenix/trace/errors.py,sha256=wB1z8qdPckngdfU-TORToekvg3344oNFAA83_hC2yFY,180
@@ -281,8 +282,8 @@ phoenix/utilities/logging.py,sha256=lDXd6EGaamBNcQxL4vP1au9-i_SXe0OraUDiJOcszSw,
281
282
  phoenix/utilities/project.py,sha256=8IJuMM4yUMoooPi37sictGj8Etu9rGmq6RFtc9848cQ,436
282
283
  phoenix/utilities/re.py,sha256=PDve_OLjRTM8yQQJHC8-n3HdIONi7aNils3ZKRZ5uBM,2045
283
284
  phoenix/utilities/span_store.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
284
- arize_phoenix-4.22.1.dist-info/METADATA,sha256=aMe9GmDUEAXZE2A5wixJeuulWvcq7dA7U4FGnGVVCf8,11902
285
- arize_phoenix-4.22.1.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
286
- arize_phoenix-4.22.1.dist-info/licenses/IP_NOTICE,sha256=JBqyyCYYxGDfzQ0TtsQgjts41IJoa-hiwDrBjCb9gHM,469
287
- arize_phoenix-4.22.1.dist-info/licenses/LICENSE,sha256=HFkW9REuMOkvKRACuwLPT0hRydHb3zNg-fdFt94td18,3794
288
- arize_phoenix-4.22.1.dist-info/RECORD,,
285
+ arize_phoenix-4.23.0.dist-info/METADATA,sha256=gHdCepPUbWpwWYNgkM1Tek-oR8i-JGP9x84pyTPsTCc,11902
286
+ arize_phoenix-4.23.0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
287
+ arize_phoenix-4.23.0.dist-info/licenses/IP_NOTICE,sha256=JBqyyCYYxGDfzQ0TtsQgjts41IJoa-hiwDrBjCb9gHM,469
288
+ arize_phoenix-4.23.0.dist-info/licenses/LICENSE,sha256=HFkW9REuMOkvKRACuwLPT0hRydHb3zNg-fdFt94td18,3794
289
+ arize_phoenix-4.23.0.dist-info/RECORD,,
@@ -230,7 +230,7 @@ class DatasetMutationMixin:
230
230
  ) -> DatasetMutationPayload:
231
231
  dataset_id = input.dataset_id
232
232
  # Extract the span rowids from the input examples if they exist
233
- span_ids = span_ids = [example.span_id for example in input.examples if example.span_id]
233
+ span_ids = [example.span_id for example in input.examples if example.span_id]
234
234
  span_rowids = {
235
235
  from_global_id_with_expected_type(global_id=span_id, expected_type_name=Span.__name__)
236
236
  for span_id in set(span_ids)
@@ -260,6 +260,8 @@ class DatasetMutationMixin:
260
260
  )
261
261
  .returning(models.DatasetVersion.id)
262
262
  )
263
+
264
+ # Fetch spans and span annotations
263
265
  spans = (
264
266
  await session.execute(
265
267
  select(models.Span.id)
@@ -267,9 +269,36 @@ class DatasetMutationMixin:
267
269
  .where(models.Span.id.in_(span_rowids))
268
270
  )
269
271
  ).all()
270
- # Just validate that the number of spans matches the number of span_ids
271
- # to ensure that the span_ids are valid
272
- assert len(spans) == len(span_rowids)
272
+
273
+ span_annotations = (
274
+ await session.execute(
275
+ select(
276
+ models.SpanAnnotation.span_rowid,
277
+ models.SpanAnnotation.name,
278
+ models.SpanAnnotation.label,
279
+ models.SpanAnnotation.score,
280
+ models.SpanAnnotation.explanation,
281
+ models.SpanAnnotation.metadata_,
282
+ models.SpanAnnotation.annotator_kind,
283
+ )
284
+ .select_from(models.SpanAnnotation)
285
+ .where(models.SpanAnnotation.span_rowid.in_(span_rowids))
286
+ )
287
+ ).all()
288
+
289
+ span_annotations_by_span: Dict[int, Dict[Any, Any]] = {span.id: {} for span in spans}
290
+ for annotation in span_annotations:
291
+ span_id = annotation.span_rowid
292
+ if span_id not in span_annotations_by_span:
293
+ span_annotations_by_span[span_id] = dict()
294
+ span_annotations_by_span[span_id][annotation.name] = {
295
+ "label": annotation.label,
296
+ "score": annotation.score,
297
+ "explanation": annotation.explanation,
298
+ "metadata": annotation.metadata_,
299
+ "annotator_kind": annotation.annotator_kind,
300
+ }
301
+
273
302
  DatasetExample = models.DatasetExample
274
303
  dataset_example_rowids = (
275
304
  await session.scalars(
@@ -291,21 +320,32 @@ class DatasetMutationMixin:
291
320
  assert len(dataset_example_rowids) == len(input.examples)
292
321
  assert all(map(lambda id: isinstance(id, int), dataset_example_rowids))
293
322
  DatasetExampleRevision = models.DatasetExampleRevision
294
- await session.execute(
295
- insert(DatasetExampleRevision),
296
- [
323
+
324
+ dataset_example_revisions = []
325
+ for dataset_example_rowid, example in zip(dataset_example_rowids, input.examples):
326
+ span_annotation = {}
327
+ if example.span_id:
328
+ span_id = from_global_id_with_expected_type(
329
+ global_id=example.span_id,
330
+ expected_type_name=Span.__name__,
331
+ )
332
+ span_annotation = span_annotations_by_span.get(span_id, {})
333
+ dataset_example_revisions.append(
297
334
  {
298
335
  DatasetExampleRevision.dataset_example_id.key: dataset_example_rowid,
299
336
  DatasetExampleRevision.dataset_version_id.key: dataset_version_rowid,
300
337
  DatasetExampleRevision.input.key: example.input,
301
338
  DatasetExampleRevision.output.key: example.output,
302
- DatasetExampleRevision.metadata_.key: example.metadata,
339
+ DatasetExampleRevision.metadata_.key: {
340
+ **(example.metadata or {}),
341
+ "annotations": span_annotation,
342
+ },
303
343
  DatasetExampleRevision.revision_kind.key: "CREATE",
304
344
  }
305
- for dataset_example_rowid, example in zip(
306
- dataset_example_rowids, input.examples
307
- )
308
- ],
345
+ )
346
+ await session.execute(
347
+ insert(DatasetExampleRevision),
348
+ dataset_example_revisions,
309
349
  )
310
350
  info.context.event_queue.put(DatasetInsertEvent((dataset.id,)))
311
351
  return DatasetMutationPayload(dataset=to_gql_dataset(dataset))
@@ -67,10 +67,40 @@ from phoenix.server.api.types.Project import Project
67
67
  from phoenix.server.api.types.SortDir import SortDir
68
68
  from phoenix.server.api.types.Span import Span, to_gql_span
69
69
  from phoenix.server.api.types.Trace import Trace
70
+ from phoenix.server.api.types.User import User
70
71
 
71
72
 
72
73
  @strawberry.type
73
74
  class Query:
75
+ @strawberry.field
76
+ async def users(
77
+ self,
78
+ info: Info[Context, None],
79
+ first: Optional[int] = 50,
80
+ last: Optional[int] = UNSET,
81
+ after: Optional[CursorString] = UNSET,
82
+ before: Optional[CursorString] = UNSET,
83
+ ) -> Connection[User]:
84
+ args = ConnectionArgs(
85
+ first=first,
86
+ after=after if isinstance(after, CursorString) else None,
87
+ last=last,
88
+ before=before if isinstance(before, CursorString) else None,
89
+ )
90
+ stmt = select(models.User).order_by(models.User.email)
91
+ async with info.context.db() as session:
92
+ users = await session.stream_scalars(stmt)
93
+ data = [
94
+ User(
95
+ id_attr=user.id,
96
+ email=user.email,
97
+ username=user.username,
98
+ created_at=user.created_at,
99
+ )
100
+ async for user in users
101
+ ]
102
+ return connection_from_list(data=data, args=args)
103
+
74
104
  @strawberry.field
75
105
  async def projects(
76
106
  self,
@@ -232,7 +232,7 @@ class Span(Node):
232
232
  @strawberry.field(
233
233
  description="The span's attributes translated into an example revision for a dataset",
234
234
  ) # type: ignore
235
- def as_example_revision(self) -> SpanAsExampleRevision:
235
+ async def as_example_revision(self, info: Info[Context, None]) -> SpanAsExampleRevision:
236
236
  db_span = self.db_span
237
237
  attributes = db_span.attributes
238
238
  span_io = _SpanIO(
@@ -248,10 +248,28 @@ class Span(Node):
248
248
  llm_output_messages=get_attribute_value(attributes, LLM_OUTPUT_MESSAGES),
249
249
  retrieval_documents=get_attribute_value(attributes, RETRIEVAL_DOCUMENTS),
250
250
  )
251
+
252
+ # Fetch annotations associated with this span
253
+ span_annotations = await self.span_annotations(info)
254
+ annotations = dict()
255
+ for annotation in span_annotations:
256
+ annotations[annotation.name] = {
257
+ "label": annotation.label,
258
+ "score": annotation.score,
259
+ "explanation": annotation.explanation,
260
+ "metadata": annotation.metadata,
261
+ "annotator_kind": annotation.annotator_kind.value,
262
+ }
263
+ # Merge annotations into the metadata
264
+ metadata = {
265
+ **attributes,
266
+ "annotations": annotations,
267
+ }
268
+
251
269
  return SpanAsExampleRevision(
252
270
  input=get_dataset_example_input(span_io),
253
271
  output=get_dataset_example_output(span_io),
254
- metadata=attributes,
272
+ metadata=metadata,
255
273
  )
256
274
 
257
275
  @strawberry.field(description="The project that this span belongs to.") # type: ignore
@@ -0,0 +1,13 @@
1
+ from datetime import datetime
2
+ from typing import Optional
3
+
4
+ import strawberry
5
+ from strawberry.relay import Node, NodeID
6
+
7
+
8
+ @strawberry.type
9
+ class User(Node):
10
+ id_attr: NodeID[int]
11
+ email: str
12
+ username: Optional[str]
13
+ created_at: datetime
phoenix/server/app.py CHANGED
@@ -115,6 +115,8 @@ class AppConfig(NamedTuple):
115
115
  n_samples: int
116
116
  is_development: bool
117
117
  web_manifest_path: Path
118
+ authentication_enabled: bool
119
+ """ Whether authentication is enabled """
118
120
 
119
121
 
120
122
  class Static(StaticFiles):
@@ -162,6 +164,7 @@ class Static(StaticFiles):
162
164
  "request": request,
163
165
  "is_development": self._app_config.is_development,
164
166
  "manifest": self._web_manifest,
167
+ "authentication_enabled": self._app_config.authentication_enabled,
165
168
  },
166
169
  )
167
170
  except Exception as e:
@@ -395,6 +398,7 @@ def create_app(
395
398
  db: DbSessionFactory,
396
399
  export_path: Path,
397
400
  model: Model,
401
+ authentication_enabled: bool,
398
402
  umap_params: UMAPParameters,
399
403
  corpus: Optional[Model] = None,
400
404
  debug: bool = False,
@@ -515,6 +519,7 @@ def create_app(
515
519
  n_neighbors=umap_params.n_neighbors,
516
520
  n_samples=umap_params.n_samples,
517
521
  is_development=dev,
522
+ authentication_enabled=authentication_enabled,
518
523
  web_manifest_path=SERVER_DIR / "static" / ".vite" / "manifest.json",
519
524
  ),
520
525
  ),
phoenix/server/main.py CHANGED
@@ -13,6 +13,7 @@ from uvicorn import Config, Server
13
13
  import phoenix.trace.v1 as pb
14
14
  from phoenix.config import (
15
15
  EXPORT_DIR,
16
+ get_auth_settings,
16
17
  get_env_database_connection_str,
17
18
  get_env_enable_prometheus,
18
19
  get_env_grpc_port,
@@ -80,6 +81,11 @@ _WELCOME_MESSAGE = """
80
81
  | Storage: {storage}
81
82
  """
82
83
 
84
+ _EXPERIMENTAL_WARNING = """
85
+ 🚨 WARNING: Phoenix is running in experimental mode. 🚨
86
+ | Authentication enabled: {auth_enabled}
87
+ """
88
+
83
89
 
84
90
  def _write_pid_file_when_ready(
85
91
  server: Server,
@@ -212,6 +218,8 @@ if __name__ == "__main__":
212
218
  reference_inferences,
213
219
  )
214
220
 
221
+ authentication_enabled, auth_secret = get_auth_settings()
222
+
215
223
  fixture_spans: List[Span] = []
216
224
  fixture_evals: List[pb.Evaluation] = []
217
225
  if trace_dataset_name is not None:
@@ -251,6 +259,7 @@ if __name__ == "__main__":
251
259
  db=factory,
252
260
  export_path=export_path,
253
261
  model=model,
262
+ authentication_enabled=authentication_enabled,
254
263
  umap_params=umap_params,
255
264
  corpus=None
256
265
  if corpus_inferences is None
@@ -278,5 +287,8 @@ if __name__ == "__main__":
278
287
  )
279
288
  )
280
289
 
290
+ if authentication_enabled:
291
+ print(_EXPERIMENTAL_WARNING.format(auth_enabled=authentication_enabled))
292
+
281
293
  # Start the server
282
294
  server.run()
@@ -1,32 +1,32 @@
1
1
  {
2
- "_components-BC3-LP_a.js": {
3
- "file": "assets/components-BC3-LP_a.js",
2
+ "_components-DBYPF96c.js": {
3
+ "file": "assets/components-DBYPF96c.js",
4
4
  "name": "components",
5
5
  "imports": [
6
- "_vendor-BMWfu6zp.js",
7
- "_vendor-arizeai-Sj74jm5V.js",
8
- "_pages--n2933VW.js",
6
+ "_vendor-CIqy43_9.js",
7
+ "_vendor-arizeai-B1YgcWL8.js",
8
+ "_pages-BhOnrUmC.js",
9
9
  "_vendor-three-DwGkEfCM.js",
10
- "_vendor-codemirror-DO3VqEcD.js"
10
+ "_vendor-codemirror-_bcwCA1C.js"
11
11
  ]
12
12
  },
13
- "_pages--n2933VW.js": {
14
- "file": "assets/pages--n2933VW.js",
13
+ "_pages-BhOnrUmC.js": {
14
+ "file": "assets/pages-BhOnrUmC.js",
15
15
  "name": "pages",
16
16
  "imports": [
17
- "_vendor-BMWfu6zp.js",
18
- "_components-BC3-LP_a.js",
19
- "_vendor-arizeai-Sj74jm5V.js",
20
- "_vendor-recharts-BGN0SxgJ.js",
21
- "_vendor-codemirror-DO3VqEcD.js"
17
+ "_vendor-CIqy43_9.js",
18
+ "_components-DBYPF96c.js",
19
+ "_vendor-arizeai-B1YgcWL8.js",
20
+ "_vendor-recharts-C3pM_Wlg.js",
21
+ "_vendor-codemirror-_bcwCA1C.js"
22
22
  ]
23
23
  },
24
24
  "_vendor-!~{003}~.js": {
25
25
  "file": "assets/vendor-DxkFTwjz.css",
26
26
  "src": "_vendor-!~{003}~.js"
27
27
  },
28
- "_vendor-BMWfu6zp.js": {
29
- "file": "assets/vendor-BMWfu6zp.js",
28
+ "_vendor-CIqy43_9.js": {
29
+ "file": "assets/vendor-CIqy43_9.js",
30
30
  "name": "vendor",
31
31
  "imports": [
32
32
  "_vendor-three-DwGkEfCM.js"
@@ -35,25 +35,25 @@
35
35
  "assets/vendor-DxkFTwjz.css"
36
36
  ]
37
37
  },
38
- "_vendor-arizeai-Sj74jm5V.js": {
39
- "file": "assets/vendor-arizeai-Sj74jm5V.js",
38
+ "_vendor-arizeai-B1YgcWL8.js": {
39
+ "file": "assets/vendor-arizeai-B1YgcWL8.js",
40
40
  "name": "vendor-arizeai",
41
41
  "imports": [
42
- "_vendor-BMWfu6zp.js"
42
+ "_vendor-CIqy43_9.js"
43
43
  ]
44
44
  },
45
- "_vendor-codemirror-DO3VqEcD.js": {
46
- "file": "assets/vendor-codemirror-DO3VqEcD.js",
45
+ "_vendor-codemirror-_bcwCA1C.js": {
46
+ "file": "assets/vendor-codemirror-_bcwCA1C.js",
47
47
  "name": "vendor-codemirror",
48
48
  "imports": [
49
- "_vendor-BMWfu6zp.js"
49
+ "_vendor-CIqy43_9.js"
50
50
  ]
51
51
  },
52
- "_vendor-recharts-BGN0SxgJ.js": {
53
- "file": "assets/vendor-recharts-BGN0SxgJ.js",
52
+ "_vendor-recharts-C3pM_Wlg.js": {
53
+ "file": "assets/vendor-recharts-C3pM_Wlg.js",
54
54
  "name": "vendor-recharts",
55
55
  "imports": [
56
- "_vendor-BMWfu6zp.js"
56
+ "_vendor-CIqy43_9.js"
57
57
  ]
58
58
  },
59
59
  "_vendor-three-DwGkEfCM.js": {
@@ -61,18 +61,18 @@
61
61
  "name": "vendor-three"
62
62
  },
63
63
  "index.tsx": {
64
- "file": "assets/index-BjJvafYL.js",
64
+ "file": "assets/index-DNxu4viw.js",
65
65
  "name": "index",
66
66
  "src": "index.tsx",
67
67
  "isEntry": true,
68
68
  "imports": [
69
- "_vendor-BMWfu6zp.js",
70
- "_vendor-arizeai-Sj74jm5V.js",
71
- "_components-BC3-LP_a.js",
72
- "_pages--n2933VW.js",
69
+ "_vendor-CIqy43_9.js",
70
+ "_vendor-arizeai-B1YgcWL8.js",
71
+ "_pages-BhOnrUmC.js",
72
+ "_components-DBYPF96c.js",
73
73
  "_vendor-three-DwGkEfCM.js",
74
- "_vendor-codemirror-DO3VqEcD.js",
75
- "_vendor-recharts-BGN0SxgJ.js"
74
+ "_vendor-recharts-C3pM_Wlg.js",
75
+ "_vendor-codemirror-_bcwCA1C.js"
76
76
  ]
77
77
  }
78
78
  }