Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support pagination on spans resolver #3046

Merged
merged 78 commits into from
May 8, 2024
Merged
Show file tree
Hide file tree
Changes from 60 commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
4709ddb
add test notebook
axiomofjoy May 1, 2024
15bc0cb
refactor: improved summaries with dataloaders (#3039)
RogerHYang May 1, 2024
39926d0
add pagination it notebook
axiomofjoy May 1, 2024
986a140
clean test
axiomofjoy May 1, 2024
16935a4
add helper functions for converting cursors to and from ids
axiomofjoy May 1, 2024
56faea7
add test case for after and first
axiomofjoy May 1, 2024
0c7d4df
add page info to tests
axiomofjoy May 2, 2024
f2a70f3
remove totalCount from PageInfo gql type
axiomofjoy May 2, 2024
6bce63b
nail down test case and understand offset cursors
axiomofjoy May 3, 2024
6e97aa7
implement forward cursor-based pagination with basic support (not tes…
axiomofjoy May 3, 2024
8ae29bf
add failing test cases to test for the correctness of hasNextPage
axiomofjoy May 3, 2024
8501f55
add overfetching to determine whether there's a next page and pass tests
axiomofjoy May 3, 2024
1aa6e2d
add filter condition to span query and format notebook
axiomofjoy May 3, 2024
61177b8
add failing test case for filter condition
axiomofjoy May 3, 2024
2cbc805
fix test case for filtering
axiomofjoy May 3, 2024
da66aa2
basic filtering and sorting test cases
axiomofjoy May 3, 2024
fcbe384
clean tests
axiomofjoy May 3, 2024
0a18e1c
add test case covering attribute filter with cursor
axiomofjoy May 3, 2024
a617752
descending ordering test with cursor
axiomofjoy May 3, 2024
3f7a0a0
add failing test to order by ascending start time with cursor
axiomofjoy May 3, 2024
7b69157
Merge remote-tracking branch 'origin/sql' into pagination
axiomofjoy May 3, 2024
0bf342e
add failing test to order by ascending start time with cursor
axiomofjoy May 4, 2024
7808eff
adapt notebook test cases since we are now ordering by descending row…
axiomofjoy May 4, 2024
92ede3d
pass order by cumulative prompt token count test case
axiomofjoy May 4, 2024
7a59423
rename variable in test notebook
axiomofjoy May 4, 2024
5b88cf8
add cursor serialization and deserialization for floating point sorta…
axiomofjoy May 4, 2024
2126500
refactor to be open to datetime cursor serialization
axiomofjoy May 4, 2024
30a783b
add serialization for datetimes to cursors
axiomofjoy May 4, 2024
c31532c
refactor spans resolver to use new identifier abstraction
axiomofjoy May 4, 2024
a0cbe23
refactor TupleIdentifier to NodeIdentifier
axiomofjoy May 4, 2024
837f30a
fix type error
axiomofjoy May 4, 2024
470c049
add failing test case for order by datetime with cursor
axiomofjoy May 4, 2024
789bcd9
refactor troublesome test case
axiomofjoy May 5, 2024
63d24f8
Merge remote-tracking branch 'origin/sql' into pagination
axiomofjoy May 5, 2024
329c2ad
pass test with order by start time with cursor
axiomofjoy May 5, 2024
3c22691
update node identifier tests with a more granular timestamp
axiomofjoy May 5, 2024
e404fe4
pass test case for order by ascending timestamp with cursor
axiomofjoy May 5, 2024
0cd5ee4
add test case to sort by ascending start time without cursor
axiomofjoy May 5, 2024
1eba507
pass test for pageInfo cursor from order by start time with cursor
axiomofjoy May 5, 2024
389bc5b
ensure fixture spans are inserted in chronological order and don't re…
axiomofjoy May 5, 2024
459fb3c
ensure that queries with sorts but no cursor still return the sorted …
axiomofjoy May 5, 2024
1a04f77
rename variables in tests
axiomofjoy May 5, 2024
4797f2f
allow integer types to be passed into a node identifiers sortable fie…
axiomofjoy May 5, 2024
d2f3536
refactor SpanColumn type to advertise an `orm_expression` property
axiomofjoy May 5, 2024
27577df
add and pass test for floating point order by with cursor
axiomofjoy May 5, 2024
c1ac2f9
refactor map from graphql span column type to orm expressions and rem…
axiomofjoy May 5, 2024
423e354
add support for integer types to node identifier
axiomofjoy May 5, 2024
77ab626
pass tests for order by integer with cursor
axiomofjoy May 6, 2024
0dcc245
paginating by latency working on column parameters
axiomofjoy May 6, 2024
85b08b8
add support for string-based cursors
axiomofjoy May 6, 2024
0427c72
add failing test for order by eval label with cursor
axiomofjoy May 6, 2024
05745ca
add passing tests for order by eval labels with no cursor, both ascen…
axiomofjoy May 6, 2024
2ecc76a
refactor SpanFilter to return result object containing annotation ali…
axiomofjoy May 6, 2024
d8b59de
refactor SpanSort to return result object in preparation for returnin…
axiomofjoy May 6, 2024
81c8f55
fix style
axiomofjoy May 6, 2024
eb06174
Revert "refactor SpanFilter to return result object containing annota…
axiomofjoy May 6, 2024
ced6e20
passing order by descending eval labels with cursor
axiomofjoy May 6, 2024
795d7a7
add test for order by ascending eval labels with cursor
axiomofjoy May 6, 2024
10b6b92
Merge remote-tracking branch 'origin/sql' into pagination
axiomofjoy May 6, 2024
34fefca
Merge remote-tracking branch 'origin/sql' into pagination
axiomofjoy May 7, 2024
5a1a975
rename NodeIdentifier to Cursor
axiomofjoy May 7, 2024
4a20bfc
more refactoring of pagination types
axiomofjoy May 7, 2024
711ed68
more renaming of pagination types
axiomofjoy May 7, 2024
e4e00aa
rename more variables for clarity
axiomofjoy May 7, 2024
3c462b0
rename pagination variables again
axiomofjoy May 7, 2024
e320328
add docstring
axiomofjoy May 7, 2024
f7f7786
fix bug preventing sorts on token counts
axiomofjoy May 7, 2024
d5a96a5
add test for order by hallucination eval score in descending order wi…
axiomofjoy May 7, 2024
d57001e
add test for ascending order by hallucination score
axiomofjoy May 7, 2024
b63426a
revert changes to main
axiomofjoy May 7, 2024
380acee
clean
axiomofjoy May 7, 2024
c5f0cad
rename variable
axiomofjoy May 7, 2024
55fe46e
change type hint
axiomofjoy May 7, 2024
7f4b772
remove unnecessary variable declaration
axiomofjoy May 7, 2024
20ce9e6
remove unnecessary nesting
axiomofjoy May 7, 2024
a8c7d58
nest iter inside context manager, it works outside the context manage…
axiomofjoy May 7, 2024
ae0ac67
ensure that direction of rowid column matches direction of sort column
axiomofjoy May 7, 2024
30f46da
fix bug with token counts
axiomofjoy May 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion app/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,6 @@ type PageInfo {
hasPreviousPage: Boolean!
startCursor: String
endCursor: String
totalCount: Int!
}

enum PerformanceMetric {
Expand Down
220 changes: 220 additions & 0 deletions integration-tests/pagination_queries.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Example Queries for Cursor-Based Pagination"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from phoenix.db import models\n",
"from sqlalchemy import and_, create_engine, select\n",
"from sqlalchemy.orm import aliased, sessionmaker"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"PostgresSession = sessionmaker(\n",
" create_engine(\n",
" \"postgresql+psycopg://localhost:5432/postgres?user=postgres&password=mysecretpassword\",\n",
" echo=True,\n",
" ),\n",
" expire_on_commit=False,\n",
")\n",
"SqliteSession = sessionmaker(\n",
" create_engine(\"sqlite:////Users/xandersong/.phoenix/phoenix.db\", echo=True),\n",
" expire_on_commit=False,\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- filter: None\n",
"- sort: None\n",
"- after: None\n",
"- before: None\n",
"- first: 10\n",
"- last: None"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"page_size = 10\n",
"with SqliteSession() as session:\n",
" span_ids = session.scalars(select(models.Span.id).limit(page_size)).all()\n",
"span_ids"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- filter: None\n",
"- sort: None\n",
"- after: 5\n",
"- before: None\n",
"- first: 10\n",
"- last: None"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"cursor = 10\n",
"page_size = 10\n",
"with SqliteSession() as session:\n",
" span_ids = session.scalars(\n",
" select(models.Span.id).where(models.Span.id >= cursor).limit(page_size)\n",
" ).all()\n",
"span_ids"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- filter: \"\"\"span_kind == 'LLM'\"\"\"\n",
"- sort: None\n",
"- after: 10\n",
"- before: None\n",
"- first: 10\n",
"- last: None"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"cursor = 10\n",
"page_size = 10\n",
"with SqliteSession() as session:\n",
" span_ids = session.scalars(\n",
" select(models.Span.id)\n",
" .where(models.Span.span_kind == \"LLM\")\n",
" .where(models.Span.id >= cursor)\n",
" .limit(page_size)\n",
" ).all()\n",
"span_ids"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- filter: None\n",
"- sort: prompt token count\n",
"- after: 10\n",
"- before: None\n",
"- first: 10\n",
"- last: None"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"cursor = 100\n",
"page_size = 10\n",
"with SqliteSession() as session:\n",
" prompt_tokens = models.Span.attributes[[\"llm\", \"token_count\", \"prompt\"]]\n",
" for index, span in enumerate(\n",
" session.execute(\n",
" select(models.Span.id, prompt_tokens)\n",
" .where(models.Span.id >= cursor)\n",
" .order_by(prompt_tokens, models.Span.id)\n",
" .limit(page_size)\n",
" )\n",
" ):\n",
" print(f\"{index=} {span=}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- filter: attributes[\"llm.prompt.tokens] < 50\n",
"- sort: evals[\"Q&A Correctness\"].score DESC\n",
"- after: 10\n",
"- before: None\n",
"- first: 10\n",
"- last: None"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"span"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"span.attributes[\"llm\"]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"cursor = 100\n",
"page_size = 10\n",
"A = aliased(models.SpanAnnotation, name=\"A\")\n",
"with SqliteSession() as session:\n",
" for index, (span, score) in enumerate(\n",
" session.execute(\n",
" select(models.Span, A.score)\n",
" .join(\n",
" A,\n",
" onclause=and_(\n",
" A.span_rowid == models.Span.id,\n",
" A.name == \"Q&A Correctness\",\n",
" A.annotator_kind == \"LLM\",\n",
" ),\n",
" )\n",
" .where(models.Span.id >= cursor)\n",
" .order_by(A.score.desc(), models.Span.id)\n",
" )\n",
" ):\n",
" print(f\"{index=} {span.id=} {score=}\")"
]
}
],
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Loading
Loading