Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions cortex/tests/test_webgl_view.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"""Tests for the viewer plumbing in cortex.webgl.view that needs no browser."""

import pytest

from cortex.webgl import serve, view


def test_local_url_is_localhost(monkeypatch):
"""The URL opened on this machine must not depend on the hostname.

socket.gethostname() returns the mDNS name on macOS, which resolves to a
list of addresses (link-local ones included) and only reaches the server if
the firewall lets python accept connections on a non-loopback interface.
"""
monkeypatch.setattr(serve, "hostname", "mymac.local")
monkeypatch.setattr(view, "domain_name", "")

local, network = view._viewer_urls(39140)
assert local == "http://localhost:39140/mixer.html"
assert network == "http://mymac.local:39140/mixer.html"


def test_network_url_appends_configured_domain(monkeypatch):
"""webgl.domain_name is appended to the hostname, and never to localhost."""
monkeypatch.setattr(serve, "hostname", "mymac")
monkeypatch.setattr(view, "domain_name", ".example.org")

local, network = view._viewer_urls(8080)
assert local == "http://localhost:8080/mixer.html"
assert network == "http://mymac.example.org:8080/mixer.html"


@pytest.mark.parametrize("hostname", ["localhost", "mymac.local", "mymac"])
def test_urls_agree_on_port_and_path(monkeypatch, hostname):
"""Both URLs address the same running server."""
monkeypatch.setattr(serve, "hostname", hostname)
monkeypatch.setattr(view, "domain_name", "")

local, network = view._viewer_urls(1234)
for url in (local, network):
assert url.startswith("http://")
assert url.endswith(":1234/mixer.html")
37 changes: 34 additions & 3 deletions cortex/webgl/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,26 @@
colormaps = [(os.path.splitext(os.path.split(cm)[1])[0], serve.make_base64(cm))
for cm in sorted(colormaps)]


def _viewer_urls(port: int) -> tuple[str, str]:
"""Return the (local, network) URLs of a viewer running on `port`.

The local URL is the one to open on the machine running the server. The
network URL is built from the machine's hostname plus the configured
``webgl.domain_name``, and is the one to hand to someone else.

They have to be kept apart, because the hostname is not a dependable way
for this machine to reach itself. ``socket.gethostname()`` returns the mDNS
name on macOS (``mymac.local``), which resolves to a whole list of
addresses -- link-local ones among them -- and only reaches the server if
the local firewall lets this python process accept connections on a
non-loopback interface. None of that applies to localhost.
"""
local = "http://localhost:%d/mixer.html" % port
network = "http://%s%s:%d/mixer.html" % (serve.hostname, domain_name, port)
return local, network


def make_static(
outpath,
data,
Expand Down Expand Up @@ -1032,17 +1052,28 @@ def get_local_client(self):
port)

server.start()
local_url, network_url = _viewer_urls(server.port)
print("Started server on port %d"%server.port)
url = "http://%s%s:%d/mixer.html"%(serve.hostname, domain_name, server.port)
if network_url == local_url:
print("Open the viewer at %s"%local_url)
else:
print("Open the viewer at %s (from another machine: %s)"
%(local_url, network_url))
if open_browser:
webbrowser.open(url)
# This runs on the same machine as the server, so localhost is both
# correct and the most reliable thing to hand the browser.
webbrowser.open(local_url)
client = server.get_client()
client.server = server
return client
elif display_url:
try:
from IPython.display import HTML, display
display(HTML('Open viewer: <a href="{0}" target="_blank">{0}</a>'.format(url)))
link = 'Open viewer: <a href="{0}" target="_blank">{0}</a>'.format(local_url)
if network_url != local_url:
link += (' (from another machine: '
'<a href="{0}" target="_blank">{0}</a>)'.format(network_url))
display(HTML(link))
except:
pass

Expand Down