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

Files changed (73) hide show
  1. {arize_phoenix-12.3.0.dist-info → arize_phoenix-12.5.0.dist-info}/METADATA +2 -1
  2. {arize_phoenix-12.3.0.dist-info → arize_phoenix-12.5.0.dist-info}/RECORD +73 -72
  3. phoenix/auth.py +27 -2
  4. phoenix/config.py +302 -53
  5. phoenix/db/README.md +546 -28
  6. phoenix/db/models.py +3 -3
  7. phoenix/server/api/auth.py +9 -0
  8. phoenix/server/api/context.py +2 -0
  9. phoenix/server/api/dataloaders/__init__.py +2 -0
  10. phoenix/server/api/dataloaders/dataset_dataset_splits.py +52 -0
  11. phoenix/server/api/input_types/ProjectSessionSort.py +158 -1
  12. phoenix/server/api/input_types/SpanSort.py +2 -1
  13. phoenix/server/api/input_types/UserRoleInput.py +1 -0
  14. phoenix/server/api/mutations/annotation_config_mutations.py +6 -6
  15. phoenix/server/api/mutations/api_key_mutations.py +13 -5
  16. phoenix/server/api/mutations/chat_mutations.py +3 -3
  17. phoenix/server/api/mutations/dataset_label_mutations.py +6 -6
  18. phoenix/server/api/mutations/dataset_mutations.py +8 -8
  19. phoenix/server/api/mutations/dataset_split_mutations.py +7 -7
  20. phoenix/server/api/mutations/experiment_mutations.py +2 -2
  21. phoenix/server/api/mutations/export_events_mutations.py +3 -3
  22. phoenix/server/api/mutations/model_mutations.py +4 -4
  23. phoenix/server/api/mutations/project_mutations.py +4 -4
  24. phoenix/server/api/mutations/project_session_annotations_mutations.py +4 -4
  25. phoenix/server/api/mutations/project_trace_retention_policy_mutations.py +8 -4
  26. phoenix/server/api/mutations/prompt_label_mutations.py +7 -7
  27. phoenix/server/api/mutations/prompt_mutations.py +7 -7
  28. phoenix/server/api/mutations/prompt_version_tag_mutations.py +3 -3
  29. phoenix/server/api/mutations/span_annotations_mutations.py +5 -5
  30. phoenix/server/api/mutations/trace_annotations_mutations.py +4 -4
  31. phoenix/server/api/mutations/trace_mutations.py +3 -3
  32. phoenix/server/api/mutations/user_mutations.py +8 -5
  33. phoenix/server/api/routers/auth.py +23 -32
  34. phoenix/server/api/routers/oauth2.py +213 -24
  35. phoenix/server/api/routers/v1/__init__.py +18 -4
  36. phoenix/server/api/routers/v1/annotation_configs.py +19 -30
  37. phoenix/server/api/routers/v1/annotations.py +21 -22
  38. phoenix/server/api/routers/v1/datasets.py +86 -64
  39. phoenix/server/api/routers/v1/documents.py +2 -3
  40. phoenix/server/api/routers/v1/evaluations.py +12 -24
  41. phoenix/server/api/routers/v1/experiment_evaluations.py +2 -3
  42. phoenix/server/api/routers/v1/experiment_runs.py +16 -11
  43. phoenix/server/api/routers/v1/experiments.py +57 -22
  44. phoenix/server/api/routers/v1/projects.py +16 -50
  45. phoenix/server/api/routers/v1/prompts.py +30 -31
  46. phoenix/server/api/routers/v1/sessions.py +2 -5
  47. phoenix/server/api/routers/v1/spans.py +35 -26
  48. phoenix/server/api/routers/v1/traces.py +11 -19
  49. phoenix/server/api/routers/v1/users.py +13 -29
  50. phoenix/server/api/routers/v1/utils.py +3 -7
  51. phoenix/server/api/subscriptions.py +3 -3
  52. phoenix/server/api/types/Dataset.py +95 -6
  53. phoenix/server/api/types/Project.py +24 -68
  54. phoenix/server/app.py +3 -2
  55. phoenix/server/authorization.py +5 -4
  56. phoenix/server/bearer_auth.py +13 -5
  57. phoenix/server/jwt_store.py +8 -6
  58. phoenix/server/oauth2.py +172 -5
  59. phoenix/server/static/.vite/manifest.json +39 -39
  60. phoenix/server/static/assets/{components-Bs8eJEpU.js → components-cwdYEs7B.js} +501 -404
  61. phoenix/server/static/assets/{index-C6WEu5UP.js → index-Dc0vD1Rn.js} +1 -1
  62. phoenix/server/static/assets/{pages-D-n2pkoG.js → pages-BDkB3a_a.js} +577 -533
  63. phoenix/server/static/assets/{vendor-D2eEI-6h.js → vendor-Ce6GTAin.js} +1 -1
  64. phoenix/server/static/assets/{vendor-arizeai-kfOei7nf.js → vendor-arizeai-CSF-1Kc5.js} +1 -1
  65. phoenix/server/static/assets/{vendor-codemirror-1bq_t1Ec.js → vendor-codemirror-Bv8J_7an.js} +3 -3
  66. phoenix/server/static/assets/{vendor-recharts-DQ4xfrf4.js → vendor-recharts-DcLgzI7g.js} +1 -1
  67. phoenix/server/static/assets/{vendor-shiki-GGmcIQxA.js → vendor-shiki-BF8rh_7m.js} +1 -1
  68. phoenix/trace/attributes.py +80 -13
  69. phoenix/version.py +1 -1
  70. {arize_phoenix-12.3.0.dist-info → arize_phoenix-12.5.0.dist-info}/WHEEL +0 -0
  71. {arize_phoenix-12.3.0.dist-info → arize_phoenix-12.5.0.dist-info}/entry_points.txt +0 -0
  72. {arize_phoenix-12.3.0.dist-info → arize_phoenix-12.5.0.dist-info}/licenses/IP_NOTICE +0 -0
  73. {arize_phoenix-12.3.0.dist-info → arize_phoenix-12.5.0.dist-info}/licenses/LICENSE +0 -0
phoenix/db/README.md CHANGED
@@ -82,6 +82,7 @@ erDiagram
82
82
  }
83
83
 
84
84
  ProjectSession ||--o{ Trace : has
85
+ ProjectSession ||--o{ ProjectSessionAnnotation : has
85
86
  ProjectSession {
86
87
  int id PK
87
88
  string session_id
@@ -115,8 +116,8 @@ erDiagram
115
116
  string span_kind
116
117
  datetime start_time
117
118
  datetime end_time
118
- json attributes
119
- json events
119
+ jsonb attributes
120
+ jsonb events
120
121
  string status_code
121
122
  string status_message
122
123
  int cumulative_error_count
@@ -132,7 +133,7 @@ erDiagram
132
133
  int document_position
133
134
  string name
134
135
  string label
135
- float score
136
+ double score
136
137
  string explanation
137
138
  jsonb metadata
138
139
  string annotator_kind
@@ -148,7 +149,7 @@ erDiagram
148
149
  int span_rowid FK
149
150
  string name
150
151
  string label
151
- float score
152
+ double score
152
153
  string explanation
153
154
  jsonb metadata
154
155
  string annotator_kind
@@ -164,7 +165,7 @@ erDiagram
164
165
  int trace_rowid FK
165
166
  string name
166
167
  string label
167
- float score
168
+ double score
168
169
  string explanation
169
170
  jsonb metadata
170
171
  string annotator_kind
@@ -178,6 +179,8 @@ erDiagram
178
179
  Dataset ||--o{ DatasetVersion : has
179
180
  Dataset ||--o{ DatasetExample : contains
180
181
  Dataset ||--o{ Experiment : used_in
182
+ Dataset ||--o{ DatasetsDatasetLabel : has
183
+ Dataset ||--o{ ExperimentTag : tagged_with
181
184
  Dataset {
182
185
  int id PK
183
186
  string name
@@ -185,6 +188,7 @@ erDiagram
185
188
  jsonb metadata
186
189
  datetime created_at
187
190
  datetime updated_at
191
+ bigint user_id FK
188
192
  }
189
193
 
190
194
  DatasetVersion ||--o{ DatasetExampleRevision : has
@@ -195,9 +199,12 @@ erDiagram
195
199
  string description
196
200
  jsonb metadata
197
201
  datetime created_at
202
+ bigint user_id FK
198
203
  }
199
204
 
200
205
  DatasetExample ||--o{ DatasetExampleRevision : has
206
+ DatasetExample ||--o{ DatasetSplitsDatasetExample : belongs_to
207
+ DatasetExample ||--o{ ExperimentsDatasetExample : linked_in
201
208
  DatasetExample {
202
209
  int id PK
203
210
  int dataset_id FK
@@ -205,18 +212,22 @@ erDiagram
205
212
  datetime created_at
206
213
  }
207
214
 
215
+ DatasetExampleRevision ||--o{ ExperimentsDatasetExample : revision_used
208
216
  DatasetExampleRevision {
209
217
  int id PK
210
218
  int dataset_example_id FK
211
219
  int dataset_version_id FK
212
- json input
213
- json output
220
+ jsonb input
221
+ jsonb output
214
222
  jsonb metadata
215
223
  string revision_kind
216
224
  datetime created_at
217
225
  }
218
226
 
219
227
  Experiment ||--o{ ExperimentRun : has
228
+ Experiment ||--o{ ExperimentTag : has
229
+ Experiment ||--o{ ExperimentsDatasetExample : includes
230
+ Experiment ||--o{ ExperimentsDatasetSplit : uses
220
231
  Experiment {
221
232
  int id PK
222
233
  int dataset_id FK
@@ -228,6 +239,7 @@ erDiagram
228
239
  string project_name
229
240
  datetime created_at
230
241
  datetime updated_at
242
+ int user_id FK
231
243
  }
232
244
 
233
245
  ExperimentRun ||--o{ ExperimentRunAnnotation : has
@@ -238,7 +250,7 @@ erDiagram
238
250
  int dataset_example_id FK
239
251
  int repetition_number
240
252
  string trace_id
241
- json output
253
+ jsonb output
242
254
  datetime start_time
243
255
  datetime end_time
244
256
  int prompt_token_count
@@ -252,7 +264,7 @@ erDiagram
252
264
  string name
253
265
  string annotator_kind
254
266
  string label
255
- float score
267
+ double score
256
268
  string explanation
257
269
  string trace_id
258
270
  string error
@@ -261,6 +273,75 @@ erDiagram
261
273
  datetime end_time
262
274
  }
263
275
 
276
+ DatasetSplit ||--o{ DatasetSplitsDatasetExample : contains
277
+ DatasetSplit ||--o{ ExperimentsDatasetSplit : used_in
278
+ DatasetSplit {
279
+ bigint id PK
280
+ string name
281
+ string description
282
+ string color
283
+ jsonb metadata
284
+ datetime created_at
285
+ datetime updated_at
286
+ bigint user_id FK
287
+ }
288
+
289
+ DatasetSplitsDatasetExample {
290
+ bigint dataset_split_id FK
291
+ bigint dataset_example_id FK
292
+ }
293
+
294
+ DatasetLabel ||--o{ DatasetsDatasetLabel : applies_to
295
+ DatasetLabel {
296
+ bigint id PK
297
+ string name
298
+ string description
299
+ string color
300
+ bigint user_id FK
301
+ }
302
+
303
+ DatasetsDatasetLabel {
304
+ int id PK
305
+ int dataset_id FK
306
+ int dataset_label_id FK
307
+ }
308
+
309
+ ExperimentTag {
310
+ bigint id PK
311
+ bigint experiment_id FK
312
+ bigint dataset_id FK
313
+ string name
314
+ string description
315
+ bigint user_id FK
316
+ }
317
+
318
+ ExperimentsDatasetExample {
319
+ bigint experiment_id FK
320
+ bigint dataset_example_id FK
321
+ bigint dataset_example_revision_id FK
322
+ }
323
+
324
+ ExperimentsDatasetSplit {
325
+ bigint experiment_id FK
326
+ bigint dataset_split_id FK
327
+ }
328
+
329
+ ProjectSessionAnnotation {
330
+ bigint id PK
331
+ bigint project_session_id FK
332
+ string name
333
+ string label
334
+ double score
335
+ string explanation
336
+ jsonb metadata
337
+ string annotator_kind
338
+ bigint user_id FK
339
+ string identifier
340
+ string source
341
+ datetime created_at
342
+ datetime updated_at
343
+ }
344
+
264
345
  User ||--o{ ApiKey : has
265
346
  User ||--o{ AccessToken : has
266
347
  User ||--o{ RefreshToken : has
@@ -270,6 +351,13 @@ erDiagram
270
351
  User ||--o{ SpanAnnotation : has
271
352
  User ||--o{ DocumentAnnotation : has
272
353
  User ||--o{ TraceAnnotation : has
354
+ User ||--o{ ProjectSessionAnnotation : has
355
+ User ||--o{ Experiment : creates
356
+ User ||--o{ ExperimentTag : creates
357
+ User ||--o{ DatasetLabel : creates
358
+ User ||--o{ Dataset : creates
359
+ User ||--o{ DatasetVersion : creates
360
+ User ||--o{ DatasetSplit : creates
273
361
  User {
274
362
  int id PK
275
363
  int user_role_id FK
@@ -395,7 +483,7 @@ erDiagram
395
483
  GenerativeModel ||--o{ TokenPrice : has
396
484
  GenerativeModel ||--o{ SpanCost : used_in
397
485
  GenerativeModel {
398
- int id PK
486
+ bigint id PK
399
487
  string name
400
488
  string provider
401
489
  string name_pattern
@@ -407,36 +495,466 @@ erDiagram
407
495
  }
408
496
 
409
497
  TokenPrice {
410
- int id PK
411
- int model_id FK
498
+ bigint id PK
499
+ bigint model_id FK
412
500
  string token_type
413
501
  boolean is_prompt
414
- float base_rate
502
+ double base_rate
415
503
  json customization
416
504
  }
417
505
 
418
506
  SpanCost ||--o{ SpanCostDetail : has
419
507
  SpanCost {
420
- int id PK
421
- int span_rowid FK
422
- int trace_rowid FK
423
- int model_id FK
508
+ bigint id PK
509
+ bigint span_rowid FK
510
+ bigint trace_rowid FK
511
+ bigint model_id FK
424
512
  datetime span_start_time
425
- float total_cost
426
- float total_tokens
427
- float prompt_cost
428
- float prompt_tokens
429
- float completion_cost
430
- float completion_tokens
513
+ double total_cost
514
+ double total_tokens
515
+ double prompt_cost
516
+ double prompt_tokens
517
+ double completion_cost
518
+ double completion_tokens
431
519
  }
432
520
 
433
521
  SpanCostDetail {
434
- int id PK
435
- int span_cost_id FK
522
+ bigint id PK
523
+ bigint span_cost_id FK
436
524
  string token_type
437
525
  boolean is_prompt
438
- float cost
439
- float tokens
440
- float cost_per_token
526
+ double cost
527
+ double tokens
528
+ double cost_per_token
529
+ }
530
+ ```
531
+
532
+ ---
533
+
534
+ ## Focused Relationship Views
535
+
536
+ > **Note**: The following subsection diagrams show simplified table structures focusing only on foreign keys to highlight relationships. These tables contain additional columns (including primary keys and other fields) not shown here - refer to the comprehensive ERD above for complete table definitions.
537
+
538
+ ### Core Tracing & Projects
539
+
540
+ This subgroup represents the core functionality of Phoenix - projects organize traces into sessions, traces contain spans, and retention policies manage data lifecycle:
541
+
542
+ ```mermaid
543
+ erDiagram
544
+ ProjectTraceRetentionPolicy ||--o{ Project : applied_to
545
+ ProjectTraceRetentionPolicy {
546
+ }
547
+
548
+ Project ||--o{ ProjectSession : has
549
+ Project ||--o{ Trace : has
550
+ Project {
551
+ int trace_retention_policy_id FK
552
+ }
553
+
554
+ ProjectSession ||--o{ Trace : has
555
+ ProjectSession {
556
+ int project_id FK
557
+ }
558
+
559
+ Trace ||--o{ Span : contains
560
+ Trace {
561
+ int project_rowid FK
562
+ int project_session_rowid FK
563
+ }
564
+
565
+ Span {
566
+ int trace_rowid FK
567
+ string parent_id
568
+ }
569
+ ```
570
+
571
+ ### Datasets & Data Management
572
+
573
+ This subgroup shows how datasets are created from spans, organized with versions and splits, and labeled for better organization:
574
+
575
+ ```mermaid
576
+ erDiagram
577
+ User ||--o{ DatasetLabel : creates
578
+ User ||--o{ Dataset : creates
579
+ User ||--o{ DatasetSplit : creates
580
+ User ||--o{ DatasetVersion : creates
581
+ User {
582
+ }
583
+
584
+ Trace ||--o{ Span : contains
585
+ Trace {
586
+ }
587
+
588
+ Span ||--o{ DatasetExample : becomes
589
+ Span {
590
+ int trace_rowid FK
591
+ }
592
+
593
+ Dataset ||--o{ DatasetVersion : has
594
+ Dataset ||--o{ DatasetExample : contains
595
+ Dataset ||--o{ DatasetsDatasetLabel : has
596
+ Dataset {
597
+ bigint user_id FK
598
+ }
599
+
600
+ DatasetVersion ||--o{ DatasetExampleRevision : has
601
+ DatasetVersion {
602
+ int dataset_id FK
603
+ bigint user_id FK
604
+ }
605
+
606
+ DatasetExample ||--o{ DatasetExampleRevision : has
607
+ DatasetExample ||--o{ DatasetSplitsDatasetExample : belongs_to
608
+ DatasetExample {
609
+ int dataset_id FK
610
+ int span_rowid FK
611
+ }
612
+
613
+ DatasetExampleRevision {
614
+ int dataset_example_id FK
615
+ int dataset_version_id FK
616
+ }
617
+
618
+ DatasetSplit ||--o{ DatasetSplitsDatasetExample : contains
619
+ DatasetSplit {
620
+ bigint user_id FK
621
+ }
622
+
623
+ DatasetSplitsDatasetExample {
624
+ bigint dataset_split_id FK
625
+ bigint dataset_example_id FK
626
+ }
627
+
628
+ DatasetLabel ||--o{ DatasetsDatasetLabel : applies_to
629
+ DatasetLabel {
630
+ bigint user_id FK
631
+ }
632
+
633
+ DatasetsDatasetLabel {
634
+ int dataset_id FK
635
+ int dataset_label_id FK
636
+ }
637
+ ```
638
+
639
+ ### Experiments & Evaluation
640
+
641
+ This subgroup shows how experiments use datasets to run evaluations, track results, and organize findings with tags and annotations:
642
+
643
+ ```mermaid
644
+ erDiagram
645
+ User ||--o{ Experiment : creates
646
+ User ||--o{ ExperimentTag : creates
647
+ User {
648
+ }
649
+
650
+ Dataset ||--o{ Experiment : used_in
651
+ Dataset {
652
+ }
653
+
654
+ DatasetVersion ||--o{ Experiment : used_in
655
+ DatasetVersion {
656
+ }
657
+
658
+ DatasetExample ||--o{ ExperimentRun : used_in
659
+ DatasetExample ||--o{ ExperimentsDatasetExample : linked_in
660
+ DatasetExample {
661
+ }
662
+
663
+ DatasetExampleRevision ||--o{ ExperimentsDatasetExample : revision_used
664
+ DatasetExampleRevision {
665
+ }
666
+
667
+ DatasetSplit ||--o{ ExperimentsDatasetSplit : used_in
668
+ DatasetSplit {
669
+ }
670
+
671
+ Experiment ||--o{ ExperimentRun : has
672
+ Experiment ||--o{ ExperimentTag : has
673
+ Experiment ||--o{ ExperimentsDatasetExample : includes
674
+ Experiment ||--o{ ExperimentsDatasetSplit : uses
675
+ Experiment {
676
+ int dataset_id FK
677
+ int dataset_version_id FK
678
+ bigint user_id FK
679
+ }
680
+
681
+ ExperimentRun ||--o{ ExperimentRunAnnotation : has
682
+ ExperimentRun {
683
+ int experiment_id FK
684
+ int dataset_example_id FK
685
+ string trace_id
686
+ }
687
+
688
+ ExperimentRunAnnotation {
689
+ int experiment_run_id FK
690
+ }
691
+
692
+ ExperimentTag {
693
+ bigint experiment_id FK
694
+ bigint dataset_id FK
695
+ bigint user_id FK
696
+ }
697
+
698
+ ExperimentsDatasetExample {
699
+ bigint experiment_id FK
700
+ bigint dataset_example_id FK
701
+ bigint dataset_example_revision_id FK
702
+ }
703
+
704
+ ExperimentsDatasetSplit {
705
+ bigint experiment_id FK
706
+ bigint dataset_split_id FK
707
+ }
708
+ ```
709
+
710
+ ### User Management & Authentication
711
+
712
+ This subgroup shows how users are managed with roles and different authentication methods:
713
+
714
+ ```mermaid
715
+ erDiagram
716
+ UserRole ||--o{ User : has
717
+ UserRole {
718
+ }
719
+
720
+ User ||--o{ ApiKey : has
721
+ User ||--o{ AccessToken : has
722
+ User ||--o{ RefreshToken : has
723
+ User ||--o{ PasswordResetToken : has
724
+ User {
725
+ int user_role_id FK
726
+ }
727
+
728
+ ApiKey {
729
+ int user_id FK
730
+ }
731
+
732
+ RefreshToken ||--o| AccessToken : creates
733
+ RefreshToken {
734
+ int user_id FK
735
+ }
736
+
737
+ AccessToken {
738
+ int user_id FK
739
+ int refresh_token_id FK
740
+ }
741
+
742
+ PasswordResetToken {
743
+ int user_id FK
744
+ }
745
+ ```
746
+
747
+ ### Annotations
748
+
749
+ This subgroup shows how annotations are attached to spans, documents, traces, and project sessions, including their configuration:
750
+
751
+ ```mermaid
752
+ erDiagram
753
+ Project ||--o{ ProjectAnnotationConfig : has
754
+ Project ||--o{ ProjectSession : has
755
+ Project ||--o{ Trace : has
756
+ Project {
757
+ }
758
+
759
+ ProjectSession ||--o{ ProjectSessionAnnotation : has
760
+ ProjectSession {
761
+ int project_id FK
762
+ }
763
+
764
+ Trace ||--o{ Span : contains
765
+ Trace ||--o{ TraceAnnotation : has
766
+ Trace {
767
+ int project_rowid FK
768
+ }
769
+
770
+ Span ||--o{ SpanAnnotation : has
771
+ Span ||--o{ DocumentAnnotation : has
772
+ Span {
773
+ int trace_rowid FK
774
+ }
775
+
776
+ User ||--o{ SpanAnnotation : creates
777
+ User ||--o{ DocumentAnnotation : creates
778
+ User ||--o{ TraceAnnotation : creates
779
+ User ||--o{ ProjectSessionAnnotation : creates
780
+ User {
781
+ }
782
+
783
+ AnnotationConfig ||--o{ ProjectAnnotationConfig : configures
784
+ AnnotationConfig {
785
+ }
786
+
787
+ ProjectAnnotationConfig {
788
+ int project_id FK
789
+ int annotation_config_id FK
790
+ }
791
+
792
+ SpanAnnotation {
793
+ int span_rowid FK
794
+ int user_id FK
795
+ }
796
+
797
+ DocumentAnnotation {
798
+ int span_rowid FK
799
+ int user_id FK
800
+ }
801
+
802
+ TraceAnnotation {
803
+ int trace_rowid FK
804
+ int user_id FK
805
+ }
806
+
807
+ ProjectSessionAnnotation {
808
+ bigint project_session_id FK
809
+ bigint user_id FK
810
+ }
811
+ ```
812
+
813
+ ### Prompts
814
+
815
+ This subgroup shows how users create and manage prompt templates, versions, labels, and tags:
816
+
817
+ ```mermaid
818
+ erDiagram
819
+ User ||--o{ PromptVersion : creates
820
+ User ||--o{ PromptVersionTag : creates
821
+ User {
822
+ }
823
+
824
+ Prompt ||--o{ PromptVersion : has
825
+ Prompt ||--o{ PromptPromptLabel : has
826
+ Prompt ||--o{ PromptVersionTag : has
827
+ Prompt ||--o{ Prompt : derived_from
828
+ Prompt {
829
+ int source_prompt_id FK
830
+ }
831
+
832
+ PromptVersion ||--o{ PromptVersionTag : has
833
+ PromptVersion {
834
+ int prompt_id FK
835
+ int user_id FK
836
+ }
837
+
838
+ PromptLabel ||--o{ PromptPromptLabel : has
839
+ PromptLabel {
840
+ }
841
+
842
+ PromptPromptLabel {
843
+ int prompt_label_id FK
844
+ int prompt_id FK
845
+ }
846
+
847
+ PromptVersionTag {
848
+ int prompt_id FK
849
+ int prompt_version_id FK
850
+ int user_id FK
851
+ }
852
+ ```
853
+
854
+ ### Cost & Pricing
855
+
856
+ This subgroup shows how LLM costs are calculated and tracked for spans and traces:
857
+
858
+ ```mermaid
859
+ erDiagram
860
+ Trace ||--o{ Span : contains
861
+ Trace ||--o{ SpanCost : tracks
862
+ Trace {
863
+ }
864
+
865
+ Span ||--o{ SpanCost : generates
866
+ Span {
867
+ int trace_rowid FK
868
+ }
869
+
870
+ GenerativeModel ||--o{ TokenPrice : defines
871
+ GenerativeModel ||--o{ SpanCost : calculates
872
+ GenerativeModel {
873
+ }
874
+
875
+ TokenPrice {
876
+ bigint model_id FK
877
+ }
878
+
879
+ SpanCost ||--o{ SpanCostDetail : has
880
+ SpanCost {
881
+ bigint span_rowid FK
882
+ bigint trace_rowid FK
883
+ bigint model_id FK
884
+ }
885
+
886
+ SpanCostDetail {
887
+ bigint span_cost_id FK
441
888
  }
442
889
  ```
890
+
891
+ ### User-Created Content
892
+
893
+ This subgroup shows all entities that track user ownership through user_id foreign keys, representing content created or managed by users across datasets, experiments, prompts, and annotations:
894
+
895
+ ```mermaid
896
+ erDiagram
897
+ User ||--o{ Dataset : creates
898
+ User ||--o{ DatasetVersion : creates
899
+ User ||--o{ DatasetSplit : creates
900
+ User ||--o{ DatasetLabel : creates
901
+ User ||--o{ Experiment : creates
902
+ User ||--o{ ExperimentTag : creates
903
+ User ||--o{ PromptVersion : creates
904
+ User ||--o{ PromptVersionTag : creates
905
+ User ||--o{ SpanAnnotation : creates
906
+ User ||--o{ DocumentAnnotation : creates
907
+ User ||--o{ TraceAnnotation : creates
908
+ User ||--o{ ProjectSessionAnnotation : creates
909
+ User {
910
+ }
911
+
912
+ Dataset {
913
+ bigint user_id FK
914
+ }
915
+
916
+ DatasetVersion {
917
+ bigint user_id FK
918
+ }
919
+
920
+ DatasetSplit {
921
+ bigint user_id FK
922
+ }
923
+
924
+ DatasetLabel {
925
+ bigint user_id FK
926
+ }
927
+
928
+ Experiment {
929
+ bigint user_id FK
930
+ }
931
+
932
+ ExperimentTag {
933
+ bigint user_id FK
934
+ }
935
+
936
+ PromptVersion {
937
+ int user_id FK
938
+ }
939
+
940
+ PromptVersionTag {
941
+ int user_id FK
942
+ }
943
+
944
+ SpanAnnotation {
945
+ int user_id FK
946
+ }
947
+
948
+ DocumentAnnotation {
949
+ int user_id FK
950
+ }
951
+
952
+ TraceAnnotation {
953
+ int user_id FK
954
+ }
955
+
956
+ ProjectSessionAnnotation {
957
+ bigint user_id FK
958
+ }
959
+ ```
960
+
phoenix/db/models.py CHANGED
@@ -1607,7 +1607,7 @@ class PasswordResetToken(HasId):
1607
1607
  )
1608
1608
  user: Mapped["User"] = relationship("User", back_populates="password_reset_token")
1609
1609
  created_at: Mapped[datetime] = mapped_column(UtcTimeStamp, server_default=func.now())
1610
- expires_at: Mapped[Optional[datetime]] = mapped_column(UtcTimeStamp, nullable=False, index=True)
1610
+ expires_at: Mapped[datetime] = mapped_column(UtcTimeStamp, nullable=False, index=True)
1611
1611
  __table_args__ = (dict(sqlite_autoincrement=True),)
1612
1612
 
1613
1613
 
@@ -1619,7 +1619,7 @@ class RefreshToken(HasId):
1619
1619
  )
1620
1620
  user: Mapped["User"] = relationship("User", back_populates="refresh_tokens")
1621
1621
  created_at: Mapped[datetime] = mapped_column(UtcTimeStamp, server_default=func.now())
1622
- expires_at: Mapped[Optional[datetime]] = mapped_column(UtcTimeStamp, nullable=False, index=True)
1622
+ expires_at: Mapped[datetime] = mapped_column(UtcTimeStamp, nullable=False, index=True)
1623
1623
  __table_args__ = (dict(sqlite_autoincrement=True),)
1624
1624
 
1625
1625
 
@@ -1631,7 +1631,7 @@ class AccessToken(HasId):
1631
1631
  )
1632
1632
  user: Mapped["User"] = relationship("User", back_populates="access_tokens")
1633
1633
  created_at: Mapped[datetime] = mapped_column(UtcTimeStamp, server_default=func.now())
1634
- expires_at: Mapped[Optional[datetime]] = mapped_column(UtcTimeStamp, nullable=False, index=True)
1634
+ expires_at: Mapped[datetime] = mapped_column(UtcTimeStamp, nullable=False, index=True)
1635
1635
  refresh_token_id: Mapped[int] = mapped_column(
1636
1636
  ForeignKey("refresh_tokens.id", ondelete="CASCADE"),
1637
1637
  index=True,