Plain is headed towards 1.0! Subscribe for development updates →

 1import os
 2import tomllib
 3from pathlib import Path
 4from typing import Any
 5
 6from plain.runtime import APP_PATH, PLAIN_TEMP_PATH
 7
 8from .process import ProcessManager
 9from .utils import has_pyproject_toml
10
11
12class ServicesProcess(ProcessManager):
13    pidfile = PLAIN_TEMP_PATH / "dev" / "services.pid"
14    log_dir = PLAIN_TEMP_PATH / "dev" / "logs" / "services"
15
16    @staticmethod
17    def get_services(root: str | Path) -> dict[str, Any]:
18        if not has_pyproject_toml(root):
19            return {}
20
21        with open(Path(root, "pyproject.toml"), "rb") as f:
22            pyproject = tomllib.load(f)
23
24        return (
25            pyproject.get("tool", {})
26            .get("plain", {})
27            .get("dev", {})
28            .get("services", {})
29        )
30
31    def run(self) -> None:
32        self.write_pidfile()
33        self.prepare_log()
34        self.init_poncho(print)
35
36        try:
37            services = self.get_services(APP_PATH.parent)
38            for name, data in services.items():
39                env = {
40                    **os.environ,
41                    "PYTHONUNBUFFERED": "true",
42                    **data.get("env", {}),
43                }
44                self.poncho.add_process(name, data["cmd"], env=env)
45
46            self.poncho.loop()
47        finally:
48            self.rm_pidfile()
49            self.close()