stormvogel.communication_server =============================== .. py:module:: stormvogel.communication_server .. autoapi-nested-parse:: Communication from Javascript/HTML to IPython/Jupyter lab using a local server and requests. Initialization by user is not recommended. It should happen automatically when creating a network.Network. Remember that you need AT LEAST ONE AVAILABLE (and sometimes also forwarded) PORT BETWEEN min_port AND max_port IN ORDER FOR IT TO WORK. Attributes ---------- .. autoapisummary:: stormvogel.communication_server.enable_server stormvogel.communication_server.localhost_address stormvogel.communication_server.min_port stormvogel.communication_server.max_port stormvogel.communication_server.port_range stormvogel.communication_server.server_port stormvogel.communication_server.events stormvogel.communication_server.server_running stormvogel.communication_server.server Classes ------- .. autoapisummary:: stormvogel.communication_server.CommunicationServer Functions --------- .. autoapisummary:: stormvogel.communication_server.random_word stormvogel.communication_server.__warn_request stormvogel.communication_server.__warn_server stormvogel.communication_server.__warn_no_free_port stormvogel.communication_server.is_port_free stormvogel.communication_server.find_free_port stormvogel.communication_server.initialize_server Module Contents --------------- .. py:function:: random_word(k: int) -> str Generate a random word of length *k*. :param k: Length of the random word. :returns: A random string of ASCII letters. .. py:data:: enable_server :type: bool :value: True Disable if you don't want to use an internal communication server. Some features might break. .. py:data:: localhost_address :type: str :value: '127.0.0.1' .. py:data:: min_port :value: 8889 .. py:data:: max_port :value: 8905 .. py:data:: port_range The range of ports that stromvogel uses. They should all be forwarded if you're on an http tunnel. .. py:data:: server_port :type: int :value: 8888 Global variable storing the port that is being used by this process. Changes when initialize_server is called. .. py:data:: events :type: dict[str, Callable[[str], Any]] Dictionary that stores currently active events, along with their function, hashed by randomly generated ids. .. py:data:: server_running :type: bool :value: False Global variable that is set to true when the server is running. .. py:data:: server :type: CommunicationServer | None :value: None Global variable holding the server used for this notebook. None if not initialized. .. py:class:: CommunicationServer(server_port: int = 8080) Run a web server in the background to receive Javascript communications. The server maintains a list of events, each with a unique id. The Javascript code sends a POST request to the server with the id and the data. The server then looks up the event with that id and calls the function associated with it. .. py:attribute:: server_port :type: int :value: 8080 .. py:attribute:: web_server :type: http.server.HTTPServer .. py:method:: __run_server() Run the server on a background thread. Set the global variable ``server_running`` to ``True`` once started. This prevents making requests too early. .. py:method:: add_event(js: str, function: Callable[[str], Any]) -> str Add an event using some JavaScript code. Within the *js* code, use the special function ``FUNCTION(...)`` to call the Python *function*. Example:: js = "FUNCTION(37 + 42);" function = lambda data: print(data) The arithmetic is performed in Javascript, and the result is printed in Python. Note that the function is called with the result of the arithmetic as a string. :param js: JavaScript code containing a ``FUNCTION(...)`` call. :param function: Python callable invoked with the JavaScript result as a string. :returns: Event id which can be used to remove the event later. .. py:method:: remove_event(event_id: str) -> Callable[[str], Any] Remove the event associated with the given event id. :param event_id: The id of the event to remove. :returns: The callable that was associated with the event. .. py:method:: result(js: str, timeout_seconds: float = 2.0) -> str Execute some JavaScript and return the result. Use the special function ``RETURN(...)`` in *js* to send the result back. Example:: js = "RETURN(37 + 42);" The arithmetic is executed in Javascript, and ``"79"`` is returned as a string. :param js: JavaScript code containing a ``RETURN(...)`` call. :param timeout_seconds: Seconds to wait for a result before raising. :returns: The result from JavaScript as a string. :raises TimeoutError: If no result is received within *timeout_seconds*. .. py:function:: __warn_request() .. py:function:: __warn_server() .. py:function:: __warn_no_free_port() .. py:function:: is_port_free(port: int) -> bool Return ``True`` if the specified port is free on ``localhost_address``. :param port: Port number to check. :returns: ``True`` if the port is free, ``False`` otherwise. .. py:function:: find_free_port() -> int Find a free port in the configured port range. :returns: A free port number, or ``-1`` if none are available. .. py:function:: initialize_server(silent=True) -> CommunicationServer | None If server is None, then create a new server and store it in global variable server. Use the port stored in global variable server_port. If the server is already initialized, just return it. If the server has not been created yet, create one on the first free port in the configured range and store it in the global ``server`` variable. If already initialized, return the existing server. :returns: The server instance, or ``None`` if initialization failed or is disabled.