diff --git a/examples/user_guide/Deploy_and_Export.ipynb b/examples/user_guide/Deploy_and_Export.ipynb index d9d0f2a6ee..5cb40e52ca 100644 --- a/examples/user_guide/Deploy_and_Export.ipynb +++ b/examples/user_guide/Deploy_and_Export.ipynb @@ -238,7 +238,38 @@ ")\n", "```\n", "\n", - "The ``pn.serve`` function accepts the same arguments as the `show` method." + "The ``pn.serve`` accepts a number of arguments:\n", + "\n", + " panel: Viewable, function or {str: Viewable or function}\n", + " A Panel object, a function returning a Panel object or a\n", + " dictionary mapping from the URL slug to either.\n", + " port: int (optional, default=0)\n", + " Allows specifying a specific port\n", + " address: str\n", + " The address the server should listen on for HTTP requests.\n", + " websocket_origin: str or list(str) (optional)\n", + " A list of hosts that can connect to the websocket.\n", + "\n", + " This is typically required when embedding a server app in\n", + " an external web site.\n", + "\n", + " If None, \"localhost\" is used.\n", + " loop: tornado.ioloop.IOLoop (optional, default=IOLoop.current())\n", + " The tornado IOLoop to run the Server on\n", + " show: boolean (optional, default=False)\n", + " Whether to open the server in a new browser tab on start\n", + " start: boolean(optional, default=False)\n", + " Whether to start the Server\n", + " title: str or {str: str} (optional, default=None)\n", + " An HTML title for the application or a dictionary mapping\n", + " from the URL slug to a customized title\n", + " verbose: boolean (optional, default=True)\n", + " Whether to print the address and port\n", + " location: boolean or panel.io.location.Location\n", + " Whether to create a Location component to observe and\n", + " set the URL location.\n", + " kwargs: dict\n", + " Additional keyword arguments to pass to Server instance" ] }, { diff --git a/panel/io/notebook.py b/panel/io/notebook.py index 421af59328..b59a1a829a 100644 --- a/panel/io/notebook.py +++ b/panel/io/notebook.py @@ -239,8 +239,8 @@ def show_server(panel, notebook_url, port): else: origin = _origin_url(notebook_url) server_id = uuid.uuid4().hex - server = get_server(panel, port, origin, start=True, show=False, - server_id=server_id) + server = get_server(panel, port=port, websocket_origin=origin, + start=True, show=False, server_id=server_id) if callable(notebook_url): url = notebook_url(server.port) diff --git a/panel/io/server.py b/panel/io/server.py index 918769c36c..9d9f8c18f8 100644 --- a/panel/io/server.py +++ b/panel/io/server.py @@ -111,8 +111,9 @@ def unlocked(): curdoc.unhold() -def serve(panels, port=0, websocket_origin=None, loop=None, show=True, - start=True, title=None, verbose=True, location=True, **kwargs): +def serve(panels, port=0, address=None, websocket_origin=None, loop=None, + show=True, start=True, title=None, verbose=True, location=True, + **kwargs): """ Allows serving one or more panel objects on a single server. The panels argument should be either a Panel object or a function @@ -123,11 +124,13 @@ def serve(panels, port=0, websocket_origin=None, loop=None, show=True, Arguments --------- - panel: Viewable, function or {str: Viewable} + panel: Viewable, function or {str: Viewable or function} A Panel object, a function returning a Panel object or a dictionary mapping from the URL slug to either. port: int (optional, default=0) Allows specifying a specific port + address : str + The address the server should listen on for HTTP requests. websocket_origin: str or list(str) (optional) A list of hosts that can connect to the websocket. @@ -152,8 +155,8 @@ def serve(panels, port=0, websocket_origin=None, loop=None, show=True, kwargs: dict Additional keyword arguments to pass to Server instance """ - return get_server(panels, port, websocket_origin, loop, show, start, - title, verbose, location, **kwargs) + return get_server(panels, port, address, websocket_origin, loop, + show, start, title, verbose, location, **kwargs) class ProxyFallbackHandler(RequestHandler): @@ -195,9 +198,9 @@ def get_static_routes(static_dirs): return patterns -def get_server(panel, port=0, websocket_origin=None, loop=None, - show=False, start=False, title=None, verbose=False, - location=True, static_dirs={}, **kwargs): +def get_server(panel, port=0, address=None, websocket_origin=None, + loop=None, show=False, start=False, title=None, + verbose=False, location=True, static_dirs={}, **kwargs): """ Returns a Server instance with this panel attached as the root app. @@ -209,6 +212,8 @@ def get_server(panel, port=0, websocket_origin=None, loop=None, dictionary mapping from the URL slug to either. port: int (optional, default=0) Allows specifying a specific port + address : str + The address the server should listen on for HTTP requests. websocket_origin: str or list(str) (optional) A list of hosts that can connect to the websocket. @@ -217,24 +222,24 @@ def get_server(panel, port=0, websocket_origin=None, loop=None, If None, "localhost" is used. loop : tornado.ioloop.IOLoop (optional, default=IOLoop.current()) - The tornado IOLoop to run the Server on + The tornado IOLoop to run the Server on. show : boolean (optional, default=False) - Whether to open the server in a new browser tab on start + Whether to open the server in a new browser tab on start. start : boolean(optional, default=False) - Whether to start the Server - title: str or {str: str} (optional, default=None) + Whether to start the Server. + title : str or {str: str} (optional, default=None) An HTML title for the application or a dictionary mapping - from the URL slug to a customized title + from the URL slug to a customized title. verbose: boolean (optional, default=False) - Whether to report the address and port + Whether to report the address and port. location : boolean or panel.io.location.Location Whether to create a Location component to observe and set the URL location. static_dirs: dict (optional, default={}) A dictionary of routes and local paths to serve as static file - directories on those routes + directories on those routes. kwargs: dict - Additional keyword arguments to pass to Server instance + Additional keyword arguments to pass to Server instance. Returns ------- @@ -286,6 +291,9 @@ def get_server(panel, port=0, websocket_origin=None, loop=None, if 'index' not in opts: opts['index'] = INDEX_HTML + if address is not None: + opts['address'] = address + if websocket_origin: if not isinstance(websocket_origin, list): websocket_origin = [websocket_origin] diff --git a/panel/tests/test_server.py b/panel/tests/test_server.py index c4b8ff9b25..4e93ebc793 100644 --- a/panel/tests/test_server.py +++ b/panel/tests/test_server.py @@ -47,7 +47,7 @@ def test_server_static_dirs(): loop = IOLoop() server = StoppableThread( target=html._get_server, io_loop=loop, - args=(5008, None, loop, False, True, None, False, None), + args=(5008, None, None, loop, False, True, None, False, None), kwargs=dict(static_dirs={'tests': os.path.dirname(__file__)})) server.start() diff --git a/panel/viewable.py b/panel/viewable.py index 01c64d8fca..5fedf04f47 100644 --- a/panel/viewable.py +++ b/panel/viewable.py @@ -228,11 +228,11 @@ def _modify_doc(self, server_id, title, doc, location): state._servers[server_id][2].append(doc) return self.server_doc(doc, title, location) - def _get_server(self, port=0, websocket_origin=None, loop=None, + def _get_server(self, port=0, address=None, websocket_origin=None, loop=None, show=False, start=False, title=None, verbose=False, location=True, **kwargs): - return get_server(self, port, websocket_origin, loop, show, - start, title, verbose, **kwargs) + return get_server(self, port, address, websocket_origin, loop, + show, start, title, verbose, **kwargs) def _on_msg(self, ref, manager, msg): """ @@ -301,15 +301,19 @@ def servable(self, title=None, location=True): self.server_doc(title=title, location=True) return self - def show(self, title=None, port=0, websocket_origin=None, threaded=False, - verbose=True, open=True, location=True, **kwargs): + def show(self, title=None, port=0, address=None, websocket_origin=None, + threaded=False, verbose=True, open=True, location=True, **kwargs): """ Starts a Bokeh server and displays the Viewable in a new tab. Arguments --------- + title : str + A string title to give the Document (if served as an app) port: int (optional, default=0) Allows specifying a specific port + address : str + The address the server should listen on for HTTP requests. websocket_origin: str or list(str) (optional) A list of hosts that can connect to the websocket. This is typically required when embedding a server app in @@ -318,8 +322,6 @@ def show(self, title=None, port=0, websocket_origin=None, threaded=False, threaded: boolean (optional, default=False) Whether to launch the Server on a separate thread, allowing interactive use. - title : str - A string title to give the Document (if served as an app) verbose: boolean (optional, default=True) Whether to print the address and port open : boolean (optional, default=True) @@ -339,12 +341,13 @@ def show(self, title=None, port=0, websocket_origin=None, threaded=False, loop = IOLoop() server = StoppableThread( target=self._get_server, io_loop=loop, - args=(port, websocket_origin, loop, open, True, title, verbose, location), + args=(port, address, websocket_origin, loop, open, + True, title, verbose, location), kwargs=kwargs) server.start() else: server = self._get_server( - port, websocket_origin, show=open, start=True, + port, address, websocket_origin, show=open, start=True, title=title, verbose=verbose, location=location, **kwargs ) return server