arize-phoenix 11.5.0__py3-none-any.whl → 11.6.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.4
2
2
  Name: arize-phoenix
3
- Version: 11.5.0
3
+ Version: 11.6.0
4
4
  Summary: AI Observability and Evaluation
5
5
  Project-URL: Documentation, https://arize.com/docs/phoenix/
6
6
  Project-URL: Issues, https://github.com/Arize-ai/phoenix/issues
@@ -6,7 +6,7 @@ phoenix/exceptions.py,sha256=n2L2KKuecrdflB9MsCdAYCiSEvGJptIsfRkXMoJle7A,169
6
6
  phoenix/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
7
7
  phoenix/services.py,sha256=ngkyKGVatX3cO2WJdo2hKdaVKP-xJCMvqthvga6kJss,5196
8
8
  phoenix/settings.py,sha256=2kHfT3BNOVd4dAO1bq-syEQbHSG8oX2-7NhOwK2QREk,896
9
- phoenix/version.py,sha256=89g_4HXr4XouZfNDdwEbm-Xwu06Vvu-EUBmo-baEVQQ,23
9
+ phoenix/version.py,sha256=kjhthIE5r_ArzQulbcqnrRj4ewlV2jNJYfo-PPrxloM,23
10
10
  phoenix/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  phoenix/core/embedding_dimension.py,sha256=zKGbcvwOXgLf-yrJBpQyKtd-LEOPRKHnUToyAU8Owis,87
12
12
  phoenix/core/model.py,sha256=qBFraOtmwCCnWJltKNP18DDG0mULXigytlFsa6YOz6k,4837
@@ -91,7 +91,7 @@ phoenix/pointcloud/pointcloud.py,sha256=SN_1wXZcwKrtSnHGZLDZGx71orqE1WyVF7E-D58d
91
91
  phoenix/pointcloud/projectors.py,sha256=TQgwc9cJDjJkin1WZyZzgl3HsYrLLiyWD7Czy4jNW3U,1088
92
92
  phoenix/pointcloud/umap_parameters.py,sha256=db_WEPoamuWtopZx7tQfAXPnoE0MS8FkAV0_ThjEx_Q,1735
93
93
  phoenix/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
94
- phoenix/server/app.py,sha256=oz5vDRGj58XUd1yOcCKVBQP6hmRiZAI3FMjnXkAxDoE,46758
94
+ phoenix/server/app.py,sha256=GwItmVRwSM5JspXIHwEO1hXjRAqQRQ4djZfbzJjnh3Q,46694
95
95
  phoenix/server/authorization.py,sha256=AGpQT6HpPn2ROOxxVBvjPV1393KF4v-K5IHJ4JaTOHM,2175
96
96
  phoenix/server/bearer_auth.py,sha256=f4v4W94KyTdGGCPsK1tXOe0vouPuvanAEa03XSdCvPE,6650
97
97
  phoenix/server/dml_event.py,sha256=MjJmVEKytq75chBOSyvYDusUnEbg1pHpIjR3pZkUaJA,2838
@@ -105,14 +105,14 @@ phoenix/server/rate_limiters.py,sha256=cFc73D2NaxqNZZDbwfIDw4So-fRVOJPBtqxOZ8Qky
105
105
  phoenix/server/retention.py,sha256=MQe1FWuc_NxhqgIq5q2hfFhWT8ddAmpppgI74xYEQ6c,3064
106
106
  phoenix/server/telemetry.py,sha256=4EluDDrhdDPxAjaW6lVSbi73xkB5XeUCZWOmZGdk0hg,2755
107
107
  phoenix/server/thread_server.py,sha256=Ea2AWreN1lwJsT2wYvGaRaiXrzBqH4kgkZpx0FO5Ocw,2144
108
- phoenix/server/types.py,sha256=OdC56_7R7EoUPUx5t8kw9dnedH_Ut-RkVI5atya3joI,7918
108
+ phoenix/server/types.py,sha256=j8erl9iRNaR8t0DCQG84-uDVbHy9Qnm7T2EuTtDNNsU,8013
109
109
  phoenix/server/api/README.md,sha256=Pyq1PLPgTzXAswrfIhGXrjI3Skq8it2jTVnanT6Ba4Q,1162
110
110
  phoenix/server/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
111
111
  phoenix/server/api/auth.py,sha256=Bf21wayr-Jrp0ZF9RgbOi9_M91eHE1Tclq9lDYtrkTU,1575
112
112
  phoenix/server/api/context.py,sha256=mqsq_8Ru50e-PxKWNTzh9zptb1PFjYFUf58uW59UYL0,8996
113
113
  phoenix/server/api/exceptions.py,sha256=TA0JuY2YRnj35qGuMSQ8d0ToHum9gWm9W--3fSKHrX0,1171
114
114
  phoenix/server/api/interceptor.py,sha256=ykDnoC_apUd-llVli3m1CW18kNSIgjz2qZ6m5JmPDu8,1294
115
- phoenix/server/api/queries.py,sha256=BIM-6k-TGWYSalFEADWi5zpL3-6EUoQdpXLD4GmuaMw,45274
115
+ phoenix/server/api/queries.py,sha256=fvbdyhJ57I6DPrNEBkWwhw8BRF7DyIZ3LtYwXwI7yVw,45651
116
116
  phoenix/server/api/schema.py,sha256=fcs36xQwFF_Qe41_5cWR8wYpDvOrnbcyTeo5WNMbDsA,1702
117
117
  phoenix/server/api/subscriptions.py,sha256=ZOGNsLVr5TNjCWgbzO7Eq6Ls_NRdJH9AxC0cW_v0vhM,25332
118
118
  phoenix/server/api/utils.py,sha256=quCBRcusc6PUq9tJq7M8PgwFZp7nXgVAxtbw8feribY,833
@@ -262,7 +262,7 @@ phoenix/server/api/routers/v1/experiments.py,sha256=osy0JG_iVSCkoRi__0tjldfS5zzB
262
262
  phoenix/server/api/routers/v1/models.py,sha256=p3gJN-9SWiUYTUTft4bZMsZVCBNTb4nN1Foy68eRZzQ,1997
263
263
  phoenix/server/api/routers/v1/projects.py,sha256=32GwTLsaFgQLVNdjrlrGe90XT3pIX1N7-zX9D9_J_4w,12701
264
264
  phoenix/server/api/routers/v1/prompts.py,sha256=chRYcLkOYDJdJfVZVukVTUyIRnLPvsJCg41CuPxOIU8,26695
265
- phoenix/server/api/routers/v1/spans.py,sha256=ib7kWpIpSqI53XFFU5xw80tmenajI5m8c8yfvDfTPrQ,44256
265
+ phoenix/server/api/routers/v1/spans.py,sha256=oFoDT2XLB4chsiFQIa0fAsY2rQOa4ApioH232_utJLo,44226
266
266
  phoenix/server/api/routers/v1/traces.py,sha256=63T-WYiwh8X3Sp6u_OFfA9zLLKk6cNsnciiDyUzKLVk,8561
267
267
  phoenix/server/api/routers/v1/users.py,sha256=hUZCe7ctJqEkSJBe046a0OAFMLZodtyO7NLP7U6S8Pg,11986
268
268
  phoenix/server/api/routers/v1/utils.py,sha256=oXIOGPzPTkE0ZWUTRCoRIQQ7wTzoSwtWFaUSjlGBqts,4960
@@ -332,7 +332,7 @@ phoenix/server/api/types/Retrieval.py,sha256=OhMK2ncjoyp5h1yjKhjlKpoTbQrMHuxmgSF
332
332
  phoenix/server/api/types/ScalarDriftMetricEnum.py,sha256=IUAcRPpgL41WdoIgK6cNk2Te38SspXGyEs-S1fY23_A,232
333
333
  phoenix/server/api/types/Segments.py,sha256=vT2v0efoa5cuBKxLtxTnsUP5YJJCZfTloM71Spu0tMI,2915
334
334
  phoenix/server/api/types/SortDir.py,sha256=OUpXhlCzCxPoXSDkJJygEs9Rw9pMymfaZUG5zPTrw4Y,152
335
- phoenix/server/api/types/Span.py,sha256=C0gTw9cx-6MKdMPCbrBjyyYRgXBpXB8wrR41lOhFPZE,36253
335
+ phoenix/server/api/types/Span.py,sha256=0o1lyceeZhEeBLBdd8gYo324nQ1P6eTPOi3aKdZZUd4,32015
336
336
  phoenix/server/api/types/SpanAnnotation.py,sha256=uPWu7Z8rmpfKhaaxbged4_o00pPCR3nkn7Gji9vB8jY,1959
337
337
  phoenix/server/api/types/SpanCostDetailSummaryEntry.py,sha256=RXAdOC6MFyR9mwaoj8lMMdI3_9r3z6mR2izJvlsj12U,252
338
338
  phoenix/server/api/types/SpanCostSummary.py,sha256=wo03FCMcFzB5m4P5kvA5jzi9ACLbht38ozQbDJUh94g,357
@@ -356,13 +356,13 @@ phoenix/server/api/types/node.py,sha256=BLl_IOFr0zrqUxaAtGLGui5aeM5VNVXFTzGeAKrz
356
356
  phoenix/server/api/types/pagination.py,sha256=BXm46gXZfrBS4hpiLvVSEdsbb29ctUMVJYjKXlOLxUA,9064
357
357
  phoenix/server/cost_tracking/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
358
358
  phoenix/server/cost_tracking/cost_details_calculator.py,sha256=ywWQO6foRZC0CmbNPGpa3DaPoWzuIp3ke9s4NqHLuUw,8736
359
- phoenix/server/cost_tracking/cost_model_lookup.py,sha256=ys-jZY3cSE2_-f1glFhYgOd60kQdDL07MnChaxojTLo,6800
359
+ phoenix/server/cost_tracking/cost_model_lookup.py,sha256=jhtVdnQBzrTUHeOGPWgOebk-Io5hpJ1vAgWOu8ojeJ4,6801
360
360
  phoenix/server/cost_tracking/helpers.py,sha256=Pk6ECjnYreTxrldtRwxnwFcxIPVsvDq_yAwDA_spkOc,2122
361
- phoenix/server/cost_tracking/model_cost_manifest.json,sha256=UgtshWqK3KV4tsgboS0Z4xj08PEnCwubaMhliN1fquk,54092
361
+ phoenix/server/cost_tracking/model_cost_manifest.json,sha256=sMXOjssVwcJkmdMapA5-eYjXIboUu8FDosuXGL3q1Cw,53862
362
362
  phoenix/server/cost_tracking/regex_specificity.py,sha256=9kqWuQ68C-hlwW25hr7BhFlRt5y2Nnpy0Ax3n9UN6Xk,11622
363
363
  phoenix/server/cost_tracking/token_cost_calculator.py,sha256=2JEZnvusx2-xbhp8krp9EarjWuyGH2KO4e-ZwJX-K0s,1598
364
364
  phoenix/server/daemons/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
365
- phoenix/server/daemons/db_disk_usage_monitor.py,sha256=benip_Qomzec7P5D53JLd0mFHpR5YKDuyC89gp52H00,7810
365
+ phoenix/server/daemons/db_disk_usage_monitor.py,sha256=_MckKf9GbQ3Is4WZ3RmwJmvVElkF9Ipss3yNHjF8R3c,8016
366
366
  phoenix/server/daemons/generative_model_store.py,sha256=CkMG0jFWtxcUNP_7iFTgzHPyl5IgnXUwwJb7584pmkI,1566
367
367
  phoenix/server/daemons/span_cost_calculator.py,sha256=0BXMe9sHN8k5RjIQjCBzZdwvFuBHu8zDqAJc8rXbQA0,3199
368
368
  phoenix/server/email/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -385,10 +385,10 @@ phoenix/server/static/apple-touch-icon-76x76.png,sha256=CT_xT12I0u2i0WU8JzBZBuOQ
385
385
  phoenix/server/static/apple-touch-icon.png,sha256=fOfpjqGpWYbJ0eAurKsyoZP1EAs6ZVooBJ_SGk2ZkDs,3801
386
386
  phoenix/server/static/favicon.ico,sha256=bY0vvCKRftemZfPShwZtE93DiiQdaYaozkPGwNFr6H8,34494
387
387
  phoenix/server/static/modernizr.js,sha256=mvK-XtkNqjOral-QvzoqsyOMECXIMu5BQwSVN_wcU9c,2564
388
- phoenix/server/static/.vite/manifest.json,sha256=ZL_0RVhWw_gqiweBE08ChN_fTip0uAUv9LpftqB_gbQ,2165
389
- phoenix/server/static/assets/components-Bwf6zNbg.js,sha256=zjt5QXni04diJyCeU7EUjC9aXmgEy4z_GFbY-9sFjLU,613779
390
- phoenix/server/static/assets/index-Bfg9uQ43.js,sha256=TfWnwuZRhp_gO7pmIk20FYl5gz0zQlOUQkaO8NXh6e0,61540
391
- phoenix/server/static/assets/pages-BCR8hW_l.js,sha256=8_EPH5EgP4I-Z2YPV9CK3mbdmHp3LHJ4KLg5368MQDE,1142908
388
+ phoenix/server/static/.vite/manifest.json,sha256=Zj-tml_8YSPL9TgLhBQlJtU8VvoayudhofQOJ0SZwrc,2165
389
+ phoenix/server/static/assets/components-mOUBHJ12.js,sha256=0CP0snc1584_nGtYOZ2-TzS61eorXGcw19V2nXysysc,613664
390
+ phoenix/server/static/assets/index-CQ_A6K_M.js,sha256=McgJhbcluGJTW8reudv1UCVYW2cFTpJJ10Tl-xfizSU,61726
391
+ phoenix/server/static/assets/pages-CCsLkNZY.js,sha256=zgD05qvSU39V6nYtxslmXXk_8zZHfANMDpO3GL1_4JA,1146914
392
392
  phoenix/server/static/assets/vendor-DRWIRkSJ.js,sha256=f56XLATSYmnWXn7652x9UsGk4jOQygtd7bfaXtI4I_o,2738792
393
393
  phoenix/server/static/assets/vendor-WIZid84E.css,sha256=spZD2r7XL5GfLO13ln-IuXfnjAref8l6g_n_AvxxOlI,5517
394
394
  phoenix/server/static/assets/vendor-arizeai-DUhQaeau.js,sha256=FtPCxnjNFpPwea0mcq1qokn2T5MQWpp-yxL-_ZbaUZw,181769
@@ -435,9 +435,9 @@ phoenix/utilities/project.py,sha256=auVpARXkDb-JgeX5f2aStyFIkeKvGwN9l7qrFeJMVxI,
435
435
  phoenix/utilities/re.py,sha256=6YyUWIkv0zc2SigsxfOWIHzdpjKA_TZo2iqKq7zJKvw,2081
436
436
  phoenix/utilities/span_store.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
437
437
  phoenix/utilities/template_formatters.py,sha256=gh9PJD6WEGw7TEYXfSst1UR4pWWwmjxMLrDVQ_CkpkQ,2779
438
- arize_phoenix-11.5.0.dist-info/METADATA,sha256=cyab8qY5pMOami0zRvOPxRRprGOB2MF19X-x00QU3Ck,27761
439
- arize_phoenix-11.5.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
440
- arize_phoenix-11.5.0.dist-info/entry_points.txt,sha256=Pgpn8Upxx9P8z8joPXZWl2LlnAlGc3gcQoVchb06X1Q,94
441
- arize_phoenix-11.5.0.dist-info/licenses/IP_NOTICE,sha256=JBqyyCYYxGDfzQ0TtsQgjts41IJoa-hiwDrBjCb9gHM,469
442
- arize_phoenix-11.5.0.dist-info/licenses/LICENSE,sha256=HFkW9REuMOkvKRACuwLPT0hRydHb3zNg-fdFt94td18,3794
443
- arize_phoenix-11.5.0.dist-info/RECORD,,
438
+ arize_phoenix-11.6.0.dist-info/METADATA,sha256=yvDNlFfsf6bNEXlrDyo0qflVgYt5T5UjmB9Y-Se7ZKY,27761
439
+ arize_phoenix-11.6.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
440
+ arize_phoenix-11.6.0.dist-info/entry_points.txt,sha256=Pgpn8Upxx9P8z8joPXZWl2LlnAlGc3gcQoVchb06X1Q,94
441
+ arize_phoenix-11.6.0.dist-info/licenses/IP_NOTICE,sha256=JBqyyCYYxGDfzQ0TtsQgjts41IJoa-hiwDrBjCb9gHM,469
442
+ arize_phoenix-11.6.0.dist-info/licenses/LICENSE,sha256=HFkW9REuMOkvKRACuwLPT0hRydHb3zNg-fdFt94td18,3794
443
+ arize_phoenix-11.6.0.dist-info/RECORD,,
@@ -335,28 +335,20 @@ class Query:
335
335
  async def compare_experiments(
336
336
  self,
337
337
  info: Info[Context, None],
338
- experiment_ids: list[GlobalID],
338
+ baseline_experiment_id: GlobalID,
339
+ compare_experiment_ids: list[GlobalID],
339
340
  first: Optional[int] = 50,
340
341
  after: Optional[CursorString] = UNSET,
341
342
  filter_condition: Optional[str] = UNSET,
342
343
  ) -> Connection[ExperimentComparison]:
343
- # Handle empty experiment_ids gracefully
344
- if not experiment_ids:
345
- return connection_from_list(
346
- data=[],
347
- args=ConnectionArgs(
348
- first=first,
349
- after=after if isinstance(after, CursorString) else None,
350
- ),
351
- )
352
-
353
- experiment_ids_ = [
344
+ if baseline_experiment_id in compare_experiment_ids:
345
+ raise BadRequest("Compare experiment IDs cannot contain the baseline experiment ID")
346
+ if len(set(compare_experiment_ids)) < len(compare_experiment_ids):
347
+ raise BadRequest("Compare experiment IDs must be unique")
348
+ experiment_ids = [
354
349
  from_global_id_with_expected_type(experiment_id, models.Experiment.__name__)
355
- for experiment_id in experiment_ids
350
+ for experiment_id in (baseline_experiment_id, *compare_experiment_ids)
356
351
  ]
357
- if len(set(experiment_ids_)) != len(experiment_ids_):
358
- raise BadRequest("Experiment IDs must be unique.")
359
-
360
352
  cursor = Cursor.from_string(after) if after else None
361
353
  page_size = first or 50
362
354
 
@@ -375,7 +367,7 @@ class Query:
375
367
  models.Experiment.dataset_version_id == models.DatasetVersion.id,
376
368
  )
377
369
  .where(
378
- models.Experiment.id.in_(experiment_ids_),
370
+ models.Experiment.id.in_(experiment_ids),
379
371
  )
380
372
  )
381
373
  ).first()
@@ -385,7 +377,7 @@ class Query:
385
377
  num_datasets, dataset_id, version_id, num_resolved_experiment_ids = validation_result
386
378
  if num_datasets != 1:
387
379
  raise BadRequest("Experiments must belong to the same dataset.")
388
- if num_resolved_experiment_ids != len(experiment_ids_):
380
+ if num_resolved_experiment_ids != len(experiment_ids):
389
381
  raise NotFound("Unable to resolve one or more experiment IDs.")
390
382
 
391
383
  revision_ids = (
@@ -425,7 +417,7 @@ class Query:
425
417
  examples_query = update_examples_query_with_filter_condition(
426
418
  query=examples_query,
427
419
  filter_condition=filter_condition,
428
- experiment_ids=experiment_ids_,
420
+ experiment_ids=experiment_ids,
429
421
  )
430
422
 
431
423
  examples = (await session.scalars(examples_query)).all()
@@ -444,17 +436,20 @@ class Query:
444
436
  models.ExperimentRun.dataset_example_id.in_(
445
437
  example.id for example in examples
446
438
  ),
447
- models.ExperimentRun.experiment_id.in_(experiment_ids_),
439
+ models.ExperimentRun.experiment_id.in_(experiment_ids),
448
440
  )
449
441
  )
450
442
  .options(joinedload(models.ExperimentRun.trace).load_only(models.Trace.trace_id))
443
+ .order_by(
444
+ models.ExperimentRun.repetition_number.asc()
445
+ ) # repetitions are not currently implemented, but this ensures that the repetitions will be properly ordered once implemented # noqa: E501
451
446
  ):
452
447
  runs[run.dataset_example_id][run.experiment_id].append(run)
453
448
 
454
449
  cursors_and_nodes = []
455
450
  for example in examples:
456
451
  run_comparison_items = []
457
- for experiment_id in experiment_ids_:
452
+ for experiment_id in experiment_ids:
458
453
  run_comparison_items.append(
459
454
  RunComparisonItem(
460
455
  experiment_id=GlobalID(Experiment.__name__, str(experiment_id)),
@@ -479,7 +474,7 @@ class Query:
479
474
 
480
475
  return connection_from_cursors_and_nodes(
481
476
  cursors_and_nodes=cursors_and_nodes,
482
- has_previous_page=False,
477
+ has_previous_page=False, # set to false since we are only doing forward pagination (https://relay.dev/graphql/connections.htm#sec-undefined.PageInfo.Fields) # noqa: E501
483
478
  has_next_page=has_next_page,
484
479
  )
485
480
 
@@ -989,13 +984,14 @@ class Query:
989
984
  # stats = cast(Iterable[tuple[str, int]], await session.execute(stmt))
990
985
  # stats = _consolidate_sqlite_db_table_stats(stats)
991
986
  elif info.context.db.dialect is SupportedSQLDialect.POSTGRESQL:
992
- stmt = text(f"""\
987
+ nspname = getenv(ENV_PHOENIX_SQL_DATABASE_SCHEMA) or "public"
988
+ stmt = text("""\
993
989
  SELECT c.relname, pg_total_relation_size(c.oid)
994
990
  FROM pg_class as c
995
991
  INNER JOIN pg_namespace as n ON n.oid = c.relnamespace
996
992
  WHERE c.relkind = 'r'
997
- AND n.nspname = '{getenv(ENV_PHOENIX_SQL_DATABASE_SCHEMA) or "public"}';
998
- """)
993
+ AND n.nspname = :nspname;
994
+ """).bindparams(nspname=nspname)
999
995
  try:
1000
996
  async with info.context.db() as session:
1001
997
  stats = cast(Iterable[tuple[str, int]], await session.execute(stmt))
@@ -602,7 +602,7 @@ async def span_search_otlpv1(
602
602
  models.Trace.trace_id,
603
603
  )
604
604
  .join(models.Trace, onclause=models.Trace.id == models.Span.trace_rowid)
605
- .join(models.Project, onclause=models.Project.id == project_id)
605
+ .where(models.Trace.project_rowid == project_id)
606
606
  .order_by(*order_by)
607
607
  )
608
608
 
@@ -737,7 +737,7 @@ async def span_search(
737
737
  models.Trace.trace_id,
738
738
  )
739
739
  .join(models.Trace, onclause=models.Trace.id == models.Span.trace_rowid)
740
- .join(models.Project, onclause=models.Project.id == project_id)
740
+ .where(models.Trace.project_rowid == project_id)
741
741
  .order_by(*order_by)
742
742
  )
743
743
 
@@ -19,7 +19,6 @@ from typing_extensions import Annotated, TypeAlias
19
19
  import phoenix.trace.schemas as trace_schema
20
20
  from phoenix.db import models
21
21
  from phoenix.server.api.context import Context
22
- from phoenix.server.api.dataloaders import types as dataloader_types
23
22
  from phoenix.server.api.helpers.dataset_helpers import (
24
23
  get_dataset_example_input,
25
24
  get_dataset_example_output,
@@ -829,104 +828,6 @@ class Span(Node):
829
828
  for entry in entries
830
829
  ]
831
830
 
832
- @strawberry.field
833
- async def cumulative_cost_summary(self, info: Info[Context, None]) -> Optional[SpanCostSummary]:
834
- max_depth = 0
835
- descendant_rowids = await info.context.data_loaders.span_descendants.load(
836
- (self.span_rowid, max_depth)
837
- )
838
- span_costs = await info.context.data_loaders.span_cost_by_span.load_many(
839
- (self.span_rowid, *descendant_rowids)
840
- )
841
- total_cost: Optional[float] = None
842
- total_tokens: Optional[float] = None
843
- prompt_cost: Optional[float] = None
844
- prompt_tokens: Optional[float] = None
845
- completion_cost: Optional[float] = None
846
- completion_tokens: Optional[float] = None
847
- for span_cost in span_costs:
848
- if span_cost is None:
849
- continue
850
- if span_cost.total_cost is not None:
851
- total_cost = (total_cost or 0) + span_cost.total_cost
852
- if span_cost.total_tokens is not None:
853
- total_tokens = (total_tokens or 0) + span_cost.total_tokens
854
- if span_cost.prompt_cost is not None:
855
- prompt_cost = (prompt_cost or 0) + span_cost.prompt_cost
856
- if span_cost.prompt_tokens is not None:
857
- prompt_tokens = (prompt_tokens or 0) + span_cost.prompt_tokens
858
- if span_cost.completion_cost is not None:
859
- completion_cost = (completion_cost or 0) + span_cost.completion_cost
860
- if span_cost.completion_tokens is not None:
861
- completion_tokens = (completion_tokens or 0) + span_cost.completion_tokens
862
- return SpanCostSummary(
863
- prompt=CostBreakdown(
864
- tokens=prompt_tokens,
865
- cost=prompt_cost,
866
- ),
867
- completion=CostBreakdown(
868
- tokens=completion_tokens,
869
- cost=completion_cost,
870
- ),
871
- total=CostBreakdown(
872
- tokens=total_tokens,
873
- cost=total_cost,
874
- ),
875
- )
876
-
877
- @strawberry.field
878
- async def cumulative_cost_detail_summary_entries(
879
- self, info: Info[Context, None]
880
- ) -> list[SpanCostDetailSummaryEntry]:
881
- max_depth = 0
882
- descendant_rowids = await info.context.data_loaders.span_descendants.load(
883
- (self.span_rowid, max_depth)
884
- )
885
- entry_lists = (
886
- await info.context.data_loaders.span_cost_detail_summary_entries_by_span.load_many(
887
- (self.span_rowid, *descendant_rowids)
888
- )
889
- )
890
-
891
- TokenType: TypeAlias = str
892
- IsPrompt: TypeAlias = bool
893
- grouped_entries: dict[
894
- IsPrompt, dict[TokenType, list[dataloader_types.SpanCostDetailSummaryEntry]]
895
- ] = {}
896
-
897
- for entries in entry_lists:
898
- for entry in entries:
899
- is_prompt = entry.is_prompt
900
- token_type = entry.token_type
901
- if is_prompt not in grouped_entries:
902
- grouped_entries[is_prompt] = {}
903
- if token_type not in grouped_entries[is_prompt]:
904
- grouped_entries[is_prompt][token_type] = []
905
- grouped_entries[is_prompt][token_type].append(entry)
906
-
907
- result: list[SpanCostDetailSummaryEntry] = []
908
- for is_prompt in (True, False):
909
- entries_by_token_type = grouped_entries[is_prompt]
910
- for token_type, entries in sorted(entries_by_token_type.items()):
911
- cost: Optional[float] = None
912
- tokens: Optional[float] = None
913
- for entry in entries:
914
- if entry.value.cost is not None:
915
- cost = (cost or 0) + entry.value.cost
916
- if entry.value.tokens is not None:
917
- tokens = (tokens or 0) + entry.value.tokens
918
- result.append(
919
- SpanCostDetailSummaryEntry(
920
- token_type=token_type,
921
- is_prompt=is_prompt,
922
- value=CostBreakdown(
923
- tokens=tokens,
924
- cost=cost,
925
- ),
926
- )
927
- )
928
- return result
929
-
930
831
 
931
832
  def _hide_embedding_vectors(attributes: Mapping[str, Any]) -> Mapping[str, Any]:
932
833
  if not (
phoenix/server/app.py CHANGED
@@ -386,19 +386,16 @@ async def version() -> PlainTextResponse:
386
386
  return PlainTextResponse(f"{phoenix_version}")
387
387
 
388
388
 
389
- DB_MUTEX: Optional[asyncio.Lock] = None
390
-
391
-
392
389
  def _db(
393
- engine: AsyncEngine, bypass_lock: bool = False
394
- ) -> Callable[[], AbstractAsyncContextManager[AsyncSession]]:
390
+ engine: AsyncEngine,
391
+ ) -> Callable[[Optional[asyncio.Lock]], AbstractAsyncContextManager[AsyncSession]]:
395
392
  Session = async_sessionmaker(engine, expire_on_commit=False)
396
393
 
397
394
  @contextlib.asynccontextmanager
398
- async def factory() -> AsyncIterator[AsyncSession]:
395
+ async def factory(lock: Optional[asyncio.Lock] = None) -> AsyncIterator[AsyncSession]:
399
396
  async with contextlib.AsyncExitStack() as stack:
400
- if not bypass_lock and DB_MUTEX:
401
- await stack.enter_async_context(DB_MUTEX)
397
+ if lock:
398
+ await stack.enter_async_context(lock)
402
399
  yield await stack.enter_async_context(Session.begin())
403
400
 
404
401
  return factory
@@ -542,8 +539,7 @@ def _lifespan(
542
539
  for callback in startup_callbacks:
543
540
  if isinstance((res := callback()), Awaitable):
544
541
  await res
545
- global DB_MUTEX
546
- DB_MUTEX = asyncio.Lock() if db.dialect is SupportedSQLDialect.SQLITE else None
542
+ db.lock = asyncio.Lock() if db.dialect is SupportedSQLDialect.SQLITE else None
547
543
  async with AsyncExitStack() as stack:
548
544
  (
549
545
  enqueue,
@@ -109,7 +109,7 @@ class CostModelLookup:
109
109
  model
110
110
  for model in self._models
111
111
  if (not model.start_time or model.start_time <= start_time)
112
- and model.name_pattern.match(model_name)
112
+ and model.name_pattern.search(model_name)
113
113
  ]
114
114
  if not candidates:
115
115
  return None