Source code for wdom.server
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Web server control functions."""
import os
import json
import logging
import asyncio
from typing import Any
from tornado import autoreload
from wdom.util import STATIC_DIR, install_asyncio
from wdom.options import config
from wdom.server.base import exclude_patterns, open_browser, watch_dir
from wdom.server import _tornado as module
__all__ = (
'add_static_path',
'exclude_patterns',
'get_app',
'start',
'start_server',
'stop_server',
)
logger = logging.getLogger(__name__)
_server = None
server_config = module.server_config
_msg_queue = []
def is_connected() -> bool:
"""Check if the current server has a client connection."""
return module.is_connected()
def push_message(msg: dict) -> None:
"""Push message on the message queue."""
_msg_queue.append(msg)
def send_message() -> None:
"""Send message via WS to all client connections."""
if not _msg_queue:
return
msg = json.dumps(_msg_queue)
_msg_queue.clear()
for conn in module.connections:
conn.write_message(msg)
[docs]def add_static_path(prefix: str, path: str, no_watch: bool = False) -> None:
"""Add directory to serve static files.
First argument ``prefix`` is a URL prefix for the ``path``. ``path`` must
be a directory. If ``no_watch`` is True, any change of the files in the
path do not trigger restart if ``--autoreload`` is enabled.
"""
app = get_app()
app.add_static_path(prefix, path)
if not no_watch:
watch_dir(path)
[docs]def get_app() -> module.Application:
"""Get root web application object."""
return module.get_app()
async def _message_loop() -> None:
while True:
send_message()
await asyncio.sleep(config.message_wait)
[docs]def start_server(browser: str = None, address: str = None,
check_time: int = 500, **kwargs: Any
) -> module.HTTPServer:
"""Start web server.
Use wrapper function :func:`start` instead.
"""
# Add application's static files directory
from wdom.document import get_document
add_static_path('_static', STATIC_DIR)
doc = get_document()
if os.path.exists(doc.tempdir):
add_static_path('tmp', doc.tempdir, no_watch=True)
if doc._autoreload or config.autoreload or config.debug:
install_asyncio()
autoreload.start(check_time=check_time)
global _server
_server = module.start_server(**kwargs)
logger.info('Start server on {0}:{1:d}'.format(
server_config['address'], server_config['port']))
# start messaging loop
asyncio.ensure_future(_message_loop())
if config.open_browser:
open_browser('http://{}:{}/'.format(server_config['address'],
server_config['port']),
browser or config.browser)
return _server
[docs]def stop_server(server: module.HTTPServer = None) -> None:
"""Terminate web server."""
module.stop_server(server or _server)
[docs]def start(**kwargs: Any) -> None:
"""Start web server.
Run until ``Ctrl-c`` pressed, or if auto-shutdown is enabled, until when
all browser windows are closed.
"""
start_server(**kwargs)
try:
asyncio.get_event_loop().run_forever()
except KeyboardInterrupt:
stop_server()