arize-phoenix 4.26.0__py3-none-any.whl → 4.28.1__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.
- {arize_phoenix-4.26.0.dist-info → arize_phoenix-4.28.1.dist-info}/METADATA +2 -3
- {arize_phoenix-4.26.0.dist-info → arize_phoenix-4.28.1.dist-info}/RECORD +22 -22
- phoenix/auth.py +3 -0
- phoenix/inferences/fixtures.py +14 -8
- phoenix/server/api/context.py +10 -1
- phoenix/server/api/mutations/__init__.py +4 -2
- phoenix/server/api/mutations/auth_mutations.py +63 -0
- phoenix/server/api/routers/v1/experiments.py +55 -1
- phoenix/server/api/routers/v1/utils.py +2 -2
- phoenix/server/app.py +149 -29
- phoenix/server/main.py +71 -7
- phoenix/server/static/.vite/manifest.json +9 -9
- phoenix/server/static/assets/{components-1Ahruijo.js → components-BYH03rjA.js} +108 -100
- phoenix/server/static/assets/index-fqdjNpYm.js +100 -0
- phoenix/server/static/assets/{pages-CFS6mPnW.js → pages-DnbxgoTK.js} +271 -215
- phoenix/session/client.py +17 -1
- phoenix/trace/dsl/helpers.py +3 -1
- phoenix/trace/fixtures.py +47 -4
- phoenix/version.py +1 -1
- phoenix/server/api/routers/auth.py +0 -52
- phoenix/server/static/assets/index-BEE_RWJx.js +0 -100
- {arize_phoenix-4.26.0.dist-info → arize_phoenix-4.28.1.dist-info}/WHEEL +0 -0
- {arize_phoenix-4.26.0.dist-info → arize_phoenix-4.28.1.dist-info}/licenses/IP_NOTICE +0 -0
- {arize_phoenix-4.26.0.dist-info → arize_phoenix-4.28.1.dist-info}/licenses/LICENSE +0 -0
phoenix/server/app.py
CHANGED
|
@@ -2,6 +2,7 @@ import asyncio
|
|
|
2
2
|
import contextlib
|
|
3
3
|
import json
|
|
4
4
|
import logging
|
|
5
|
+
from datetime import datetime, timedelta, timezone
|
|
5
6
|
from functools import cached_property
|
|
6
7
|
from pathlib import Path
|
|
7
8
|
from types import MethodType
|
|
@@ -10,12 +11,14 @@ from typing import (
|
|
|
10
11
|
Any,
|
|
11
12
|
AsyncContextManager,
|
|
12
13
|
AsyncIterator,
|
|
14
|
+
Awaitable,
|
|
13
15
|
Callable,
|
|
14
16
|
Dict,
|
|
15
17
|
Iterable,
|
|
16
18
|
List,
|
|
17
19
|
NamedTuple,
|
|
18
20
|
Optional,
|
|
21
|
+
Set,
|
|
19
22
|
Tuple,
|
|
20
23
|
Union,
|
|
21
24
|
cast,
|
|
@@ -26,11 +29,8 @@ from fastapi import APIRouter, FastAPI
|
|
|
26
29
|
from fastapi.middleware.gzip import GZipMiddleware
|
|
27
30
|
from fastapi.responses import FileResponse
|
|
28
31
|
from fastapi.utils import is_body_allowed_for_status_code
|
|
29
|
-
from sqlalchemy
|
|
30
|
-
|
|
31
|
-
AsyncSession,
|
|
32
|
-
async_sessionmaker,
|
|
33
|
-
)
|
|
32
|
+
from sqlalchemy import select
|
|
33
|
+
from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, async_sessionmaker
|
|
34
34
|
from starlette.datastructures import State as StarletteState
|
|
35
35
|
from starlette.exceptions import HTTPException
|
|
36
36
|
from starlette.middleware import Middleware
|
|
@@ -46,12 +46,9 @@ from typing_extensions import TypeAlias
|
|
|
46
46
|
|
|
47
47
|
import phoenix
|
|
48
48
|
import phoenix.trace.v1 as pb
|
|
49
|
-
from phoenix.config import
|
|
50
|
-
DEFAULT_PROJECT_NAME,
|
|
51
|
-
SERVER_DIR,
|
|
52
|
-
server_instrumentation_is_enabled,
|
|
53
|
-
)
|
|
49
|
+
from phoenix.config import DEFAULT_PROJECT_NAME, SERVER_DIR, server_instrumentation_is_enabled
|
|
54
50
|
from phoenix.core.model_schema import Model
|
|
51
|
+
from phoenix.db import models
|
|
55
52
|
from phoenix.db.bulk_inserter import BulkInserter
|
|
56
53
|
from phoenix.db.engines import create_engine
|
|
57
54
|
from phoenix.db.helpers import SupportedSQLDialect
|
|
@@ -82,7 +79,6 @@ from phoenix.server.api.dataloaders import (
|
|
|
82
79
|
TokenCountDataLoader,
|
|
83
80
|
TraceRowIdsDataLoader,
|
|
84
81
|
)
|
|
85
|
-
from phoenix.server.api.routers.auth import router as auth_router
|
|
86
82
|
from phoenix.server.api.routers.v1 import REST_API_VERSION
|
|
87
83
|
from phoenix.server.api.routers.v1 import router as v1_router
|
|
88
84
|
from phoenix.server.api.schema import schema
|
|
@@ -93,9 +89,17 @@ from phoenix.server.telemetry import initialize_opentelemetry_tracer_provider
|
|
|
93
89
|
from phoenix.server.types import (
|
|
94
90
|
CanGetLastUpdatedAt,
|
|
95
91
|
CanPutItem,
|
|
92
|
+
DaemonTask,
|
|
96
93
|
DbSessionFactory,
|
|
97
94
|
LastUpdatedAt,
|
|
98
95
|
)
|
|
96
|
+
from phoenix.trace.fixtures import (
|
|
97
|
+
get_evals_from_fixture,
|
|
98
|
+
get_trace_fixture_by_name,
|
|
99
|
+
load_example_traces,
|
|
100
|
+
reset_fixture_span_ids_and_timestamps,
|
|
101
|
+
)
|
|
102
|
+
from phoenix.trace.otel import decode_otlp_span, encode_span_to_otlp
|
|
99
103
|
from phoenix.trace.schemas import Span
|
|
100
104
|
from phoenix.utilities.client import PHOENIX_SERVER_VERSION_HEADER
|
|
101
105
|
|
|
@@ -103,12 +107,23 @@ if TYPE_CHECKING:
|
|
|
103
107
|
from opentelemetry.trace import TracerProvider
|
|
104
108
|
|
|
105
109
|
logger = logging.getLogger(__name__)
|
|
110
|
+
logger.setLevel(logging.INFO)
|
|
106
111
|
logger.addHandler(logging.NullHandler())
|
|
107
112
|
|
|
108
113
|
router = APIRouter(include_in_schema=False)
|
|
109
114
|
|
|
110
115
|
templates = Jinja2Templates(directory=SERVER_DIR / "templates")
|
|
111
116
|
|
|
117
|
+
"""
|
|
118
|
+
Threshold (in minutes) to determine if database is booted up for the first time.
|
|
119
|
+
|
|
120
|
+
Used to assess whether the `default` project was created recently.
|
|
121
|
+
If so, demo data is automatically ingested upon initial boot up to populate the database.
|
|
122
|
+
"""
|
|
123
|
+
NEW_DB_AGE_THRESHOLD_MINUTES = 2
|
|
124
|
+
|
|
125
|
+
ProjectName: TypeAlias = str
|
|
126
|
+
|
|
112
127
|
|
|
113
128
|
class AppConfig(NamedTuple):
|
|
114
129
|
has_inferences: bool
|
|
@@ -226,9 +241,99 @@ def _db(engine: AsyncEngine) -> Callable[[], AsyncContextManager[AsyncSession]]:
|
|
|
226
241
|
return factory
|
|
227
242
|
|
|
228
243
|
|
|
244
|
+
class Scaffolder(DaemonTask):
|
|
245
|
+
def __init__(
|
|
246
|
+
self,
|
|
247
|
+
db: DbSessionFactory,
|
|
248
|
+
queue_span: Callable[[Span, ProjectName], Awaitable[None]],
|
|
249
|
+
queue_evaluation: Callable[[pb.Evaluation], Awaitable[None]],
|
|
250
|
+
tracing_fixture_names: Set[str] = set(),
|
|
251
|
+
force_fixture_ingestion: bool = False,
|
|
252
|
+
) -> None:
|
|
253
|
+
super().__init__()
|
|
254
|
+
self._db = db
|
|
255
|
+
self._queue_span = queue_span
|
|
256
|
+
self._queue_evaluation = queue_evaluation
|
|
257
|
+
self._tracing_fixtures = set(
|
|
258
|
+
get_trace_fixture_by_name(name) for name in tracing_fixture_names
|
|
259
|
+
)
|
|
260
|
+
self._force_fixture_ingestion = force_fixture_ingestion
|
|
261
|
+
|
|
262
|
+
async def __aenter__(self) -> None:
|
|
263
|
+
await self.start()
|
|
264
|
+
|
|
265
|
+
async def __aexit__(self, *args: Any, **kwargs: Any) -> None:
|
|
266
|
+
await self.stop()
|
|
267
|
+
|
|
268
|
+
async def _run(self) -> None:
|
|
269
|
+
"""
|
|
270
|
+
Main entry point for Scaffolder.
|
|
271
|
+
Determines whether to load fixtures and handles them.
|
|
272
|
+
"""
|
|
273
|
+
if await self._should_load_fixtures():
|
|
274
|
+
logger.info("Loading trace fixtures.")
|
|
275
|
+
await self._handle_tracing_fixtures()
|
|
276
|
+
logger.info("Finished loading fixtures.")
|
|
277
|
+
else:
|
|
278
|
+
logger.info("DB is not new, avoid loading demo fixtures.")
|
|
279
|
+
|
|
280
|
+
async def _should_load_fixtures(self) -> bool:
|
|
281
|
+
if self._force_fixture_ingestion:
|
|
282
|
+
return True
|
|
283
|
+
|
|
284
|
+
async with self._db() as session:
|
|
285
|
+
created_at = await session.scalar(
|
|
286
|
+
select(models.Project.created_at).where(models.Project.name == "default")
|
|
287
|
+
)
|
|
288
|
+
if created_at is None:
|
|
289
|
+
return False
|
|
290
|
+
|
|
291
|
+
is_new_db = datetime.now(timezone.utc) - created_at < timedelta(
|
|
292
|
+
minutes=NEW_DB_AGE_THRESHOLD_MINUTES
|
|
293
|
+
)
|
|
294
|
+
return is_new_db
|
|
295
|
+
|
|
296
|
+
async def _handle_tracing_fixtures(self) -> None:
|
|
297
|
+
"""
|
|
298
|
+
Main handler for processing trace fixtures. Process each fixture by
|
|
299
|
+
loading its trace dataframe, gettting and processings its
|
|
300
|
+
spans and evals, and queuing.
|
|
301
|
+
"""
|
|
302
|
+
loop = asyncio.get_running_loop()
|
|
303
|
+
for fixture in self._tracing_fixtures:
|
|
304
|
+
try:
|
|
305
|
+
trace_ds = await loop.run_in_executor(None, load_example_traces, fixture.name)
|
|
306
|
+
|
|
307
|
+
fixture_spans, fixture_evals = await loop.run_in_executor(
|
|
308
|
+
None,
|
|
309
|
+
reset_fixture_span_ids_and_timestamps,
|
|
310
|
+
(
|
|
311
|
+
# Apply `encode` here because legacy jsonl files contains UUIDs as strings.
|
|
312
|
+
# `encode` removes the hyphens in the UUIDs.
|
|
313
|
+
decode_otlp_span(encode_span_to_otlp(span))
|
|
314
|
+
for span in trace_ds.to_spans()
|
|
315
|
+
),
|
|
316
|
+
get_evals_from_fixture(fixture.name),
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
project_name = fixture.project_name or fixture.name
|
|
320
|
+
logger.info(f"Loading '{project_name}' fixtures...")
|
|
321
|
+
for span in fixture_spans:
|
|
322
|
+
await self._queue_span(span, project_name)
|
|
323
|
+
for evaluation in fixture_evals:
|
|
324
|
+
await self._queue_evaluation(evaluation)
|
|
325
|
+
|
|
326
|
+
except FileNotFoundError:
|
|
327
|
+
logger.warning(f"Fixture file not found for '{fixture.name}'")
|
|
328
|
+
except ValueError as e:
|
|
329
|
+
logger.error(f"Error processing fixture '{fixture.name}': {e}")
|
|
330
|
+
except Exception as e:
|
|
331
|
+
logger.error(f"Unexpected error processing fixture '{fixture.name}': {e}")
|
|
332
|
+
|
|
333
|
+
|
|
229
334
|
def _lifespan(
|
|
230
335
|
*,
|
|
231
|
-
|
|
336
|
+
db: DbSessionFactory,
|
|
232
337
|
bulk_inserter: BulkInserter,
|
|
233
338
|
dml_event_handler: DmlEventHandler,
|
|
234
339
|
tracer_provider: Optional["TracerProvider"] = None,
|
|
@@ -236,11 +341,13 @@ def _lifespan(
|
|
|
236
341
|
startup_callbacks: Iterable[Callable[[], None]] = (),
|
|
237
342
|
shutdown_callbacks: Iterable[Callable[[], None]] = (),
|
|
238
343
|
read_only: bool = False,
|
|
344
|
+
tracing_fixture_names: Set[str] = set(),
|
|
345
|
+
force_fixture_ingestion: bool = False,
|
|
239
346
|
) -> StatefulLifespan[FastAPI]:
|
|
240
347
|
@contextlib.asynccontextmanager
|
|
241
348
|
async def lifespan(_: FastAPI) -> AsyncIterator[Dict[str, Any]]:
|
|
242
349
|
global DB_MUTEX
|
|
243
|
-
DB_MUTEX = asyncio.Lock() if dialect is SupportedSQLDialect.SQLITE else None
|
|
350
|
+
DB_MUTEX = asyncio.Lock() if db.dialect is SupportedSQLDialect.SQLITE else None
|
|
244
351
|
async with bulk_inserter as (
|
|
245
352
|
enqueue,
|
|
246
353
|
queue_span,
|
|
@@ -251,7 +358,13 @@ def _lifespan(
|
|
|
251
358
|
disabled=read_only,
|
|
252
359
|
tracer_provider=tracer_provider,
|
|
253
360
|
enable_prometheus=enable_prometheus,
|
|
254
|
-
), dml_event_handler
|
|
361
|
+
), dml_event_handler, Scaffolder(
|
|
362
|
+
db=db,
|
|
363
|
+
queue_span=queue_span,
|
|
364
|
+
queue_evaluation=queue_evaluation,
|
|
365
|
+
tracing_fixture_names=tracing_fixture_names,
|
|
366
|
+
force_fixture_ingestion=force_fixture_ingestion,
|
|
367
|
+
):
|
|
255
368
|
for callback in startup_callbacks:
|
|
256
369
|
callback()
|
|
257
370
|
yield {
|
|
@@ -317,17 +430,19 @@ def create_graphql_router(
|
|
|
317
430
|
dataset_example_spans=DatasetExampleSpansDataLoader(db),
|
|
318
431
|
document_evaluation_summaries=DocumentEvaluationSummaryDataLoader(
|
|
319
432
|
db,
|
|
320
|
-
cache_map=
|
|
321
|
-
|
|
322
|
-
|
|
433
|
+
cache_map=(
|
|
434
|
+
cache_for_dataloaders.document_evaluation_summary
|
|
435
|
+
if cache_for_dataloaders
|
|
436
|
+
else None
|
|
437
|
+
),
|
|
323
438
|
),
|
|
324
439
|
document_evaluations=DocumentEvaluationsDataLoader(db),
|
|
325
440
|
document_retrieval_metrics=DocumentRetrievalMetricsDataLoader(db),
|
|
326
441
|
annotation_summaries=AnnotationSummaryDataLoader(
|
|
327
442
|
db,
|
|
328
|
-
cache_map=
|
|
329
|
-
|
|
330
|
-
|
|
443
|
+
cache_map=(
|
|
444
|
+
cache_for_dataloaders.annotation_summary if cache_for_dataloaders else None
|
|
445
|
+
),
|
|
331
446
|
),
|
|
332
447
|
experiment_annotation_summaries=ExperimentAnnotationSummaryDataLoader(db),
|
|
333
448
|
experiment_error_rates=ExperimentErrorRatesDataLoader(db),
|
|
@@ -335,15 +450,17 @@ def create_graphql_router(
|
|
|
335
450
|
experiment_sequence_number=ExperimentSequenceNumberDataLoader(db),
|
|
336
451
|
latency_ms_quantile=LatencyMsQuantileDataLoader(
|
|
337
452
|
db,
|
|
338
|
-
cache_map=
|
|
339
|
-
|
|
340
|
-
|
|
453
|
+
cache_map=(
|
|
454
|
+
cache_for_dataloaders.latency_ms_quantile if cache_for_dataloaders else None
|
|
455
|
+
),
|
|
341
456
|
),
|
|
342
457
|
min_start_or_max_end_times=MinStartOrMaxEndTimeDataLoader(
|
|
343
458
|
db,
|
|
344
|
-
cache_map=
|
|
345
|
-
|
|
346
|
-
|
|
459
|
+
cache_map=(
|
|
460
|
+
cache_for_dataloaders.min_start_or_max_end_time
|
|
461
|
+
if cache_for_dataloaders
|
|
462
|
+
else None
|
|
463
|
+
),
|
|
347
464
|
),
|
|
348
465
|
record_counts=RecordCountDataLoader(
|
|
349
466
|
db,
|
|
@@ -438,6 +555,8 @@ def create_app(
|
|
|
438
555
|
startup_callbacks: Iterable[Callable[[], None]] = (),
|
|
439
556
|
shutdown_callbacks: Iterable[Callable[[], None]] = (),
|
|
440
557
|
secret: Optional[str] = None,
|
|
558
|
+
tracing_fixture_names: Set[str] = set(),
|
|
559
|
+
force_fixture_ingestion: bool = False,
|
|
441
560
|
) -> FastAPI:
|
|
442
561
|
startup_callbacks_list: List[Callable[[], None]] = list(startup_callbacks)
|
|
443
562
|
shutdown_callbacks_list: List[Callable[[], None]] = list(shutdown_callbacks)
|
|
@@ -510,11 +629,12 @@ def create_app(
|
|
|
510
629
|
prometheus_middlewares = [Middleware(PrometheusMiddleware)]
|
|
511
630
|
else:
|
|
512
631
|
prometheus_middlewares = []
|
|
632
|
+
|
|
513
633
|
app = FastAPI(
|
|
514
634
|
title="Arize-Phoenix REST API",
|
|
515
635
|
version=REST_API_VERSION,
|
|
516
636
|
lifespan=_lifespan(
|
|
517
|
-
|
|
637
|
+
db=db,
|
|
518
638
|
read_only=read_only,
|
|
519
639
|
bulk_inserter=bulk_inserter,
|
|
520
640
|
dml_event_handler=dml_event_handler,
|
|
@@ -522,6 +642,8 @@ def create_app(
|
|
|
522
642
|
enable_prometheus=enable_prometheus,
|
|
523
643
|
shutdown_callbacks=shutdown_callbacks_list,
|
|
524
644
|
startup_callbacks=startup_callbacks_list,
|
|
645
|
+
tracing_fixture_names=tracing_fixture_names,
|
|
646
|
+
force_fixture_ingestion=force_fixture_ingestion,
|
|
525
647
|
),
|
|
526
648
|
middleware=[
|
|
527
649
|
Middleware(HeadersMiddleware),
|
|
@@ -539,8 +661,6 @@ def create_app(
|
|
|
539
661
|
app.include_router(router)
|
|
540
662
|
app.include_router(graphql_router)
|
|
541
663
|
app.add_middleware(GZipMiddleware)
|
|
542
|
-
if authentication_enabled:
|
|
543
|
-
app.include_router(auth_router)
|
|
544
664
|
if serve_ui:
|
|
545
665
|
app.mount(
|
|
546
666
|
"/",
|
phoenix/server/main.py
CHANGED
|
@@ -48,6 +48,7 @@ from phoenix.trace.fixtures import (
|
|
|
48
48
|
TRACES_FIXTURES,
|
|
49
49
|
get_dataset_fixtures,
|
|
50
50
|
get_evals_from_fixture,
|
|
51
|
+
get_trace_fixtures_by_project_name,
|
|
51
52
|
load_example_traces,
|
|
52
53
|
reset_fixture_span_ids_and_timestamps,
|
|
53
54
|
send_dataset_fixtures,
|
|
@@ -135,7 +136,7 @@ if __name__ == "__main__":
|
|
|
135
136
|
parser.add_argument("--export_path")
|
|
136
137
|
parser.add_argument("--host", type=str, required=False)
|
|
137
138
|
parser.add_argument("--port", type=int, required=False)
|
|
138
|
-
parser.add_argument("--read-only",
|
|
139
|
+
parser.add_argument("--read-only", action="store_true", required=False) # Default is False
|
|
139
140
|
parser.add_argument("--no-internet", action="store_true")
|
|
140
141
|
parser.add_argument("--umap_params", type=str, required=False, default=DEFAULT_UMAP_PARAMS_STR)
|
|
141
142
|
parser.add_argument("--debug", action="store_true")
|
|
@@ -144,6 +145,43 @@ if __name__ == "__main__":
|
|
|
144
145
|
parser.add_argument("--no-ui", action="store_true")
|
|
145
146
|
subparsers = parser.add_subparsers(dest="command", required=True)
|
|
146
147
|
serve_parser = subparsers.add_parser("serve")
|
|
148
|
+
serve_parser.add_argument(
|
|
149
|
+
"--with-fixture",
|
|
150
|
+
type=str,
|
|
151
|
+
required=False,
|
|
152
|
+
default="",
|
|
153
|
+
help=("Name of an inference fixture. Example: 'fixture1'"),
|
|
154
|
+
)
|
|
155
|
+
serve_parser.add_argument(
|
|
156
|
+
"--with-trace-fixtures",
|
|
157
|
+
type=str,
|
|
158
|
+
required=False,
|
|
159
|
+
default="",
|
|
160
|
+
help=(
|
|
161
|
+
"Comma separated list of tracing fixture names (spaces are ignored). "
|
|
162
|
+
"Example: 'fixture1, fixture2'"
|
|
163
|
+
),
|
|
164
|
+
)
|
|
165
|
+
serve_parser.add_argument(
|
|
166
|
+
"--with-projects",
|
|
167
|
+
type=str,
|
|
168
|
+
required=False,
|
|
169
|
+
default="",
|
|
170
|
+
help=(
|
|
171
|
+
"Comma separated list of project names (spaces are ignored). "
|
|
172
|
+
"Example: 'project1, project2'"
|
|
173
|
+
),
|
|
174
|
+
)
|
|
175
|
+
serve_parser.add_argument(
|
|
176
|
+
"--force-fixture-ingestion",
|
|
177
|
+
action="store_true", # default is False
|
|
178
|
+
required=False,
|
|
179
|
+
help=(
|
|
180
|
+
"Whether or not to check the database age before adding the fixtures. "
|
|
181
|
+
"Default is False, i.e., fixtures will only be added if the "
|
|
182
|
+
"database is new."
|
|
183
|
+
),
|
|
184
|
+
)
|
|
147
185
|
datasets_parser = subparsers.add_parser("datasets")
|
|
148
186
|
datasets_parser.add_argument("--primary", type=str, required=True)
|
|
149
187
|
datasets_parser.add_argument("--reference", type=str, required=False)
|
|
@@ -151,12 +189,14 @@ if __name__ == "__main__":
|
|
|
151
189
|
datasets_parser.add_argument("--trace", type=str, required=False)
|
|
152
190
|
fixture_parser = subparsers.add_parser("fixture")
|
|
153
191
|
fixture_parser.add_argument("fixture", type=str, choices=[fixture.name for fixture in FIXTURES])
|
|
154
|
-
fixture_parser.add_argument("--primary-only",
|
|
192
|
+
fixture_parser.add_argument("--primary-only", action="store_true") # Default is False
|
|
155
193
|
trace_fixture_parser = subparsers.add_parser("trace-fixture")
|
|
156
194
|
trace_fixture_parser.add_argument(
|
|
157
195
|
"fixture", type=str, choices=[fixture.name for fixture in TRACES_FIXTURES]
|
|
158
196
|
)
|
|
159
|
-
trace_fixture_parser.add_argument(
|
|
197
|
+
trace_fixture_parser.add_argument(
|
|
198
|
+
"--simulate-streaming", action="store_true"
|
|
199
|
+
) # Default is False
|
|
160
200
|
demo_parser = subparsers.add_parser("demo")
|
|
161
201
|
demo_parser.add_argument("fixture", type=str, choices=[fixture.name for fixture in FIXTURES])
|
|
162
202
|
demo_parser.add_argument(
|
|
@@ -164,10 +204,12 @@ if __name__ == "__main__":
|
|
|
164
204
|
)
|
|
165
205
|
demo_parser.add_argument("--simulate-streaming", action="store_true")
|
|
166
206
|
args = parser.parse_args()
|
|
207
|
+
|
|
167
208
|
db_connection_str = (
|
|
168
209
|
args.database_url if args.database_url else get_env_database_connection_str()
|
|
169
210
|
)
|
|
170
211
|
export_path = Path(args.export_path) if args.export_path else EXPORT_DIR
|
|
212
|
+
force_fixture_ingestion = False
|
|
171
213
|
if args.command == "datasets":
|
|
172
214
|
primary_inferences_name = args.primary
|
|
173
215
|
reference_inferences_name = args.reference
|
|
@@ -202,7 +244,26 @@ if __name__ == "__main__":
|
|
|
202
244
|
)
|
|
203
245
|
trace_dataset_name = args.trace_fixture
|
|
204
246
|
simulate_streaming = args.simulate_streaming
|
|
205
|
-
|
|
247
|
+
elif args.command == "serve":
|
|
248
|
+
# We use sets to avoid duplicates
|
|
249
|
+
tracing_fixture_names = set()
|
|
250
|
+
if args.with_fixture:
|
|
251
|
+
primary_inferences, reference_inferences, corpus_inferences = get_inferences(
|
|
252
|
+
str(args.with_fixture),
|
|
253
|
+
args.no_internet,
|
|
254
|
+
)
|
|
255
|
+
if args.with_trace_fixtures:
|
|
256
|
+
tracing_fixture_names.update(
|
|
257
|
+
[name.strip() for name in args.with_trace_fixtures.split(",")]
|
|
258
|
+
)
|
|
259
|
+
if args.with_projects:
|
|
260
|
+
project_names = [name.strip() for name in args.with_projects.split(",")]
|
|
261
|
+
tracing_fixture_names.update(
|
|
262
|
+
fixture.name
|
|
263
|
+
for name in project_names
|
|
264
|
+
for fixture in get_trace_fixtures_by_project_name(name)
|
|
265
|
+
)
|
|
266
|
+
force_fixture_ingestion = args.force_fixture_ingestion
|
|
206
267
|
host: Optional[str] = args.host or get_env_host()
|
|
207
268
|
display_host = host or "localhost"
|
|
208
269
|
# If the host is "::", the convention is to bind to all interfaces. However, uvicorn
|
|
@@ -260,6 +321,9 @@ if __name__ == "__main__":
|
|
|
260
321
|
engine = create_engine_and_run_migrations(db_connection_str)
|
|
261
322
|
instrumentation_cleanups = instrument_engine_if_enabled(engine)
|
|
262
323
|
factory = DbSessionFactory(db=_db(engine), dialect=engine.dialect.name)
|
|
324
|
+
corpus_model = (
|
|
325
|
+
None if corpus_inferences is None else create_model_from_inferences(corpus_inferences)
|
|
326
|
+
)
|
|
263
327
|
# Print information about the server
|
|
264
328
|
msg = _WELCOME_MESSAGE.format(
|
|
265
329
|
version=version("arize-phoenix"),
|
|
@@ -278,9 +342,7 @@ if __name__ == "__main__":
|
|
|
278
342
|
model=model,
|
|
279
343
|
authentication_enabled=authentication_enabled,
|
|
280
344
|
umap_params=umap_params,
|
|
281
|
-
corpus=
|
|
282
|
-
if corpus_inferences is None
|
|
283
|
-
else create_model_from_inferences(corpus_inferences),
|
|
345
|
+
corpus=corpus_model,
|
|
284
346
|
debug=args.debug,
|
|
285
347
|
dev=args.dev,
|
|
286
348
|
serve_ui=not args.no_ui,
|
|
@@ -291,6 +353,8 @@ if __name__ == "__main__":
|
|
|
291
353
|
startup_callbacks=[lambda: print(msg)],
|
|
292
354
|
shutdown_callbacks=instrumentation_cleanups,
|
|
293
355
|
secret=secret,
|
|
356
|
+
tracing_fixture_names=tracing_fixture_names,
|
|
357
|
+
force_fixture_ingestion=force_fixture_ingestion,
|
|
294
358
|
)
|
|
295
359
|
server = Server(config=Config(app, host=host, port=port, root_path=host_root_path)) # type: ignore
|
|
296
360
|
Thread(target=_write_pid_file_when_ready, args=(server,), daemon=True).start()
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
{
|
|
2
|
-
"_components-
|
|
3
|
-
"file": "assets/components-
|
|
2
|
+
"_components-BYH03rjA.js": {
|
|
3
|
+
"file": "assets/components-BYH03rjA.js",
|
|
4
4
|
"name": "components",
|
|
5
5
|
"imports": [
|
|
6
6
|
"_vendor-aSQri0vz.js",
|
|
7
7
|
"_vendor-arizeai-CsdcB1NH.js",
|
|
8
|
-
"_pages-
|
|
8
|
+
"_pages-DnbxgoTK.js",
|
|
9
9
|
"_vendor-three-DwGkEfCM.js",
|
|
10
10
|
"_vendor-codemirror-CYHkhs7D.js"
|
|
11
11
|
]
|
|
12
12
|
},
|
|
13
|
-
"_pages-
|
|
14
|
-
"file": "assets/pages-
|
|
13
|
+
"_pages-DnbxgoTK.js": {
|
|
14
|
+
"file": "assets/pages-DnbxgoTK.js",
|
|
15
15
|
"name": "pages",
|
|
16
16
|
"imports": [
|
|
17
17
|
"_vendor-aSQri0vz.js",
|
|
18
|
-
"_components-
|
|
18
|
+
"_components-BYH03rjA.js",
|
|
19
19
|
"_vendor-arizeai-CsdcB1NH.js",
|
|
20
20
|
"_vendor-recharts-B0sannek.js",
|
|
21
21
|
"_vendor-codemirror-CYHkhs7D.js"
|
|
@@ -61,15 +61,15 @@
|
|
|
61
61
|
"name": "vendor-three"
|
|
62
62
|
},
|
|
63
63
|
"index.tsx": {
|
|
64
|
-
"file": "assets/index-
|
|
64
|
+
"file": "assets/index-fqdjNpYm.js",
|
|
65
65
|
"name": "index",
|
|
66
66
|
"src": "index.tsx",
|
|
67
67
|
"isEntry": true,
|
|
68
68
|
"imports": [
|
|
69
69
|
"_vendor-aSQri0vz.js",
|
|
70
70
|
"_vendor-arizeai-CsdcB1NH.js",
|
|
71
|
-
"_pages-
|
|
72
|
-
"_components-
|
|
71
|
+
"_pages-DnbxgoTK.js",
|
|
72
|
+
"_components-BYH03rjA.js",
|
|
73
73
|
"_vendor-three-DwGkEfCM.js",
|
|
74
74
|
"_vendor-recharts-B0sannek.js",
|
|
75
75
|
"_vendor-codemirror-CYHkhs7D.js"
|