U
    /eL                     @  sn  d Z ddl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mZmZmZm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 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, er8d	dl-m.Z. d	dl/m0Z0 d	dl1m2Z2 d	dl3m4Z4 ddl5m6Z6 dZ7G dd dZ8G dd de8Z9G 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.

    )annotationsN)	FrameType)TYPE_CHECKINGAnyDictListMapping)version)
HTTPServer)IOLoop   )__version__)
properties)BoolIntNullableString)DEFAULT_SERVER_PORT)Options   )(DEFAULT_WEBSOCKET_MAX_MESSAGE_SIZE_BYTESBokehTornado)bind_socketscreate_hosts_allowlist)Application)	ModifyDoc)ID)BrowserTarget)ServerSession)
BaseServerServerc                   @  s  e Zd ZdZdddddddZedd	d
dZdd	ddZd9dddddZdd	ddZ	dd	ddZ
ddddddZd:ddd d!d"Zd;ddd$dd%d&d'Zd(Zdd	d)d*Zd+d,dd-d.d/Zed0d	d1d2Zedd	d3d4Zedd	d5d6Zedd	d7d8ZdS )<r   aK   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.

    .. autoclasstoc::

    r   r   r
   None)io_looptornado_apphttp_serverreturnc                 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)selfr"   r#   r$    r,   7/tmp/pip-unpacked-wheel-f5fndrjf/bokeh/server/server.py__init__l   s    zBaseServer.__init__r%   c                 C  s   | j S )zG The Tornado ``IOLoop`` that this Bokeh Server is running on.

        )r)   r+   r,   r,   r-   r"      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*   startr0   r,   r,   r-   r2      s    zBaseServer.startTbool)waitr%   c                 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'   r1   r*   stopr(   )r+   r4   r,   r,   r-   r5      s    zBaseServer.stopc                 C  s   | j   | j| j j dS )z Stop listening on ports. The server will no longer be usable after
        calling this function.

        .. note::
            This function is mostly useful for tests

        Returns:
            None

        N)r(   r5   r"   Zadd_callbackZclose_all_connectionsr0   r,   r,   r-   unlisten   s    
zBaseServer.unlistenc                 C  sb   | j s|   t| j ttj| j z| 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&   r2   atexitregister_atexitsignalSIGTERM_sigtermr)   KeyboardInterruptprintr5   r0   r,   r,   r-   run_until_shutdown   s    zBaseServer.run_until_shutdownstrr   r   )app_path
session_idr%   c                 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+   rA   rB   r,   r,   r-   rC      s    zBaseServer.get_sessionN
str | NonezList[ServerSession])rA   r%   c                 C  s:   |dk	r| j |S g }| j jD ]}|| j |7 }q |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+   rA   Zall_sessionspathr,   r,   r-   rE      s    zBaseServer.get_sessionstabr   )rA   browsernewr%   c                 C  sj   | dstdd}| jdk	r0| jdkr0| j}d| d| j | j | }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 :doc:`webbrowser <python:library/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 /	localhostN zhttp://:r   )view)rH   rI   )
startswith
ValueErroraddressportprefixZbokeh.util.browserrN   )r+   rA   rH   rI   Zaddress_stringurlrN   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)r4   )_atexit_ranlogdebugr'   r5   r0   r,   r,   r-   r9   !  s    
zBaseServer._atexitzsignal.Signalsr   )signumframer%   c                 C  s$   t d| d | j| jj d S )NzReceived signal z, shutting down)r>   r)   Zadd_callback_from_signalr5   )r+   rY   rZ   r,   r,   r-   r<   *  s    zBaseServer._sigtermintc                 C  s&   t dd | jj D }| d S )zQ The configured port number that the server listens on for HTTP requests
        c                 s  s$   | ]}|j tjtjfkr|V  qd S NfamilysocketAF_INETAF_INET6.0sockr,   r,   r-   	<genexpr>3  s   z"BaseServer.port.<locals>.<genexpr>r   nextr(   Z_socketsvaluesgetsocknamer+   rd   r,   r,   r-   rR   /  s    
zBaseServer.portc                 C  s&   t dd | jj D }| d S )zM The configured address that the server listens on for HTTP requests
        c                 s  s$   | ]}|j tjtjfkr|V  qd S r\   r]   rb   r,   r,   r-   re   =  s   z%BaseServer.address.<locals>.<genexpr>r   rf   rj   r,   r,   r-   rQ   9  s    
zBaseServer.addressc                 C  s   | j jS )z> The configured URL prefix to use for all Bokeh server paths. )r*   rS   r0   r,   r,   r-   rS   C  s    zBaseServer.prefixc                 C  s   | j jS )z5 A path to a Jinja2 template to use for index at "/" )r*   indexr0   r,   r,   r-   rk   H  s    zBaseServer.index)T)N)NrG   )__name__
__module____qualname____doc__r.   propertyr"   r2   r5   r6   r?   rC   rE   rU   rV   r9   r<   rR   rQ   rS   rk   r,   r,   r,   r-   r   X   s,   %			r   c                      sT   e Zd ZdZddddddd fd	d
ZeddddZedd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.

    .. autoclasstoc::

    Nz?Mapping[str, Application | ModifyDoc] | Application | ModifyDoczIOLoop | NonezDict[str, Any] | Noner   r!   )applicationsr"   http_server_kwargskwargsr%   c                   s  t dttf  t|}|jdkr4|dk	r4td|jdkrPtjdkrPtd|dkr\i }|	d|j
 |jrt d d	dl}||jj}|j|j|j|jd
 ||d< t|j|j\}| _|j| _t|j| j}	ztt|f|	|j|j|jd|}
|jdkr(tdd |
j  D s(t!dt"|
f|}|#|j |$| W n, t%k
rx   |D ]}|&  qb Y nX |dkrt'( }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   NzSetting both num_procs and io_loop in Server is incompatible. Use BaseServer to coordinate an explicit IOLoop and multi-process HTTPServerwin32z&num_procs > 1 not supported on WindowsZxheaderszConfiguring for SSL terminationr   )certfilekeyfilepasswordZssl_options)extra_websocket_originsrS   rk   Z websocket_max_message_size_bytesc                 s  s   | ]}|j jV  qd S r\   )ZapplicationZsafe_to_fork)rc   Zapp_contextr,   r,   r-   re     s     z"Server.__init__.<locals>.<genexpr>ztUser application code has run before attempting to start multiple processes. This is considered an unsafe operation.)+rW   infor   tornado_version_ServerOpts	num_procsRuntimeErrorsysplatform
setdefaultuse_xheadersssl_certfilesslcreate_default_contextPurposeCLIENT_AUTHload_cert_chainssl_keyfilessl_passwordr   rQ   rR   _port_addressr   allow_websocket_originr   rS   rk   websocket_max_message_sizeallrq   rh   r1   r
   r2   Zadd_sockets	Exceptioncloser   currentsuperr.   )r+   rq   r"   rr   rs   optsr   contextZsocketsrx   r#   r$   s	__class__r,   r-   r.   g  sV    ,

zServer.__init__r[   r/   c                 C  s   | j S )z[ The configured port number that the server listens on for HTTP
        requests.

        )r   r0   r,   r,   r-   rR     s    zServer.portrD   c                 C  s   | j S )zW The configured address that the server listens on for HTTP
        requests.

        )r   r0   r,   r,   r-   rQ     s    zServer.address)NN)	rl   rm   rn   ro   r.   rp   rR   rQ   __classcell__r,   r,   r   r-   r    Q  s      dr    c                   @  s   e Zd ZU edddZded< eeddZded	< ee	d
dZ
ded< edddZded< eeddZded< eeeddZded< edddZded< eeddZded< eeddZded< eeddZded< eeddZded < d!S )"r{   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helpr[   r|   zD
    The address the server should listen on for HTTP requests.
    )r   rD   rQ   zH
    The port number the server should listen on for HTTP requests.
    rR   rL   z9
    A URL prefix to use for all Bokeh server paths.
    r@   rS   z>
    A path to a Jinja2 template to use for the index "/"
    rk   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.
    zList[str] | Noner   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).
    r3   r   z=
    The path to a certificate file for SSL termination.
    r   z=
    The path to a private key file for SSL termination.
    r   z>
    A password to decrypt the SSL keyfile, if necessary.
    r   z?
    Set the Tornado ``websocket_max_message_size`` value.
    r   N)rl   rm   rn   r   r|   __annotations__r   r   rQ   r   rR   rS   rk   pr   r   r   r   r   r   r   r   r   r,   r,   r,   r-   r{     s   
	r{   );ro   
__future__r   logging	getLoggerrl   rW   r7   r:   r_   r~   typesr   typingr   r   r   r   r   Ztornador	   rz   Ztornado.httpserverr
   Ztornado.ioloopr   rL   r   corer   r   Zcore.propertiesr   r   r   r   	resourcesr   Zutil.optionsr   r   r   utilr   r   Zapplication.applicationr   Zapplication.handlers.functionr   Z
core.typesr   Zutil.browserr   sessionr   __all__r   r    r{   r,   r,   r,   r-   <module>   s>   
		 z 