StrictDoc Documentation
strictdoc/server/server.py
Source file coverage
Path:
strictdoc/server/server.py
Lines:
79
Non-empty lines:
69
Non-empty lines covered with requirements:
69 / 69 (100.0%)
Functions:
2
Functions covered by requirements:
2 / 2 (100.0%)
1
"""
2
@relation(SDOC-SRS-126, scope=file)
3
"""
4
 
5
import os
6
import tempfile
7
from contextlib import ExitStack
8
from pathlib import Path
9
from typing import List, Tuple
10
 
11
import uvicorn
12
 
13
from strictdoc.commands.server_config import ServerCommandConfig
14
from strictdoc.core.project_config import ProjectConfig
15
from strictdoc.helpers.pickle import pickle_dump
16
from strictdoc.server.config import SDocServerEnvVariable
17
from strictdoc.server.reload_config import UvicornReloadConfig
18
 
19
 
20
def run_strictdoc_server(
21
    *, server_config: ServerCommandConfig, project_config: ProjectConfig
22
) -> None:
23
    with ExitStack() as stack:
24
        reload_config = UvicornReloadConfig.create(
25
            project_config, server_config
26
        )
27
 
28
        # The server's uvicorn.run does not support passing arguments to the
29
        # main function (strictdoc_production_app). Passing the pickled config
30
        # through the environmental variables interface.
31
        tmp_config_file = stack.enter_context(tempfile.NamedTemporaryFile())
32
        config_dump = pickle_dump(project_config)
33
        tmp_config_file.write(config_dump)
34
        tmp_config_file.flush()
35
 
36
        os.environ[SDocServerEnvVariable.PATH_TO_CONFIG] = tmp_config_file.name
37
 
38
        # The uvicorn config code uses this function to additionally resolve
39
        # the reload includes and excludes. Unfortunately, it does not work
40
        # correctly with the expanded globs that are created by StrictDoc.
41
        # Not doing any resolutions seems to work fine with StrictDoc, so using
42
        # a 'do nothing' stub and an assert below to make sure that this function
43
        # is not removed by uvicorn.
44
        def dont_resolve_reload_patterns(
45
            patterns_list: List[str], directories_list: List[str]
46
        ) -> Tuple[List[str], List[Path]]:  # pragma: no cover
47
            return patterns_list, list(  # pragma: no cover
48
                map(Path, directories_list)
49
            )
50
 
51
        assert hasattr(uvicorn.config, "resolve_reload_patterns"), (
52
            "REGRESSION: The function 'resolve_reload_patterns' is not defined "
53
            "in uvicorn.config. Please report this to StrictDoc developers at "
54
            "https://github.com/strictdoc-project/strictdoc/issues."
55
        )
56
        uvicorn.config.resolve_reload_patterns = dont_resolve_reload_patterns
57
 
58
        uvicorn.run(
59
            "strictdoc.server.app:strictdoc_production_app",
60
            app_dir=".",
61
            factory=True,
62
            host=server_config.host
63
            if server_config.host is not None
64
            else project_config.server_host,
65
            log_level="info",
66
            # "server" command port overrides the strictdoc.toml option for now.
67
            # Eventually, I am considering to remove the CLI option for the
68
            # port, to simplify the maintenance of two configs: the config file
69
            # and the "export" command's interface.
70
            port=(
71
                server_config.port
72
                if server_config.port is not None
73
                else project_config.server_port
74
            ),
75
            reload=reload_config.reload,
76
            reload_dirs=reload_config.reload_dirs,
77
            reload_includes=reload_config.reload_includes,
78
            reload_excludes=reload_config.reload_excludes,
79
        )