arize-phoenix 2.4.1rc4__py3-none-any.whl → 2.4.1rc6__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-2.4.1rc4.dist-info → arize_phoenix-2.4.1rc6.dist-info}/METADATA +1 -1
- {arize_phoenix-2.4.1rc4.dist-info → arize_phoenix-2.4.1rc6.dist-info}/RECORD +11 -11
- phoenix/server/app.py +10 -19
- phoenix/server/templates/index.html +3 -2
- phoenix/server/thread_server.py +3 -1
- phoenix/services.py +2 -0
- phoenix/session/session.py +45 -7
- phoenix/version.py +1 -1
- {arize_phoenix-2.4.1rc4.dist-info → arize_phoenix-2.4.1rc6.dist-info}/WHEEL +0 -0
- {arize_phoenix-2.4.1rc4.dist-info → arize_phoenix-2.4.1rc6.dist-info}/licenses/IP_NOTICE +0 -0
- {arize_phoenix-2.4.1rc4.dist-info → arize_phoenix-2.4.1rc6.dist-info}/licenses/LICENSE +0 -0
|
@@ -3,8 +3,8 @@ phoenix/config.py,sha256=wYmvT1I3wad8YIunbsiJ0nBu4-W8pUZwwbs5CxJKRs8,2442
|
|
|
3
3
|
phoenix/datetime_utils.py,sha256=D955QLrkgrrSdUM6NyqbCeAu2SMsjhR5rHVQEsVUdng,2773
|
|
4
4
|
phoenix/exceptions.py,sha256=igIWGAg3m8jm5YwQDeCY1p8ml_60A7zaGVXJ1yZhY9s,44
|
|
5
5
|
phoenix/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
6
|
-
phoenix/services.py,sha256=
|
|
7
|
-
phoenix/version.py,sha256=
|
|
6
|
+
phoenix/services.py,sha256=f6AeyKTuOpy9RCcTCjVH3gx5nYZhbTMFOuv1WSUOB5o,4992
|
|
7
|
+
phoenix/version.py,sha256=PBfHg55LBkQ021mwCxcQp5JEkKfbXnP1GrPdM50Lifo,25
|
|
8
8
|
phoenix/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
9
|
phoenix/core/embedding_dimension.py,sha256=zKGbcvwOXgLf-yrJBpQyKtd-LEOPRKHnUToyAU8Owis,87
|
|
10
10
|
phoenix/core/evals.py,sha256=OrHeYlh804rpcZIXTA6kan2mzSZMfgpphNNQdPMpNoM,7597
|
|
@@ -55,11 +55,11 @@ phoenix/pointcloud/pointcloud.py,sha256=ms-h1FLC0xXb3sk256zpSuZQDE2hdOAJzRNBklP0
|
|
|
55
55
|
phoenix/pointcloud/projectors.py,sha256=zO_RrtDYSv2rqVOfIP2_9Cv11Dc8EmcZR94xhFcBYPU,1057
|
|
56
56
|
phoenix/pointcloud/umap_parameters.py,sha256=lJsEOrbSuSiqI7g4Yt6xj7kgYxEqoep4ZHWLr6VWBqw,1760
|
|
57
57
|
phoenix/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
58
|
-
phoenix/server/app.py,sha256
|
|
58
|
+
phoenix/server/app.py,sha256=-Xn6BTdQsJ_VAAOWwiLQr_ZeyfOBSO_0cFyY7ewkqFM,7802
|
|
59
59
|
phoenix/server/evaluation_handler.py,sha256=HzaoD8Cv9HbEdd0nYSTZoakKsE8Ic5lVjeuBh0vnhoA,1554
|
|
60
60
|
phoenix/server/main.py,sha256=ZWV_UQOE2c5Gx4x_2UQiZIww3JMRWosza5BbzstTUsg,6814
|
|
61
61
|
phoenix/server/span_handler.py,sha256=reYUDaN5bavSFjEiSfvYyAG_mpJs6S3iB-RNCkZrSUU,1295
|
|
62
|
-
phoenix/server/thread_server.py,sha256=
|
|
62
|
+
phoenix/server/thread_server.py,sha256=z6VwimjlHEsOavlybcQFVWubZvHDGYOH7p61nscC0lU,2164
|
|
63
63
|
phoenix/server/trace_handler.py,sha256=pXanrp9L21Mh7MnyJbj202NJ-Rn4bCjG0oL4DtdKcls,2074
|
|
64
64
|
phoenix/server/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
65
65
|
phoenix/server/api/context.py,sha256=02vRgyLFpDCmh97QwsjWD5cdNZkoCUtDPPs1YItbdbI,583
|
|
@@ -130,10 +130,10 @@ phoenix/server/static/index.js,sha256=dJKCIzqIRBf_IKfXUbnSZnegpgnfMV3wsnFGXWV9Ie
|
|
|
130
130
|
phoenix/server/static/index.js.map,sha256=Pe5FBAB7cKnRik9CrPFsP4AHe3MR3LUI7OShR2pA5ys,15465655
|
|
131
131
|
phoenix/server/static/modernizr.js,sha256=mvK-XtkNqjOral-QvzoqsyOMECXIMu5BQwSVN_wcU9c,2564
|
|
132
132
|
phoenix/server/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
133
|
-
phoenix/server/templates/index.html,sha256=
|
|
133
|
+
phoenix/server/templates/index.html,sha256=7N-1rUz82nvblYndZLdZ_VdIOSKD5wGq4LyO5Cs-P5w,1916
|
|
134
134
|
phoenix/session/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
135
135
|
phoenix/session/evaluation.py,sha256=s5OivScAMSj8qfU4IexpmbyKvcGBj_nt-GP_13_o-iY,4843
|
|
136
|
-
phoenix/session/session.py,sha256=
|
|
136
|
+
phoenix/session/session.py,sha256=nZxE2CCip6vgUU9KyzaxQmSLF3v4ywYGLWmCUR1K5no,20104
|
|
137
137
|
phoenix/trace/__init__.py,sha256=4d_MqzUIFmlY9WWcFeTONJ4xL5mPGoWZaPM2TJ0ZDBQ,266
|
|
138
138
|
phoenix/trace/evaluation_conventions.py,sha256=t8jydM3U0-T5YpiQKRJ3tWdWGlHtzKyttYdw-ddvPOk,1048
|
|
139
139
|
phoenix/trace/exporter.py,sha256=z3xrGJhIRh7XMy4Q1FkR3KmFZym-GX0XxLTZ6eSnN0Q,4347
|
|
@@ -167,8 +167,8 @@ phoenix/trace/v1/evaluation_pb2.pyi,sha256=cCbbx06gwQmaH14s3J1X25TtaARh-k1abbxQd
|
|
|
167
167
|
phoenix/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
168
168
|
phoenix/utilities/error_handling.py,sha256=7b5rpGFj9EWZ8yrZK1IHvxB89suWk3lggDayUQcvZds,1946
|
|
169
169
|
phoenix/utilities/logging.py,sha256=lDXd6EGaamBNcQxL4vP1au9-i_SXe0OraUDiJOcszSw,222
|
|
170
|
-
arize_phoenix-2.4.
|
|
171
|
-
arize_phoenix-2.4.
|
|
172
|
-
arize_phoenix-2.4.
|
|
173
|
-
arize_phoenix-2.4.
|
|
174
|
-
arize_phoenix-2.4.
|
|
170
|
+
arize_phoenix-2.4.1rc6.dist-info/METADATA,sha256=QIZlIFPN4oM5mMXyYkwIALOztVAI59q5eACLivAVnQw,26482
|
|
171
|
+
arize_phoenix-2.4.1rc6.dist-info/WHEEL,sha256=9QBuHhg6FNW7lppboF2vKVbCGTVzsFykgRQjjlajrhA,87
|
|
172
|
+
arize_phoenix-2.4.1rc6.dist-info/licenses/IP_NOTICE,sha256=JBqyyCYYxGDfzQ0TtsQgjts41IJoa-hiwDrBjCb9gHM,469
|
|
173
|
+
arize_phoenix-2.4.1rc6.dist-info/licenses/LICENSE,sha256=HFkW9REuMOkvKRACuwLPT0hRydHb3zNg-fdFt94td18,3794
|
|
174
|
+
arize_phoenix-2.4.1rc6.dist-info/RECORD,,
|
phoenix/server/app.py
CHANGED
|
@@ -4,7 +4,7 @@ from pathlib import Path
|
|
|
4
4
|
from typing import Any, NamedTuple, Optional, Union
|
|
5
5
|
|
|
6
6
|
from starlette.applications import Starlette
|
|
7
|
-
from starlette.datastructures import QueryParams
|
|
7
|
+
from starlette.datastructures import Headers, QueryParams
|
|
8
8
|
from starlette.endpoints import HTTPEndpoint
|
|
9
9
|
from starlette.exceptions import HTTPException
|
|
10
10
|
from starlette.middleware import Middleware
|
|
@@ -35,8 +35,6 @@ logger = logging.getLogger(__name__)
|
|
|
35
35
|
|
|
36
36
|
templates = Jinja2Templates(directory=SERVER_DIR / "templates")
|
|
37
37
|
|
|
38
|
-
_databricks_basename_pattern = r"https://.*?\.com(/driver-proxy/o/\d+/\d+-\d+-\w+/\d+/)"
|
|
39
|
-
|
|
40
38
|
|
|
41
39
|
class AppConfig(NamedTuple):
|
|
42
40
|
has_corpus: bool
|
|
@@ -53,29 +51,22 @@ def _is_databricks(url: str) -> bool:
|
|
|
53
51
|
return "databricks" in url
|
|
54
52
|
|
|
55
53
|
|
|
56
|
-
def _get_databricks_basename(url: str) -> str:
|
|
57
|
-
match = re.search(_databricks_basename_pattern, url)
|
|
58
|
-
if match is None:
|
|
59
|
-
raise ValueError("Could not decipher the basename in Databricks URL")
|
|
60
|
-
return match.group(1)
|
|
61
|
-
|
|
62
|
-
|
|
63
54
|
def _get_basename(request: Request) -> str:
|
|
64
55
|
"""
|
|
65
56
|
Determine the basename for the API and static content.
|
|
66
57
|
If the server is running in a hosted notebook, the base URL
|
|
67
58
|
must be configured to point to the hosted notebook's proxy.
|
|
68
59
|
"""
|
|
69
|
-
|
|
70
|
-
if _is_sagemaker(url):
|
|
60
|
+
if _is_sagemaker(str(request.url)):
|
|
71
61
|
# Sagemaker sets up a proxy at /proxy/6006
|
|
72
62
|
# NB: this is the only port that is open
|
|
73
63
|
return "/proxy/6006"
|
|
74
|
-
if _is_databricks(
|
|
75
|
-
# For Databricks, the
|
|
76
|
-
#
|
|
77
|
-
|
|
78
|
-
|
|
64
|
+
if _is_databricks(request.headers.get("referer", "")):
|
|
65
|
+
# NG: For Databricks, the request.url is the IP address,
|
|
66
|
+
# not the DNS address, so we must rely on the referer
|
|
67
|
+
|
|
68
|
+
# For Databricks, we set the root_path to the basename
|
|
69
|
+
return request.scope.get("root_path", "")
|
|
79
70
|
# URL is relative to / for colab and local
|
|
80
71
|
return ""
|
|
81
72
|
|
|
@@ -107,9 +98,9 @@ class Static(StaticFiles):
|
|
|
107
98
|
"n_neighbors": self._app_config.n_neighbors,
|
|
108
99
|
"n_samples": self._app_config.n_samples,
|
|
109
100
|
"basename": _get_basename(request),
|
|
110
|
-
"path": request.headers.get(":path:", ""),
|
|
111
|
-
"authority": request.headers.get(":authority:", ""),
|
|
112
101
|
"request": request,
|
|
102
|
+
"referer": request.headers.get("referer", ""),
|
|
103
|
+
"root_path": request.scope.get("root_path", ""),
|
|
113
104
|
},
|
|
114
105
|
)
|
|
115
106
|
except Exception as e:
|
|
@@ -22,8 +22,9 @@
|
|
|
22
22
|
<div id="root"></div>
|
|
23
23
|
// Request Info:
|
|
24
24
|
// URL: {{request.url}}
|
|
25
|
-
//
|
|
26
|
-
//
|
|
25
|
+
// Base URL: {{request.base_url}}
|
|
26
|
+
// Headers: {{request.headers}}
|
|
27
|
+
// Referer: {{referer}}
|
|
27
28
|
<script>(function() {
|
|
28
29
|
Object.defineProperty(window, "Config", {
|
|
29
30
|
// Place any server-side injected config here
|
phoenix/server/thread_server.py
CHANGED
|
@@ -2,7 +2,7 @@ import asyncio
|
|
|
2
2
|
import logging
|
|
3
3
|
from threading import Thread
|
|
4
4
|
from time import sleep, time
|
|
5
|
-
from typing import Generator
|
|
5
|
+
from typing import Generator, Optional
|
|
6
6
|
|
|
7
7
|
from starlette.applications import Starlette
|
|
8
8
|
from uvicorn import Config, Server
|
|
@@ -27,6 +27,7 @@ class ThreadServer(Server):
|
|
|
27
27
|
app: Starlette,
|
|
28
28
|
host: str,
|
|
29
29
|
port: int,
|
|
30
|
+
root_path: str,
|
|
30
31
|
) -> None:
|
|
31
32
|
# Must use asyncio loop if nest_asyncio is applied
|
|
32
33
|
# Otherwise the app crashes when the server is run in a thread
|
|
@@ -35,6 +36,7 @@ class ThreadServer(Server):
|
|
|
35
36
|
app=app,
|
|
36
37
|
host=host,
|
|
37
38
|
port=port,
|
|
39
|
+
root_path=root_path,
|
|
38
40
|
# TODO: save logs to file
|
|
39
41
|
log_level=logging.ERROR,
|
|
40
42
|
loop=loop,
|
phoenix/services.py
CHANGED
|
@@ -110,6 +110,7 @@ class AppService(Service):
|
|
|
110
110
|
export_path: Path,
|
|
111
111
|
host: str,
|
|
112
112
|
port: int,
|
|
113
|
+
root_path: str,
|
|
113
114
|
primary_dataset_name: str,
|
|
114
115
|
umap_params: str,
|
|
115
116
|
reference_dataset_name: Optional[str],
|
|
@@ -119,6 +120,7 @@ class AppService(Service):
|
|
|
119
120
|
self.export_path = export_path
|
|
120
121
|
self.host = host
|
|
121
122
|
self.port = port
|
|
123
|
+
self.root_path = root_path # TODO(mikeldking): Add support for root_path
|
|
122
124
|
self.__primary_dataset_name = primary_dataset_name
|
|
123
125
|
self.__umap_params = umap_params
|
|
124
126
|
self.__reference_dataset_name = reference_dataset_name
|
phoenix/session/session.py
CHANGED
|
@@ -13,6 +13,7 @@ from typing import (
|
|
|
13
13
|
Iterable,
|
|
14
14
|
List,
|
|
15
15
|
Mapping,
|
|
16
|
+
NamedTuple,
|
|
16
17
|
Optional,
|
|
17
18
|
Set,
|
|
18
19
|
Union,
|
|
@@ -96,6 +97,7 @@ class Session(ABC):
|
|
|
96
97
|
default_umap_parameters: Optional[Mapping[str, Any]] = None,
|
|
97
98
|
host: Optional[str] = None,
|
|
98
99
|
port: Optional[int] = None,
|
|
100
|
+
root_path: Optional[str] = None,
|
|
99
101
|
notebook_env: Optional[NotebookEnvironment] = None,
|
|
100
102
|
):
|
|
101
103
|
self.primary_dataset = primary_dataset
|
|
@@ -125,6 +127,7 @@ class Session(ABC):
|
|
|
125
127
|
|
|
126
128
|
self.host = host or get_env_host()
|
|
127
129
|
self.port = port or get_env_port()
|
|
130
|
+
self.root_path = root_path or ""
|
|
128
131
|
self.temp_dir = TemporaryDirectory()
|
|
129
132
|
self.export_path = Path(self.temp_dir.name) / "exports"
|
|
130
133
|
self.export_path.mkdir(parents=True, exist_ok=True)
|
|
@@ -225,6 +228,7 @@ class ProcessSession(Session):
|
|
|
225
228
|
default_umap_parameters: Optional[Mapping[str, Any]] = None,
|
|
226
229
|
host: Optional[str] = None,
|
|
227
230
|
port: Optional[int] = None,
|
|
231
|
+
root_path: Optional[str] = None,
|
|
228
232
|
notebook_env: Optional[NotebookEnvironment] = None,
|
|
229
233
|
) -> None:
|
|
230
234
|
super().__init__(
|
|
@@ -235,6 +239,7 @@ class ProcessSession(Session):
|
|
|
235
239
|
default_umap_parameters=default_umap_parameters,
|
|
236
240
|
host=host,
|
|
237
241
|
port=port,
|
|
242
|
+
root_path=root_path,
|
|
238
243
|
notebook_env=notebook_env,
|
|
239
244
|
)
|
|
240
245
|
primary_dataset.to_disc()
|
|
@@ -254,6 +259,7 @@ class ProcessSession(Session):
|
|
|
254
259
|
self.export_path,
|
|
255
260
|
self.host,
|
|
256
261
|
self.port,
|
|
262
|
+
self.root_path,
|
|
257
263
|
self.primary_dataset.name,
|
|
258
264
|
umap_params_str,
|
|
259
265
|
reference_dataset_name=(
|
|
@@ -286,6 +292,7 @@ class ThreadSession(Session):
|
|
|
286
292
|
default_umap_parameters: Optional[Mapping[str, Any]] = None,
|
|
287
293
|
host: Optional[str] = None,
|
|
288
294
|
port: Optional[int] = None,
|
|
295
|
+
root_path: Optional[str] = None,
|
|
289
296
|
notebook_env: Optional[NotebookEnvironment] = None,
|
|
290
297
|
):
|
|
291
298
|
super().__init__(
|
|
@@ -296,6 +303,7 @@ class ThreadSession(Session):
|
|
|
296
303
|
default_umap_parameters=default_umap_parameters,
|
|
297
304
|
host=host,
|
|
298
305
|
port=port,
|
|
306
|
+
root_path=root_path,
|
|
299
307
|
notebook_env=notebook_env,
|
|
300
308
|
)
|
|
301
309
|
# Initialize an app service that keeps the server running
|
|
@@ -311,6 +319,7 @@ class ThreadSession(Session):
|
|
|
311
319
|
app=self.app,
|
|
312
320
|
host=self.host,
|
|
313
321
|
port=self.port,
|
|
322
|
+
root_path=self.root_path,
|
|
314
323
|
).run_in_thread()
|
|
315
324
|
# start the server
|
|
316
325
|
self.server_thread = next(self.server)
|
|
@@ -401,6 +410,7 @@ def launch_app(
|
|
|
401
410
|
|
|
402
411
|
host = host or get_env_host()
|
|
403
412
|
port = port or get_env_port()
|
|
413
|
+
root_path = _get_root_path(nb_env, port)
|
|
404
414
|
|
|
405
415
|
if run_in_thread:
|
|
406
416
|
_session = ThreadSession(
|
|
@@ -411,6 +421,7 @@ def launch_app(
|
|
|
411
421
|
default_umap_parameters,
|
|
412
422
|
host=host,
|
|
413
423
|
port=port,
|
|
424
|
+
root_path=root_path,
|
|
414
425
|
notebook_env=nb_env,
|
|
415
426
|
)
|
|
416
427
|
# TODO: catch exceptions from thread
|
|
@@ -471,7 +482,8 @@ def _get_url(host: str, port: int, notebook_env: NotebookEnvironment) -> str:
|
|
|
471
482
|
# NB: Sagemaker notebooks only work with port 6006 - which is used by tensorboard
|
|
472
483
|
return f"{_get_sagemaker_notebook_base_url()}/proxy/{port}/"
|
|
473
484
|
if notebook_env == NotebookEnvironment.DATABRICKS:
|
|
474
|
-
|
|
485
|
+
context = _get_databricks_context()
|
|
486
|
+
return f"{_get_databricks_notebook_base_url(context)}/{port}/"
|
|
475
487
|
return f"http://{host}:{port}/"
|
|
476
488
|
|
|
477
489
|
|
|
@@ -552,9 +564,26 @@ def _get_sagemaker_notebook_base_url() -> str:
|
|
|
552
564
|
return f"https://{notebook_instance_name}.notebook.{region}.sagemaker.aws"
|
|
553
565
|
|
|
554
566
|
|
|
555
|
-
def
|
|
567
|
+
def _get_root_path(environment: Optional[NotebookEnvironment], port: int) -> str:
|
|
556
568
|
"""
|
|
557
|
-
Returns base
|
|
569
|
+
Returns the base path for the app if the app is running behind a proxy
|
|
570
|
+
"""
|
|
571
|
+
if environment == NotebookEnvironment.DATABRICKS:
|
|
572
|
+
context = _get_databricks_context()
|
|
573
|
+
return f"/driver-proxy/o/{context.org_id}/{context.cluster_id}/{port}/"
|
|
574
|
+
return ""
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
class DatabricksContext(NamedTuple):
|
|
578
|
+
host: str
|
|
579
|
+
org_id: str
|
|
580
|
+
cluster_id: str
|
|
581
|
+
|
|
582
|
+
|
|
583
|
+
def _get_databricks_context() -> DatabricksContext:
|
|
584
|
+
"""
|
|
585
|
+
Returns the databricks context for constructing the base url
|
|
586
|
+
and the base_path for the app
|
|
558
587
|
"""
|
|
559
588
|
import IPython
|
|
560
589
|
|
|
@@ -563,7 +592,16 @@ def _get_databricks_notebook_base_url() -> str:
|
|
|
563
592
|
notebook_context = json.loads(
|
|
564
593
|
dbutils.entry_point.getDbutils().notebook().getContext().toJson()
|
|
565
594
|
)["tags"]
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
595
|
+
|
|
596
|
+
return DatabricksContext(
|
|
597
|
+
host=notebook_context["browserHostName"],
|
|
598
|
+
org_id=notebook_context["orgId"],
|
|
599
|
+
cluster_id=notebook_context["clusterId"],
|
|
600
|
+
)
|
|
601
|
+
|
|
602
|
+
|
|
603
|
+
def _get_databricks_notebook_base_url(context: DatabricksContext) -> str:
|
|
604
|
+
"""
|
|
605
|
+
Returns base url of the databricks notebook by parsing the tags
|
|
606
|
+
"""
|
|
607
|
+
return f"https://{context.host}/driver-proxy/o/{context.org_id}/{context.cluster_id}/"
|
phoenix/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "2.4.
|
|
1
|
+
__version__ = "2.4.1rc6"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|