arize-phoenix 4.12.0__py3-none-any.whl → 4.12.1rc1__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 (39) hide show
  1. {arize_phoenix-4.12.0.dist-info → arize_phoenix-4.12.1rc1.dist-info}/METADATA +4 -3
  2. {arize_phoenix-4.12.0.dist-info → arize_phoenix-4.12.1rc1.dist-info}/RECORD +36 -27
  3. phoenix/server/api/context.py +3 -7
  4. phoenix/server/api/openapi/main.py +18 -2
  5. phoenix/server/api/openapi/schema.py +12 -12
  6. phoenix/server/api/routers/v1/__init__.py +36 -83
  7. phoenix/server/api/routers/v1/dataset_examples.py +102 -123
  8. phoenix/server/api/routers/v1/datasets.py +390 -506
  9. phoenix/server/api/routers/v1/evaluations.py +73 -66
  10. phoenix/server/api/routers/v1/experiment_evaluations.py +68 -91
  11. phoenix/server/api/routers/v1/experiment_runs.py +98 -155
  12. phoenix/server/api/routers/v1/experiments.py +132 -181
  13. phoenix/server/api/routers/v1/pydantic_compat.py +78 -0
  14. phoenix/server/api/routers/v1/spans.py +144 -173
  15. phoenix/server/api/routers/v1/traces.py +115 -128
  16. phoenix/server/api/routers/v1/utils.py +95 -0
  17. phoenix/server/api/types/Project.py +33 -0
  18. phoenix/server/app.py +172 -176
  19. phoenix/server/main.py +3 -0
  20. phoenix/server/static/.vite/manifest.json +78 -0
  21. phoenix/server/static/assets/components-C8sm_r1F.js +1142 -0
  22. phoenix/server/static/assets/index-BEKPzgQs.js +100 -0
  23. phoenix/server/static/assets/pages-bN7juCjh.js +2885 -0
  24. phoenix/server/static/assets/vendor-CUDAPm8e.js +641 -0
  25. phoenix/server/static/assets/vendor-DxkFTwjz.css +1 -0
  26. phoenix/server/static/assets/vendor-arizeai-Do2HOmcL.js +662 -0
  27. phoenix/server/static/assets/vendor-codemirror-CrdxOlMs.js +12 -0
  28. phoenix/server/static/assets/vendor-recharts-PKRvByVe.js +59 -0
  29. phoenix/server/static/assets/vendor-three-DwGkEfCM.js +2998 -0
  30. phoenix/server/templates/index.html +83 -24
  31. phoenix/server/thread_server.py +2 -2
  32. phoenix/session/client.py +3 -2
  33. phoenix/version.py +1 -1
  34. phoenix/server/openapi/docs.py +0 -221
  35. phoenix/server/static/index.css +0 -6
  36. phoenix/server/static/index.js +0 -8548
  37. {arize_phoenix-4.12.0.dist-info → arize_phoenix-4.12.1rc1.dist-info}/WHEEL +0 -0
  38. {arize_phoenix-4.12.0.dist-info → arize_phoenix-4.12.1rc1.dist-info}/licenses/IP_NOTICE +0 -0
  39. {arize_phoenix-4.12.0.dist-info → arize_phoenix-4.12.1rc1.dist-info}/licenses/LICENSE +0 -0
phoenix/server/app.py CHANGED
@@ -1,6 +1,8 @@
1
1
  import contextlib
2
+ import json
2
3
  import logging
3
4
  from datetime import datetime
5
+ from functools import cached_property
4
6
  from pathlib import Path
5
7
  from typing import (
6
8
  TYPE_CHECKING,
@@ -19,25 +21,24 @@ from typing import (
19
21
  )
20
22
 
21
23
  import strawberry
24
+ from fastapi import APIRouter, FastAPI
25
+ from fastapi.middleware.gzip import GZipMiddleware
26
+ from fastapi.responses import FileResponse
27
+ from fastapi.utils import is_body_allowed_for_status_code
22
28
  from sqlalchemy.ext.asyncio import (
23
29
  AsyncEngine,
24
30
  AsyncSession,
25
31
  async_sessionmaker,
26
32
  )
27
- from starlette.applications import Starlette
28
- from starlette.datastructures import QueryParams
29
- from starlette.endpoints import HTTPEndpoint
30
33
  from starlette.exceptions import HTTPException
31
34
  from starlette.middleware import Middleware
32
35
  from starlette.middleware.base import BaseHTTPMiddleware, RequestResponseEndpoint
33
36
  from starlette.requests import Request
34
- from starlette.responses import FileResponse, PlainTextResponse, Response
35
- from starlette.routing import Mount, Route
37
+ from starlette.responses import PlainTextResponse, Response
36
38
  from starlette.staticfiles import StaticFiles
37
39
  from starlette.templating import Jinja2Templates
38
40
  from starlette.types import Scope, StatefulLifespan
39
- from starlette.websockets import WebSocket
40
- from strawberry.asgi import GraphQL
41
+ from strawberry.fastapi import GraphQLRouter
41
42
  from strawberry.schema import BaseSchema
42
43
  from typing_extensions import TypeAlias
43
44
 
@@ -80,11 +81,10 @@ from phoenix.server.api.dataloaders import (
80
81
  TraceEvaluationsDataLoader,
81
82
  TraceRowIdsDataLoader,
82
83
  )
83
- from phoenix.server.api.openapi.schema import OPENAPI_SCHEMA_GENERATOR
84
- from phoenix.server.api.routers.v1 import V1_ROUTES
84
+ from phoenix.server.api.routers.v1 import REST_API_VERSION
85
+ from phoenix.server.api.routers.v1 import router as v1_router
85
86
  from phoenix.server.api.schema import schema
86
87
  from phoenix.server.grpc_server import GrpcServer
87
- from phoenix.server.openapi.docs import get_swagger_ui_html
88
88
  from phoenix.server.telemetry import initialize_opentelemetry_tracer_provider
89
89
  from phoenix.trace.schemas import Span
90
90
 
@@ -93,6 +93,8 @@ if TYPE_CHECKING:
93
93
 
94
94
  logger = logging.getLogger(__name__)
95
95
 
96
+ router = APIRouter(include_in_schema=False)
97
+
96
98
  templates = Jinja2Templates(directory=SERVER_DIR / "templates")
97
99
 
98
100
 
@@ -103,6 +105,8 @@ class AppConfig(NamedTuple):
103
105
  min_dist: float
104
106
  n_neighbors: int
105
107
  n_samples: int
108
+ is_development: bool
109
+ web_manifest_path: Path
106
110
 
107
111
 
108
112
  class Static(StaticFiles):
@@ -114,6 +118,19 @@ class Static(StaticFiles):
114
118
  self._app_config = app_config
115
119
  super().__init__(**kwargs)
116
120
 
121
+ @cached_property
122
+ def _web_manifest(self) -> Dict[str, Any]:
123
+ try:
124
+ with open(self._app_config.web_manifest_path, "r") as f:
125
+ return cast(Dict[str, Any], json.load(f))
126
+ except FileNotFoundError as e:
127
+ if self._app_config.is_development:
128
+ return {}
129
+ raise e
130
+
131
+ def _sanitize_basename(self, basename: str) -> str:
132
+ return basename[:-1] if basename.endswith("/") else basename
133
+
117
134
  async def get_response(self, path: str, scope: Scope) -> Response:
118
135
  response = None
119
136
  try:
@@ -132,9 +149,11 @@ class Static(StaticFiles):
132
149
  "min_dist": self._app_config.min_dist,
133
150
  "n_neighbors": self._app_config.n_neighbors,
134
151
  "n_samples": self._app_config.n_samples,
135
- "basename": request.scope.get("root_path", ""),
152
+ "basename": self._sanitize_basename(request.scope.get("root_path", "")),
136
153
  "platform_version": phoenix.__version__,
137
154
  "request": request,
155
+ "is_development": self._app_config.is_development,
156
+ "manifest": self._web_manifest,
138
157
  },
139
158
  )
140
159
  except Exception as e:
@@ -157,116 +176,20 @@ class HeadersMiddleware(BaseHTTPMiddleware):
157
176
  ProjectRowId: TypeAlias = int
158
177
 
159
178
 
160
- class GraphQLWithContext(GraphQL): # type: ignore
161
- def __init__(
162
- self,
163
- schema: BaseSchema,
164
- db: Callable[[], AsyncContextManager[AsyncSession]],
165
- model: Model,
166
- export_path: Path,
167
- graphiql: bool = False,
168
- corpus: Optional[Model] = None,
169
- streaming_last_updated_at: Callable[[ProjectRowId], Optional[datetime]] = lambda _: None,
170
- cache_for_dataloaders: Optional[CacheForDataLoaders] = None,
171
- read_only: bool = False,
172
- ) -> None:
173
- self.db = db
174
- self.model = model
175
- self.corpus = corpus
176
- self.export_path = export_path
177
- self.streaming_last_updated_at = streaming_last_updated_at
178
- self.cache_for_dataloaders = cache_for_dataloaders
179
- self.read_only = read_only
180
- super().__init__(schema, graphiql=graphiql)
181
-
182
- async def get_context(
183
- self,
184
- request: Union[Request, WebSocket],
185
- response: Optional[Response] = None,
186
- ) -> Context:
187
- return Context(
188
- request=request,
189
- response=response,
190
- db=self.db,
191
- model=self.model,
192
- corpus=self.corpus,
193
- export_path=self.export_path,
194
- streaming_last_updated_at=self.streaming_last_updated_at,
195
- data_loaders=DataLoaders(
196
- average_experiment_run_latency=AverageExperimentRunLatencyDataLoader(self.db),
197
- dataset_example_revisions=DatasetExampleRevisionsDataLoader(self.db),
198
- dataset_example_spans=DatasetExampleSpansDataLoader(self.db),
199
- document_evaluation_summaries=DocumentEvaluationSummaryDataLoader(
200
- self.db,
201
- cache_map=self.cache_for_dataloaders.document_evaluation_summary
202
- if self.cache_for_dataloaders
203
- else None,
204
- ),
205
- document_evaluations=DocumentEvaluationsDataLoader(self.db),
206
- document_retrieval_metrics=DocumentRetrievalMetricsDataLoader(self.db),
207
- evaluation_summaries=EvaluationSummaryDataLoader(
208
- self.db,
209
- cache_map=self.cache_for_dataloaders.evaluation_summary
210
- if self.cache_for_dataloaders
211
- else None,
212
- ),
213
- experiment_annotation_summaries=ExperimentAnnotationSummaryDataLoader(self.db),
214
- experiment_error_rates=ExperimentErrorRatesDataLoader(self.db),
215
- experiment_run_counts=ExperimentRunCountsDataLoader(self.db),
216
- experiment_sequence_number=ExperimentSequenceNumberDataLoader(self.db),
217
- latency_ms_quantile=LatencyMsQuantileDataLoader(
218
- self.db,
219
- cache_map=self.cache_for_dataloaders.latency_ms_quantile
220
- if self.cache_for_dataloaders
221
- else None,
222
- ),
223
- min_start_or_max_end_times=MinStartOrMaxEndTimeDataLoader(
224
- self.db,
225
- cache_map=self.cache_for_dataloaders.min_start_or_max_end_time
226
- if self.cache_for_dataloaders
227
- else None,
228
- ),
229
- record_counts=RecordCountDataLoader(
230
- self.db,
231
- cache_map=self.cache_for_dataloaders.record_count
232
- if self.cache_for_dataloaders
233
- else None,
234
- ),
235
- span_descendants=SpanDescendantsDataLoader(self.db),
236
- span_evaluations=SpanEvaluationsDataLoader(self.db),
237
- span_projects=SpanProjectsDataLoader(self.db),
238
- token_counts=TokenCountDataLoader(
239
- self.db,
240
- cache_map=self.cache_for_dataloaders.token_count
241
- if self.cache_for_dataloaders
242
- else None,
243
- ),
244
- trace_evaluations=TraceEvaluationsDataLoader(self.db),
245
- trace_row_ids=TraceRowIdsDataLoader(self.db),
246
- project_by_name=ProjectByNameDataLoader(self.db),
247
- span_annotations=SpanAnnotationsDataLoader(self.db),
248
- ),
249
- cache_for_dataloaders=self.cache_for_dataloaders,
250
- read_only=self.read_only,
251
- )
252
-
253
-
254
- class Download(HTTPEndpoint):
255
- path: Path
256
-
257
- async def get(self, request: Request) -> FileResponse:
258
- params = QueryParams(request.query_params)
259
- file = self.path / (params.get("filename", "") + ".parquet")
260
- if not file.is_file():
261
- raise HTTPException(status_code=404)
262
- return FileResponse(
263
- path=file,
264
- filename=file.name,
265
- media_type="application/x-octet-stream",
266
- )
179
+ @router.get("/exports")
180
+ async def download_exported_file(request: Request, filename: str) -> FileResponse:
181
+ file = request.app.state.export_path / (filename + ".parquet")
182
+ if not file.is_file():
183
+ raise HTTPException(status_code=404)
184
+ return FileResponse(
185
+ path=file,
186
+ filename=file.name,
187
+ media_type="application/x-octet-stream",
188
+ )
267
189
 
268
190
 
269
- async def version(_: Request) -> PlainTextResponse:
191
+ @router.get("/arize_phoenix_version")
192
+ async def version() -> PlainTextResponse:
270
193
  return PlainTextResponse(f"{phoenix.__version__}")
271
194
 
272
195
 
@@ -288,9 +211,9 @@ def _lifespan(
288
211
  enable_prometheus: bool = False,
289
212
  clean_ups: Iterable[Callable[[], None]] = (),
290
213
  read_only: bool = False,
291
- ) -> StatefulLifespan[Starlette]:
214
+ ) -> StatefulLifespan[FastAPI]:
292
215
  @contextlib.asynccontextmanager
293
- async def lifespan(_: Starlette) -> AsyncIterator[Dict[str, Any]]:
216
+ async def lifespan(_: FastAPI) -> AsyncIterator[Dict[str, Any]]:
294
217
  async with bulk_inserter as (
295
218
  queue_span,
296
219
  queue_evaluation,
@@ -312,16 +235,90 @@ def _lifespan(
312
235
  return lifespan
313
236
 
314
237
 
238
+ @router.get("/healthz")
315
239
  async def check_healthz(_: Request) -> PlainTextResponse:
316
240
  return PlainTextResponse("OK")
317
241
 
318
242
 
319
- async def openapi_schema(request: Request) -> Response:
320
- return OPENAPI_SCHEMA_GENERATOR.OpenAPIResponse(request=request)
321
-
243
+ def create_graphql_router(
244
+ *,
245
+ schema: BaseSchema,
246
+ db: Callable[[], AsyncContextManager[AsyncSession]],
247
+ model: Model,
248
+ export_path: Path,
249
+ corpus: Optional[Model] = None,
250
+ streaming_last_updated_at: Callable[[ProjectRowId], Optional[datetime]] = lambda _: None,
251
+ cache_for_dataloaders: Optional[CacheForDataLoaders] = None,
252
+ read_only: bool = False,
253
+ ) -> GraphQLRouter: # type: ignore[type-arg]
254
+ def get_context() -> Context:
255
+ return Context(
256
+ db=db,
257
+ model=model,
258
+ corpus=corpus,
259
+ export_path=export_path,
260
+ streaming_last_updated_at=streaming_last_updated_at,
261
+ data_loaders=DataLoaders(
262
+ average_experiment_run_latency=AverageExperimentRunLatencyDataLoader(db),
263
+ dataset_example_revisions=DatasetExampleRevisionsDataLoader(db),
264
+ dataset_example_spans=DatasetExampleSpansDataLoader(db),
265
+ document_evaluation_summaries=DocumentEvaluationSummaryDataLoader(
266
+ db,
267
+ cache_map=cache_for_dataloaders.document_evaluation_summary
268
+ if cache_for_dataloaders
269
+ else None,
270
+ ),
271
+ document_evaluations=DocumentEvaluationsDataLoader(db),
272
+ document_retrieval_metrics=DocumentRetrievalMetricsDataLoader(db),
273
+ evaluation_summaries=EvaluationSummaryDataLoader(
274
+ db,
275
+ cache_map=cache_for_dataloaders.evaluation_summary
276
+ if cache_for_dataloaders
277
+ else None,
278
+ ),
279
+ experiment_annotation_summaries=ExperimentAnnotationSummaryDataLoader(db),
280
+ experiment_error_rates=ExperimentErrorRatesDataLoader(db),
281
+ experiment_run_counts=ExperimentRunCountsDataLoader(db),
282
+ experiment_sequence_number=ExperimentSequenceNumberDataLoader(db),
283
+ latency_ms_quantile=LatencyMsQuantileDataLoader(
284
+ db,
285
+ cache_map=cache_for_dataloaders.latency_ms_quantile
286
+ if cache_for_dataloaders
287
+ else None,
288
+ ),
289
+ min_start_or_max_end_times=MinStartOrMaxEndTimeDataLoader(
290
+ db,
291
+ cache_map=cache_for_dataloaders.min_start_or_max_end_time
292
+ if cache_for_dataloaders
293
+ else None,
294
+ ),
295
+ record_counts=RecordCountDataLoader(
296
+ db,
297
+ cache_map=cache_for_dataloaders.record_count if cache_for_dataloaders else None,
298
+ ),
299
+ span_annotations=SpanAnnotationsDataLoader(db),
300
+ span_descendants=SpanDescendantsDataLoader(db),
301
+ span_evaluations=SpanEvaluationsDataLoader(db),
302
+ span_projects=SpanProjectsDataLoader(db),
303
+ token_counts=TokenCountDataLoader(
304
+ db,
305
+ cache_map=cache_for_dataloaders.token_count if cache_for_dataloaders else None,
306
+ ),
307
+ trace_evaluations=TraceEvaluationsDataLoader(db),
308
+ trace_row_ids=TraceRowIdsDataLoader(db),
309
+ project_by_name=ProjectByNameDataLoader(db),
310
+ ),
311
+ cache_for_dataloaders=cache_for_dataloaders,
312
+ read_only=read_only,
313
+ )
322
314
 
323
- async def api_docs(request: Request) -> Response:
324
- return get_swagger_ui_html(openapi_url="/schema", title="arize-phoenix API")
315
+ return GraphQLRouter(
316
+ schema,
317
+ graphiql=True,
318
+ context_getter=get_context,
319
+ include_in_schema=False,
320
+ prefix="/graphql",
321
+ )
325
322
 
326
323
 
327
324
  class SessionFactory:
@@ -372,6 +369,18 @@ def instrument_engine_if_enabled(engine: AsyncEngine) -> List[Callable[[], None]
372
369
  return instrumentation_cleanups
373
370
 
374
371
 
372
+ async def plain_text_http_exception_handler(request: Request, exc: HTTPException) -> Response:
373
+ """
374
+ Overrides the default handler for HTTPExceptions to return a plain text
375
+ response instead of a JSON response. For the original source code, see
376
+ https://github.com/tiangolo/fastapi/blob/d3cdd3bbd14109f3b268df7ca496e24bb64593aa/fastapi/exception_handlers.py#L11
377
+ """
378
+ headers = getattr(exc, "headers", None)
379
+ if not is_body_allowed_for_status_code(exc.status_code):
380
+ return Response(status_code=exc.status_code, headers=headers)
381
+ return PlainTextResponse(str(exc.detail), status_code=exc.status_code, headers=headers)
382
+
383
+
375
384
  def create_app(
376
385
  db: SessionFactory,
377
386
  export_path: Path,
@@ -379,13 +388,14 @@ def create_app(
379
388
  umap_params: UMAPParameters,
380
389
  corpus: Optional[Model] = None,
381
390
  debug: bool = False,
391
+ dev: bool = False,
382
392
  read_only: bool = False,
383
393
  enable_prometheus: bool = False,
384
394
  initial_spans: Optional[Iterable[Union[Span, Tuple[Span, str]]]] = None,
385
395
  initial_evaluations: Optional[Iterable[pb.Evaluation]] = None,
386
396
  serve_ui: bool = True,
387
397
  clean_up_callbacks: List[Callable[[], None]] = [],
388
- ) -> Starlette:
398
+ ) -> FastAPI:
389
399
  clean_ups: List[Callable[[], None]] = clean_up_callbacks # To be called at app shutdown.
390
400
  initial_batch_of_spans: Iterable[Tuple[Span, str]] = (
391
401
  ()
@@ -428,7 +438,7 @@ def create_app(
428
438
 
429
439
  strawberry_extensions.append(_OpenTelemetryExtension)
430
440
 
431
- graphql = GraphQLWithContext(
441
+ graphql_router = create_graphql_router(
432
442
  db=db,
433
443
  schema=strawberry.Schema(
434
444
  query=schema.query,
@@ -439,7 +449,6 @@ def create_app(
439
449
  model=model,
440
450
  corpus=corpus,
441
451
  export_path=export_path,
442
- graphiql=True,
443
452
  streaming_last_updated_at=bulk_inserter.last_updated_at,
444
453
  cache_for_dataloaders=cache_for_dataloaders,
445
454
  read_only=read_only,
@@ -450,7 +459,9 @@ def create_app(
450
459
  prometheus_middlewares = [Middleware(PrometheusMiddleware)]
451
460
  else:
452
461
  prometheus_middlewares = []
453
- app = Starlette(
462
+ app = FastAPI(
463
+ title="Arize-Phoenix REST API",
464
+ version=REST_API_VERSION,
454
465
  lifespan=_lifespan(
455
466
  read_only=read_only,
456
467
  bulk_inserter=bulk_inserter,
@@ -462,56 +473,41 @@ def create_app(
462
473
  Middleware(HeadersMiddleware),
463
474
  *prometheus_middlewares,
464
475
  ],
476
+ exception_handlers={HTTPException: plain_text_http_exception_handler},
465
477
  debug=debug,
466
- routes=V1_ROUTES
467
- + [
468
- Route("/schema", endpoint=openapi_schema, include_in_schema=False),
469
- Route("/arize_phoenix_version", version),
470
- Route("/healthz", check_healthz),
471
- Route(
472
- "/exports",
473
- type(
474
- "DownloadExports",
475
- (Download,),
476
- {"path": export_path},
477
- ),
478
- ),
479
- Route(
480
- "/docs",
481
- api_docs,
482
- ),
483
- Route(
484
- "/graphql",
485
- graphql,
486
- ),
487
- ]
488
- + (
489
- [
490
- Mount(
491
- "/",
492
- app=Static(
493
- directory=SERVER_DIR / "static",
494
- app_config=AppConfig(
495
- has_inferences=model.is_empty is not True,
496
- has_corpus=corpus is not None,
497
- min_dist=umap_params.min_dist,
498
- n_neighbors=umap_params.n_neighbors,
499
- n_samples=umap_params.n_samples,
500
- ),
501
- ),
502
- name="static",
503
- ),
504
- ]
505
- if serve_ui
506
- else []
507
- ),
478
+ swagger_ui_parameters={
479
+ "defaultModelsExpandDepth": -1, # hides the schema section in the Swagger UI
480
+ },
508
481
  )
509
482
  app.state.read_only = read_only
483
+ app.state.export_path = export_path
484
+ app.include_router(v1_router)
485
+ app.include_router(router)
486
+ app.include_router(graphql_router)
487
+ app.add_middleware(GZipMiddleware)
488
+ if serve_ui:
489
+ app.mount(
490
+ "/",
491
+ app=Static(
492
+ directory=SERVER_DIR / "static",
493
+ app_config=AppConfig(
494
+ has_inferences=model.is_empty is not True,
495
+ has_corpus=corpus is not None,
496
+ min_dist=umap_params.min_dist,
497
+ n_neighbors=umap_params.n_neighbors,
498
+ n_samples=umap_params.n_samples,
499
+ is_development=dev,
500
+ web_manifest_path=SERVER_DIR / "static" / ".vite" / "manifest.json",
501
+ ),
502
+ ),
503
+ name="static",
504
+ )
505
+
510
506
  app.state.db = db
511
507
  if tracer_provider:
512
- from opentelemetry.instrumentation.starlette import StarletteInstrumentor
508
+ from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
513
509
 
514
- StarletteInstrumentor().instrument(tracer_provider=tracer_provider)
515
- StarletteInstrumentor.instrument_app(app, tracer_provider=tracer_provider)
516
- clean_ups.append(StarletteInstrumentor().uninstrument)
510
+ FastAPIInstrumentor().instrument(tracer_provider=tracer_provider)
511
+ FastAPIInstrumentor.instrument_app(app, tracer_provider=tracer_provider)
512
+ clean_ups.append(FastAPIInstrumentor().uninstrument)
517
513
  return app
phoenix/server/main.py CHANGED
@@ -131,6 +131,8 @@ if __name__ == "__main__":
131
131
  parser.add_argument("--no-internet", action="store_true")
132
132
  parser.add_argument("--umap_params", type=str, required=False, default=DEFAULT_UMAP_PARAMS_STR)
133
133
  parser.add_argument("--debug", action="store_true")
134
+ # Whether the app is running in a development environment
135
+ parser.add_argument("--dev", action="store_true")
134
136
  subparsers = parser.add_subparsers(dest="command", required=True)
135
137
  serve_parser = subparsers.add_parser("serve")
136
138
  datasets_parser = subparsers.add_parser("datasets")
@@ -258,6 +260,7 @@ if __name__ == "__main__":
258
260
  if corpus_inferences is None
259
261
  else create_model_from_inferences(corpus_inferences),
260
262
  debug=args.debug,
263
+ dev=args.dev,
261
264
  read_only=read_only,
262
265
  enable_prometheus=enable_prometheus,
263
266
  initial_spans=fixture_spans,
@@ -0,0 +1,78 @@
1
+ {
2
+ "_components-C8sm_r1F.js": {
3
+ "file": "assets/components-C8sm_r1F.js",
4
+ "name": "components",
5
+ "imports": [
6
+ "_vendor-CUDAPm8e.js",
7
+ "_vendor-arizeai-Do2HOmcL.js",
8
+ "_pages-bN7juCjh.js",
9
+ "_vendor-three-DwGkEfCM.js",
10
+ "_vendor-codemirror-CrdxOlMs.js"
11
+ ]
12
+ },
13
+ "_pages-bN7juCjh.js": {
14
+ "file": "assets/pages-bN7juCjh.js",
15
+ "name": "pages",
16
+ "imports": [
17
+ "_vendor-CUDAPm8e.js",
18
+ "_components-C8sm_r1F.js",
19
+ "_vendor-arizeai-Do2HOmcL.js",
20
+ "_vendor-recharts-PKRvByVe.js",
21
+ "_vendor-codemirror-CrdxOlMs.js"
22
+ ]
23
+ },
24
+ "_vendor-!~{003}~.js": {
25
+ "file": "assets/vendor-DxkFTwjz.css",
26
+ "src": "_vendor-!~{003}~.js"
27
+ },
28
+ "_vendor-CUDAPm8e.js": {
29
+ "file": "assets/vendor-CUDAPm8e.js",
30
+ "name": "vendor",
31
+ "imports": [
32
+ "_vendor-three-DwGkEfCM.js"
33
+ ],
34
+ "css": [
35
+ "assets/vendor-DxkFTwjz.css"
36
+ ]
37
+ },
38
+ "_vendor-arizeai-Do2HOmcL.js": {
39
+ "file": "assets/vendor-arizeai-Do2HOmcL.js",
40
+ "name": "vendor-arizeai",
41
+ "imports": [
42
+ "_vendor-CUDAPm8e.js"
43
+ ]
44
+ },
45
+ "_vendor-codemirror-CrdxOlMs.js": {
46
+ "file": "assets/vendor-codemirror-CrdxOlMs.js",
47
+ "name": "vendor-codemirror",
48
+ "imports": [
49
+ "_vendor-CUDAPm8e.js"
50
+ ]
51
+ },
52
+ "_vendor-recharts-PKRvByVe.js": {
53
+ "file": "assets/vendor-recharts-PKRvByVe.js",
54
+ "name": "vendor-recharts",
55
+ "imports": [
56
+ "_vendor-CUDAPm8e.js"
57
+ ]
58
+ },
59
+ "_vendor-three-DwGkEfCM.js": {
60
+ "file": "assets/vendor-three-DwGkEfCM.js",
61
+ "name": "vendor-three"
62
+ },
63
+ "index.tsx": {
64
+ "file": "assets/index-BEKPzgQs.js",
65
+ "name": "index",
66
+ "src": "index.tsx",
67
+ "isEntry": true,
68
+ "imports": [
69
+ "_vendor-CUDAPm8e.js",
70
+ "_vendor-arizeai-Do2HOmcL.js",
71
+ "_components-C8sm_r1F.js",
72
+ "_pages-bN7juCjh.js",
73
+ "_vendor-three-DwGkEfCM.js",
74
+ "_vendor-codemirror-CrdxOlMs.js",
75
+ "_vendor-recharts-PKRvByVe.js"
76
+ ]
77
+ }
78
+ }