B
    @\C                 @   s  d Z ddlmZmZmZmZ ddlZeeZ	ddl
Z
ddlZddlZddlZddlmZ ddlmZ ddlmZ ddlmZ dd	lmZmZmZmZ dd
lmZ ddlmZ ddlm Z m!Z! ddlm"Z"m#Z# dZ$G dd de%Z&G dd de&Z'G dd deZ(dS )a   Provide basic Bokeh server objects that use a Tornado ``HTTPServer`` and
``BokeTornado`` Tornado Application to service Bokeh Server Applications.
There are two public classes in this module:

:class:`~bokeh.server.server.BaseServer`
    This is a lightweight class to explicitly coordinate the components needed
    to run a Bokeh server (A :class:`~bokeh.server.tornado.BokehTornado`
    instance, and Tornado ``HTTPServer`` and a Tornado ``IOLoop``)

:class:`~bokeh.server.server.Server`
    This higher-level convenience class only needs to be configured with Bokeh
    :class:`~bokeh.application.application.Application` instances, and will
    automatically create and coordinate the lower level Tornado components.

    )absolute_importdivisionprint_functionunicode_literalsN)
HTTPServer)IOLoop   )__version__)Application)BoolIntListString)DEFAULT_SERVER_PORT)Options   )bind_socketscreate_hosts_whitelist)BokehTornado(DEFAULT_WEBSOCKET_MAX_MESSAGE_SIZE_BYTES)
BaseServerServerc               @   sv   e Zd ZdZdd Zedd Zdd Zdd	d
Zdd Z	dd Z
dd ZdddZdddZdZdd Zdd ZdS )r   a4   Explicitly coordinate the level Tornado components required to run a
    Bokeh server:

    * A Tornado ``IOLoop`` to run the Bokeh server machinery.

    * a ``BokehTornado`` Tornado application that defines the Bokeh server
      machinery.

    * a Tornado ``HTTPServer`` to direct HTTP requests

    All three of these components must be passed to ``BaseServer``, which will
    initialize the ``BokehTornado`` instance on the ``io_loop``. The
    ``http_server`` must have been previously created and initialized with the
    ``BokehTornado`` instance.

    c             C   s.   d| _ d| _|| _|| _|| _| j| dS )a7   Create a ``BaseServer`` instance.

        Args:
            io_loop (IOLoop) :
                A Tornado ``IOLoop`` to run the Bokeh Tornado application on.

            tornado_app (BokehTornado) :
                An instance of the Bokeh Tornado application that generates
                Bokeh Documents and Sessions.

            http_server (HTTPServer) :
                A Tornado ``HTTPServer`` to service HTTP requests for Bokeh
                applications. Should have already be configured with the
                ``tornado_app`` when created.

        FN)_started_stopped_http_loop_tornadoZ
initialize)selfio_looptornado_apphttp_server r!   2lib/python3.7/site-packages/bokeh/server/server.py__init__V   s    zBaseServer.__init__c             C   s   | j S )zG The Tornado ``IOLoop`` that this Bokeh Server is running on.

        )r   )r   r!   r!   r"   r   q   s    zBaseServer.io_loopc             C   s"   | j rtdd| _ | j  dS )a   Install the Bokeh Server and its background tasks on a Tornado
        ``IOLoop``.

        This method does *not* block and does *not* affect the state of the
        Tornado ``IOLoop``  You must start and stop the loop yourself, i.e.
        this method is typically useful when you are already explicitly
        managing an ``IOLoop`` yourself.

        To start a Bokeh server and immediately "run forever" in a blocking
        manner, see :func:`~bokeh.server.server.BaseServer.run_until_shutdown`.

        zAlready startedTN)r   AssertionErrorr   start)r   r!   r!   r"   r%   x   s    zBaseServer.startTc             C   s.   | j rtdd| _ | j| | j  dS )aK   Stop the Bokeh Server.

        This stops and removes all Bokeh Server ``IOLoop`` callbacks, as well
        as stops the ``HTTPServer`` that this instance was configured with.

        Args:
            fast (bool):
                Whether to wait for orderly cleanup (default: True)

        Returns:
            None

        zAlready stoppedTN)r   r$   r   stopr   )r   waitr!   r!   r"   r&      s    zBaseServer.stopc             C   s   | j   | j   dS )z Stop listening on ports. The server will no longer be usable after
        calling this function.

        Returns:
            None

        N)r   Zclose_all_connectionsr&   )r   r!   r!   r"   unlisten   s    
zBaseServer.unlistenc             C   sb   | j s|   t| j ttj| j y| j  W n t	k
rT   t
d Y nX |   dS )a   Run the Bokeh Server until shutdown is requested by the user,
        either via a Keyboard interrupt (Ctrl-C) or SIGTERM.

        Calling this method will start the Tornado ``IOLoop`` and block
        all execution in the calling process.

        Returns:
            None

        z
Interrupted, shutting downN)r   r%   atexitregister_atexitsignalSIGTERM_sigtermr   KeyboardInterruptprintr&   )r   r!   r!   r"   run_until_shutdown   s    zBaseServer.run_until_shutdownc             C   s   | j ||S )ak   Get an active a session by name application path and session ID.

        Args:
            app_path (str) :
                The configured application path for the application to return
                a session for.

            session_id (str) :
                The session ID of the session to retrieve.

        Returns:
            ServerSession

        )r   get_session)r   app_pathZ
session_idr!   r!   r"   r2      s    zBaseServer.get_sessionNc             C   s>   |dk	r| j |S g }x | j jD ]}|| j |7 }q"W |S )ai   Gets all currently active sessions for applications.

        Args:
            app_path (str, optional) :
                The configured application path for the application to return
                sessions for. If None, return active sessions for all
                applications. (default: None)

        Returns:
            list[ServerSession]

        N)r   get_sessionsZ	app_paths)r   r3   Zall_sessionspathr!   r!   r"   r4      s    zBaseServer.get_sessionstabc             C   sb   | dstdd}| jdk	r0| jdkr0| j}d|| j| j|f }ddlm} ||||d	 dS )
a   Opens an app in a browser window or tab.

        This method is useful for testing or running Bokeh server applications
        on a local machine but should not call when running Bokeh server for
        an actual deployment.

        Args:
            app_path (str) : the app path to open
                The part of the URL after the hostname:port, with leading slash.

            browser (str, optional) : browser to show with (default: None)
                For systems that support it, the **browser** argument allows
                specifying which browser to display in, e.g. "safari", "firefox",
                "opera", "windows-default" (see the ``webbrowser`` module
                documentation in the standard lib for more details).

            new (str, optional) : window or tab (default: "tab")
                If ``new`` is 'tab', then opens a new tab.
                If ``new`` is 'window', then opens a new window.

        Returns:
            None

        /zapp_path must start with a /Z	localhostN zhttp://%s:%d%s%sr   )view)browsernew)
startswith
ValueErroraddressportprefixZbokeh.util.browserr9   )r   r3   r:   r;   Zaddress_stringZurlr9   r!   r!   r"   show   s    
zBaseServer.showFc             C   s0   | j r
d S d| _ td | js,| jdd d S )NTzShutdown: cleaning upF)r'   )_atexit_ranlogdebugr   r&   )r   r!   r!   r"   r+     s    
zBaseServer._atexitc             C   s"   t d|f  | j| jj d S )Nz!Received signal %d, shutting down)r0   r   Zadd_callback_from_signalr&   )r   Zsignumframer!   r!   r"   r.     s    zBaseServer._sigterm)T)N)Nr6   )__name__
__module____qualname____doc__r#   propertyr   r%   r&   r(   r1   r2   r4   rA   rB   r+   r.   r!   r!   r!   r"   r   D   s   


%	r   c                   sF   e Zd ZdZd fdd	Zedd Zedd Zed	d
 Z  Z	S )r   a   A high level convenience class to run a Bokeh server.

    This class can automatically coordinate the three the base level
    components required to run a Bokeh server:

    * A Tornado ``IOLoop`` to run the Bokeh server machinery.

    * a ``BokehTornado`` Tornado application that defines the Bokeh server
      machinery.

    * a Tornado ``HTTPServer`` to direct HTTP requests

    This high level ``Server`` class has some limitations. In particular, it is
    not possible to set an explicit ``io_loop`` and ``num_procs`` other than 1
    at the same time. To do that, it is necessary to use ``BaseServer`` and
    coordinate the three components above explicitly.

    Nc                s  t dttjf  ddlm} ddlm  t	|r@t
||}t|t
rRd|i}x\t| D ]L\}}t	|rt
||||< t fdd|| jD r`||    q`W t|}|j| _|j| _|j| _|jdkrtd	d | D std
|jdkr|dk	rtd|jdkr6tjdkr6td|dkrDi }|d|j t | j| j\}	| _t!|j"| j}
yBt#|f|
| j|j$d|}t%|f|}|&|j |'|	 W n0 t(k
r   x|	D ]}|)  qW  Y nX |dkrt*+ }t,t-| .||| dS )a   Create a ``Server`` instance.

        Args:
            applications (dict[str, Application] or Application or callable) :
                A mapping from URL paths to Application instances, or a single
                Application to put at the root URL.

                The Application is a factory for Documents, with a new Document
                initialized for each Session. Each application is identified
                by a path that corresponds to a URL, like "/" or "/myapp"

                If a single Application is provided, it is mapped to the URL
                path "/" automatically.

                As a convenience, a callable may also be provided, in which
                an Application will be created for it using
                ``FunctionHandler``.

            io_loop (IOLoop, optional) :
                An explicit Tornado ``IOLoop`` to run Bokeh Server code on. If
                None, ``IOLoop.current()`` will be used (default: None)

            http_server_kwargs (dict, optional) :
                Extra arguments passed to ``tornado.httpserver.HTTPServer``.

                E.g. ``max_buffer_size`` to specify the maximum upload size.
                More details can be found at:

                http://www.tornadoweb.org/en/stable/httpserver.html#http-server

                If None, no extra arguments are passed (default: None)

        Additionally, the following options may be passed to configure the
        operation of ``Server``:

        .. bokeh-options:: _ServerOpts
            :module: bokeh.server.server

        Any remaining keyword arguments will be passed as-is to
        ``BokehTornado``.

        z8Starting Bokeh server version %s (running on Tornado %s)r   )FunctionHandler)DocumentLifecycleHandlerr7   c             3   s   | ]}t |  V  qd S )N)
isinstance).0Zhandler)rL   r!   r"   	<genexpr>g  s   z"Server.__init__.<locals>.<genexpr>r   c             s   s   | ]}|j V  qd S )N)Zsafe_to_fork)rN   Zappr!   r!   r"   rO   q  s    ztUser application code has run before attempting to start multiple processes. This is considered an unsafe operation.NzSetting both num_procs and io_loop in Server is incompatible. Use BaseServer to coordinate an explicit IOLoop and multi-process HTTPServerZwin32z&num_procs > 1 not supported on WindowsZxheaders)extra_websocket_originsr@   Z websocket_max_message_size_bytes)/rC   infor	   tornadoversionZ#bokeh.application.handlers.functionrK   Z-bokeh.application.handlers.document_lifecyclerL   callabler
   rM   listitemsallZ	_handlersadd_ServerOptsr?   _portr>   _addressr@   _prefix	num_procsvaluesr$   RuntimeErrorsysplatform
setdefaultuse_xheadersr   r   allow_websocket_originr   websocket_max_message_sizer   r%   Zadd_sockets	Exceptioncloser   Zcurrentsuperr   r#   )r   Zapplicationsr   Zhttp_server_kwargskwargsrK   kvZoptsZsocketsrP   r   r    s)	__class__)rL   r"   r#   .  s\    +




zServer.__init__c             C   s   | j S )zG The configured URL prefix to use for all Bokeh server paths.

        )r\   )r   r!   r!   r"   r@     s    zServer.prefixc             C   s   | j S )z[ The configured port number that the server listens on for HTTP
        requests.

        )rZ   )r   r!   r!   r"   r?     s    zServer.portc             C   s   | j S )zW The configured address that the server listens on for HTTP
        requests.

        )r[   )r   r!   r!   r"   r>     s    zServer.address)NN)
rF   rG   rH   rI   r#   rJ   r@   r?   r>   __classcell__r!   r!   )rm   r"   r     s
   mr   c               @   sb   e Zd ZedddZedddZeeddZedddZ	e
edd	dZed
ddZeeddZdS )rY   r   a  
    The number of worker processes to start for the HTTP server. If an explicit
    ``io_loop`` is also configured, then ``num_procs=1`` is the only compatible
    value. Use ``BaseServer`` to coordinate an explicit ``IOLoop`` with a
    multi-process HTTP server.

    A value of 0 will auto detect number of cores.

    Note that due to limitations inherent in Tornado, Windows does not support
    ``num_procs`` values greater than one! In this case consider running
    multiple Bokeh server instances behind a load balancer.
    )defaulthelpNzD
    The address the server should listen on for HTTP requests.
    zH
    The port number the server should listen on for HTTP requests.
    r8   z9
    A URL prefix to use for all Bokeh server paths.
    z
    A list of hosts that can connect to the websocket.

    This is typically required when embedding a Bokeh server app in an external
    web site using :func:`~bokeh.embed.server_document` or similar.

    If None, "localhost" is used.
    Fz
    Whether to have the Bokeh server override the remote IP and URI scheme
    and protocol for all requests with ``X-Real-Ip``, ``X-Forwarded-For``,
    ``X-Scheme``, ``X-Forwarded-Proto`` headers (if they are provided).
    zx
    Set the Tornado ``websocket_max_message_size`` value.

    NOTE: This setting has effect ONLY for Tornado>=4.5
    )rF   rG   rH   r   r]   r   r>   r   r?   r@   r   rd   r   rc   r   re   r!   r!   r!   r"   rY     s   rY   ))rI   Z
__future__r   r   r   r   ZloggingZ	getLoggerrF   rC   r)   r,   r`   rR   Ztornado.httpserverr   Ztornado.ioloopr   r8   r	   Zapplicationr
   Zcore.propertiesr   r   r   r   Z	resourcesr   Zutil.optionsr   utilr   r   r   r   __all__objectr   r   rY   r!   r!   r!   r"   <module>   s,   
 W 