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: Add ASGI root path parameter to Phoenix server #3186

Merged
merged 9 commits into from
May 17, 2024

Conversation

sbachstein
Copy link
Contributor

@sbachstein sbachstein commented May 13, 2024

Fixes #2918

Allow for a root path parameter so that Phoenix can be hosted behind a proxy with a path prefix.

Session code has not been adjusted because the adjustment of the root path is probably not needed in this scenario.
Client and Exporter code have not been adjusted because they provide explicit endpoint parameters where a full URL can be given.

@dosubot dosubot bot added the size:S This PR changes 10-29 lines, ignoring generated files. label May 13, 2024
Copy link
Contributor

github-actions bot commented May 13, 2024

CLA Assistant Lite bot All contributors have signed the CLA ✍️ ✅

@sbachstein sbachstein force-pushed the feature/asgi_root_path branch 3 times, most recently from d388c72 to 9535709 Compare May 14, 2024 08:39
Allow for a root path parameter so that Phoenix can be hosted behind a proxy with a path prefix
@sbachstein
Copy link
Contributor Author

I have read the CLA Document and I hereby sign the CLA

github-actions bot added a commit that referenced this pull request May 14, 2024
@sbachstein sbachstein changed the title Add ASGI root path parameter to Phoenix server feat: Add ASGI root path parameter to Phoenix server May 14, 2024
@@ -10,6 +10,7 @@
ENV_PHOENIX_PORT = "PHOENIX_PORT"
ENV_PHOENIX_GRPC_PORT = "PHOENIX_GRPC_PORT"
ENV_PHOENIX_HOST = "PHOENIX_HOST"
ENV_PHOENIX_ROOT_PATH = "PHOENIX_ROOT_PATH"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the changing env var name PHOENIX_HOST_ROOT_PATH is a bit better? We manage all of our configuration via environment variables and PHOENIX_ROOT_PATH might sound a little too generic

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, should we match the CLI parameter then to also be --host-root-path or should we stick with the --root-path parameter as it is known from uvicorn, for example?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Went with the matching CLI parameter for now.

@anticorrelator
Copy link
Contributor

Thanks so much for the contribution @sbachstein! This looks great, small request for a more specific config name

@RogerHYang
Copy link
Contributor

The client needs to be updated, otherwise it'll have the wrong url.

e.g.

urljoin(self._base_url, "/v1/traces"),

@sbachstein
Copy link
Contributor Author

The client needs to be updated, otherwise it'll have the wrong url.

e.g.

urljoin(self._base_url, "/v1/traces"),

The client provides the option to take the base path from the endpoint parameter (or environment variable). Do you think this is not sufficient and we need to, additionally, offer the option to specify HOST, PORT and ROOT_PATH?

@RogerHYang
Copy link
Contributor

The issue is that urljoin is currently absolute. See the four scenarios below

Screenshot 2024-05-15 at 7 40 16 AM

@dosubot dosubot bot added size:M This PR changes 30-99 lines, ignoring generated files. and removed size:S This PR changes 10-29 lines, ignoring generated files. labels May 15, 2024
@sbachstein
Copy link
Contributor Author

Very good catch, thank you for the hint. I adjusted all usages of urljoin to avoid the absolute paths.

@RogerHYang
Copy link
Contributor

RogerHYang commented May 15, 2024

Thanks for the update. Can we make sure that base_url always ends with /, otherwise the urljoin is still not correct.

abc below is gone because it doesn't end with /

>>> from urllib.parse import urljoin
>>> urljoin("http://xyz.com/abc", "rst")
'http://xyz.com/rst'

While we're at it, we could also add the root path as shown below.

self._base_url = ( 
    endpoint
    or get_env_collector_endpoint()
    or urljoin(f"http://{host}:{get_env_port()}", get_env_host_root_path())
).rstrip("/") + "/"

self._base_url = (
endpoint or get_env_collector_endpoint() or f"http://{host}:{get_env_port()}"
)

@@ -119,6 +120,7 @@ def _get_pid_file() -> Path:
parser.add_argument("--export_path")
parser.add_argument("--host", type=str, required=False)
parser.add_argument("--port", type=int, required=False)
parser.add_argument("--host-root-path", type=str, required=False)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure we need the command line argument here in addition to the environment variable. We've been deprecating command line arguments such as --enable-prometheus that have environment variable equivalents if setting them via environment variables feels more natural, e.g., in Kubernetes. I think host root path probably falls into that category.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, I removed the CLI parameter.

CLI parameters for settings that are naturally adjusted via environment variables are discouraged for Phoenix
@sbachstein
Copy link
Contributor Author

@RogerHYang Thank you for the hint again, that was kind of unexpected behavior for me, good to know!

@@ -18,6 +18,29 @@
from phoenix.trace.trace_dataset import TraceDataset


def test_base_path(monkeypatch: pytest.MonkeyPatch):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you for the test!

Copy link
Contributor

@RogerHYang RogerHYang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just tried this and I don't think the uvicorn implementation is correct.

At the minimum the traces endpoint is not advertised accurately.

Screenshot 2024-05-16 at 12 20 50 PM Screenshot 2024-05-16 at 12 21 11 PM Screenshot 2024-05-16 at 12 17 40 PM Screenshot 2024-05-16 at 12 17 49 PM Screenshot 2024-05-16 at 12 20 01 PM

@anticorrelator
Copy link
Contributor

@sbachstein looks like the starlette app needs to be made aware of the root path too, thanks for checking this @RogerHYang

@sbachstein
Copy link
Contributor Author

sbachstein commented May 17, 2024

To me that is expected behavior. If the application is mounted at a root path with prefix by a proxy then the proxy would also make sure to rewrite the HTTP path and remove the root path from the request. That is also how I understand and have experienced the mechanisms of uvicorn/starlette root paths.

Here is how FastAPI explains the behavior of the root path: https://fastapi.tiangolo.com/advanced/behind-a-proxy/

Copy link
Contributor

@RogerHYang RogerHYang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this is LGTM. Sorry for the hold up.

@RogerHYang RogerHYang merged commit e27cc5d into Arize-ai:main May 17, 2024
8 checks passed
@sbachstein
Copy link
Contributor Author

Thank you for the thorough review!

@axiomofjoy
Copy link
Contributor

@sbachstein Thanks for making Phoenix better!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
size:M This PR changes 30-99 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add Env Parameter for Prefix for the app
4 participants