Skip to content

Commit

Permalink
Change admin endpoint name (#5447)
Browse files Browse the repository at this point in the history
  • Loading branch information
ndmlny-qs authored Sep 14, 2023
1 parent 46b5ac9 commit 23550b2
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 3 deletions.
14 changes: 14 additions & 0 deletions doc/how_to/profiling/admin.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,22 @@ This guide addresses how to enable the admin Panel to begin monitoring resource

The `/admin` panel provides an overview of the current application and provides tools for debugging and profiling. It can be enabled by passing the ``--admin`` argument to the `panel serve` command.

```bash
panel serve my-app.py --admin
```

When you have successfully enabled it you should be able to visit the `/admin` endpoint of your application, e.g. if you are serving locally on port 5006, visit `http://localhost:5006/admin`. You should now be greeted with the overview page, which provides some details about currently active sessions, running versions and resource usage (if `psutil` is installed):

<img src="../../_static/admin_overview.png" width="70%"></img>

## Changing the admin panel endpoint

You can change the endpoint that the admin page is rendered at by using the flag `--admin-endpoint="/my-new-admin-endpoint"`. This will change where the admin endpoint is in the Bokeh server, and cause a `404: Not Found` page to be shown if you navigate to the default `/admin` path discussed above. As an example, using the following command to start your Panel app

```bash
panel serve my-app.py --admin --admin-endpoint="/my-new-admin-endpoint"
```

and navigating to [http://localhost:5006/admin](http://localhost:5006/admin) will result in a 404 page, however, navigating to [http://localhost:5006/my-new-admin-endpoint](http://localhost:5006/my-new-admin-endpoint) will result in the admin panel.

## Related Resources
17 changes: 15 additions & 2 deletions panel/command/serve.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,12 @@ class Serve(_BkServe):
action = 'store_true',
help = "Whether to add an admin panel."
)),
('--admin-endpoint', dict(
action = 'store',
type = str,
help = "Name to use for the admin endpoint.",
default = None
)),
('--admin-log-level', dict(
action = 'store',
default = None,
Expand Down Expand Up @@ -348,17 +354,24 @@ def customize_kwargs(self, args, server_kwargs):
if args.admin:
from ..io.admin import admin_panel
from ..io.server import per_app_patterns

# If `--admin-endpoint` is not set, then we default to the `/admin` path.
admin_path = "/admin"
if args.admin_endpoint:
admin_path = args.admin_endpoint
admin_path = admin_path if admin_path.startswith('/') else f'/{admin_path}'

config._admin = True
app = Application(FunctionHandler(admin_panel))
unused_timeout = args.check_unused_sessions or 15000
state._admin_context = app_ctx = AdminApplicationContext(
app, unused_timeout=unused_timeout, url='/admin'
app, unused_timeout=unused_timeout, url=admin_path
)
if all(not isinstance(handler, DocumentLifecycleHandler) for handler in app._handlers):
app.add(DocumentLifecycleHandler())
app_patterns = []
for p in per_app_patterns:
route = '/admin' + p[0]
route = admin_path + p[0]
context = {"application_context": app_ctx}
app_patterns.append((route, p[1], context))

Expand Down
7 changes: 6 additions & 1 deletion panel/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,8 @@ class _config(_base_config):

_admin = param.Boolean(default=False, doc="Whether the admin panel was enabled.")

_admin_endpoint = param.String(default=None, doc="Name to use for the admin endpoint.")

_admin_log_level = param.Selector(
default='DEBUG', objects=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'],
doc="Log level of the Admin Panel logger")
Expand Down Expand Up @@ -455,6 +457,10 @@ def _template_hook(self, value):
def _doc_build(self):
return os.environ.get('PANEL_DOC_BUILD')

@property
def admin_endpoint(self):
return os.environ.get('PANEL_ADMIN_ENDPOINT', self._admin_endpoint)

@property
def admin_log_level(self):
admin_log_level = os.environ.get('PANEL_ADMIN_LOG_LEVEL', self._admin_log_level)
Expand Down Expand Up @@ -580,7 +586,6 @@ def theme(self):
config = _config(**{k: None if p.allow_None else getattr(_config, k)
for k, p in _params.items() if k != 'name'})


class panel_extension(_pyviz_extension):
"""
Initializes and configures Panel. You should always run `pn.extension`.
Expand Down
24 changes: 24 additions & 0 deletions panel/tests/command/test_serve.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,30 @@ def test_autoreload_app(py_file):
assert r2.status_code == 200
assert "<title>B</title>" in r2.content.decode('utf-8')

@unix_only
def test_serve_admin(py_file):
app = "import panel as pn; pn.Row('# Example').servable(title='A')"
write_file(app, py_file.file)

with run_panel_serve(["--port", "0", '--admin', py_file.name]) as p:
port = wait_for_port(p.stdout)
r = requests.get(f"http://localhost:{port}/admin")
assert r.status_code == 200
assert "Admin" in r.content.decode('utf-8')

@unix_only
def test_serve_admin_custom_endpoint(py_file):
app = "import panel as pn; pn.Row('# Example').servable(title='A')"
write_file(app, py_file.file)

with run_panel_serve(["--port", "0", '--admin', '--admin-endpoint', 'foo', py_file.name]) as p:
port = wait_for_port(p.stdout)
r = requests.get(f"http://localhost:{port}/foo")
assert r.status_code == 200
assert "Admin" in r.content.decode('utf-8')
r2 = requests.get(f"http://localhost:{port}/admin")
assert r2.status_code == 404

@unix_only
@pytest.mark.parametrize('relative', [True, False])
def test_custom_html_index(relative, html_file):
Expand Down

0 comments on commit 23550b2

Please sign in to comment.