sysgraph 0.0.11__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sysgraph-0.0.11/LICENSE +21 -0
- sysgraph-0.0.11/MANIFEST.in +7 -0
- sysgraph-0.0.11/PKG-INFO +111 -0
- sysgraph-0.0.11/README.md +68 -0
- sysgraph-0.0.11/pyproject.toml +19 -0
- sysgraph-0.0.11/setup.cfg +4 -0
- sysgraph-0.0.11/setup.py +91 -0
- sysgraph-0.0.11/src/sysgraph/__init__.py +1 -0
- sysgraph-0.0.11/src/sysgraph/__main__.py +3 -0
- sysgraph-0.0.11/src/sysgraph/app.py +134 -0
- sysgraph-0.0.11/src/sysgraph/discovery.py +530 -0
- sysgraph-0.0.11/src/sysgraph/dist/assets/index-DFF8eDbX.js +735 -0
- sysgraph-0.0.11/src/sysgraph/dist/index.html +181 -0
- sysgraph-0.0.11/src/sysgraph/graph.py +104 -0
- sysgraph-0.0.11/src/sysgraph/main.py +47 -0
- sysgraph-0.0.11/src/sysgraph/model.py +114 -0
- sysgraph-0.0.11/src/sysgraph.egg-info/PKG-INFO +111 -0
- sysgraph-0.0.11/src/sysgraph.egg-info/SOURCES.txt +21 -0
- sysgraph-0.0.11/src/sysgraph.egg-info/dependency_links.txt +1 -0
- sysgraph-0.0.11/src/sysgraph.egg-info/entry_points.txt +2 -0
- sysgraph-0.0.11/src/sysgraph.egg-info/not-zip-safe +1 -0
- sysgraph-0.0.11/src/sysgraph.egg-info/requires.txt +4 -0
- sysgraph-0.0.11/src/sysgraph.egg-info/top_level.txt +1 -0
sysgraph-0.0.11/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Eugene Gubenkov
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
sysgraph-0.0.11/PKG-INFO
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sysgraph
|
|
3
|
+
Version: 0.0.11
|
|
4
|
+
Summary: Visualizer for processes and their interconnections
|
|
5
|
+
Home-page: https://github.com/gubenkoved/sysgraph
|
|
6
|
+
Author: Eugene Gubenkov
|
|
7
|
+
Author-email: gubenkoved@gmail.com
|
|
8
|
+
License: MIT
|
|
9
|
+
Project-URL: Source, https://github.com/gubenkoved/sysgraph
|
|
10
|
+
Project-URL: Issues, https://github.com/gubenkoved/sysgraph/issues
|
|
11
|
+
Keywords: process,visualization,graph,ipc,system,monitoring,linux,procfs
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
17
|
+
Classifier: Topic :: System :: Monitoring
|
|
18
|
+
Classifier: Topic :: System :: Systems Administration
|
|
19
|
+
Classifier: Environment :: Web Environment
|
|
20
|
+
Classifier: Framework :: FastAPI
|
|
21
|
+
Classifier: Intended Audience :: Developers
|
|
22
|
+
Classifier: Intended Audience :: System Administrators
|
|
23
|
+
Requires-Python: >=3.12
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: psutil
|
|
27
|
+
Requires-Dist: coloredlogs
|
|
28
|
+
Requires-Dist: fastapi>=0.95
|
|
29
|
+
Requires-Dist: uvicorn[standard]>=0.20
|
|
30
|
+
Dynamic: author
|
|
31
|
+
Dynamic: author-email
|
|
32
|
+
Dynamic: classifier
|
|
33
|
+
Dynamic: description
|
|
34
|
+
Dynamic: description-content-type
|
|
35
|
+
Dynamic: home-page
|
|
36
|
+
Dynamic: keywords
|
|
37
|
+
Dynamic: license
|
|
38
|
+
Dynamic: license-file
|
|
39
|
+
Dynamic: project-url
|
|
40
|
+
Dynamic: requires-dist
|
|
41
|
+
Dynamic: requires-python
|
|
42
|
+
Dynamic: summary
|
|
43
|
+
|
|
44
|
+
# sysgraph
|
|
45
|
+
|
|
46
|
+
Real-time process-graph visualizer that discovers running OS processes, their inter-process communication channels (pipes, Unix domain sockets, TCP/UDP network connections), and renders them as an interactive force-directed graph in the browser.
|
|
47
|
+
|
|
48
|
+

|
|
49
|
+

|
|
50
|
+
|
|
51
|
+
## Features
|
|
52
|
+
|
|
53
|
+
- **Process discovery** — enumerates all running OS processes and their parent-child relationships
|
|
54
|
+
- **IPC visualization** — discovers pipes, Unix domain sockets, and TCP/UDP connections between processes
|
|
55
|
+
- **Interactive graph** — force-directed graph rendered in the browser with zoom, pan, drag, and search
|
|
56
|
+
- **Real-time** — fetch the latest process graph on demand via the web UI
|
|
57
|
+
- **Fuzzy search** — find processes by name, PID, command line, or any property
|
|
58
|
+
- **Adjacency filtering** — right-click a node to show only its neighbors
|
|
59
|
+
- **Configurable** — tune d3 force parameters, colors, and filters via the settings panel
|
|
60
|
+
- **Export/Import** — save and load graph snapshots as JSON
|
|
61
|
+
|
|
62
|
+
## Requirements
|
|
63
|
+
|
|
64
|
+
- **Linux** (relies on `/proc` filesystem and the `ss` command)
|
|
65
|
+
- **Python ≥ 3.12**
|
|
66
|
+
- Root/sudo recommended for full visibility into all processes
|
|
67
|
+
|
|
68
|
+
## Installation
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
pip install sysgraph
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Usage
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# Start the web server (default: http://localhost:8000)
|
|
78
|
+
sysgraph
|
|
79
|
+
|
|
80
|
+
# Specify a custom port
|
|
81
|
+
sysgraph --port 9000
|
|
82
|
+
|
|
83
|
+
# Or run as a module
|
|
84
|
+
python -m sysgraph
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Open your browser to the displayed URL to see the interactive process graph.
|
|
88
|
+
|
|
89
|
+
For full visibility into all processes and their connections, run with elevated privileges:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
sudo sysgraph
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Docker
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
docker run --rm -it --pid=host --net=host gubenkoved/sysgraph
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
The `--pid=host` and `--net=host` flags allow the container to see host processes and network connections.
|
|
102
|
+
|
|
103
|
+
## How It Works
|
|
104
|
+
|
|
105
|
+
1. The **FastAPI backend** uses `psutil` and Linux-specific APIs (`/proc`, `ss`) to discover processes, pipes, Unix domain sockets, and network connections.
|
|
106
|
+
2. It builds a graph of processes (nodes) and their IPC channels (edges).
|
|
107
|
+
3. The **browser frontend** fetches the graph via `GET /api/graph` and renders it using [force-graph](https://github.com/vasturiano/force-graph) with d3 physics simulation.
|
|
108
|
+
|
|
109
|
+
## License
|
|
110
|
+
|
|
111
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# sysgraph
|
|
2
|
+
|
|
3
|
+
Real-time process-graph visualizer that discovers running OS processes, their inter-process communication channels (pipes, Unix domain sockets, TCP/UDP network connections), and renders them as an interactive force-directed graph in the browser.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **Process discovery** — enumerates all running OS processes and their parent-child relationships
|
|
11
|
+
- **IPC visualization** — discovers pipes, Unix domain sockets, and TCP/UDP connections between processes
|
|
12
|
+
- **Interactive graph** — force-directed graph rendered in the browser with zoom, pan, drag, and search
|
|
13
|
+
- **Real-time** — fetch the latest process graph on demand via the web UI
|
|
14
|
+
- **Fuzzy search** — find processes by name, PID, command line, or any property
|
|
15
|
+
- **Adjacency filtering** — right-click a node to show only its neighbors
|
|
16
|
+
- **Configurable** — tune d3 force parameters, colors, and filters via the settings panel
|
|
17
|
+
- **Export/Import** — save and load graph snapshots as JSON
|
|
18
|
+
|
|
19
|
+
## Requirements
|
|
20
|
+
|
|
21
|
+
- **Linux** (relies on `/proc` filesystem and the `ss` command)
|
|
22
|
+
- **Python ≥ 3.12**
|
|
23
|
+
- Root/sudo recommended for full visibility into all processes
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install sysgraph
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# Start the web server (default: http://localhost:8000)
|
|
35
|
+
sysgraph
|
|
36
|
+
|
|
37
|
+
# Specify a custom port
|
|
38
|
+
sysgraph --port 9000
|
|
39
|
+
|
|
40
|
+
# Or run as a module
|
|
41
|
+
python -m sysgraph
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Open your browser to the displayed URL to see the interactive process graph.
|
|
45
|
+
|
|
46
|
+
For full visibility into all processes and their connections, run with elevated privileges:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
sudo sysgraph
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Docker
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
docker run --rm -it --pid=host --net=host gubenkoved/sysgraph
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
The `--pid=host` and `--net=host` flags allow the container to see host processes and network connections.
|
|
59
|
+
|
|
60
|
+
## How It Works
|
|
61
|
+
|
|
62
|
+
1. The **FastAPI backend** uses `psutil` and Linux-specific APIs (`/proc`, `ss`) to discover processes, pipes, Unix domain sockets, and network connections.
|
|
63
|
+
2. It builds a graph of processes (nodes) and their IPC channels (edges).
|
|
64
|
+
3. The **browser frontend** fetches the graph via `GET /api/graph` and renders it using [force-graph](https://github.com/vasturiano/force-graph) with d3 physics simulation.
|
|
65
|
+
|
|
66
|
+
## License
|
|
67
|
+
|
|
68
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[tool.ruff]
|
|
6
|
+
line-length = 79
|
|
7
|
+
target-version = "py312"
|
|
8
|
+
# Tune ruff rules as needed. Ruff supports many checks and can also format (`ruff format`).
|
|
9
|
+
# See https://beta.ruff.rs/docs/configuration/ for config options.
|
|
10
|
+
exclude = [".venv", "build", "dist", "__pycache__"]
|
|
11
|
+
|
|
12
|
+
[tool.isort]
|
|
13
|
+
profile = "black"
|
|
14
|
+
multi_line_output = 3
|
|
15
|
+
include_trailing_comma = true
|
|
16
|
+
force_grid_wrap = 0
|
|
17
|
+
use_parentheses = true
|
|
18
|
+
ensure_newline_before_comments = true
|
|
19
|
+
line_length = 88
|
sysgraph-0.0.11/setup.py
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""A minimal, editable `setup.py` for the project.
|
|
3
|
+
|
|
4
|
+
This file uses a modern setuptools pattern with a `src/` layout.
|
|
5
|
+
Edit metadata (author, email, description, classifiers, dependencies) as needed.
|
|
6
|
+
"""
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
from setuptools import find_packages, setup
|
|
10
|
+
|
|
11
|
+
HERE = Path(__file__).parent
|
|
12
|
+
|
|
13
|
+
# Read long description from README if available
|
|
14
|
+
README = (HERE / "README.md").read_text(encoding="utf-8") if (HERE / "README.md").exists() else ""
|
|
15
|
+
|
|
16
|
+
# Try to read __version__ from package if present, otherwise fall back to 0.0.0
|
|
17
|
+
def read_version():
|
|
18
|
+
version_file = HERE / "src" / "sysgraph" / "__init__.py"
|
|
19
|
+
if version_file.exists():
|
|
20
|
+
for line in version_file.read_text(encoding="utf-8").splitlines():
|
|
21
|
+
if line.strip().startswith("__version__"):
|
|
22
|
+
# supports formats: __version__ = '0.1.0' or "0.1.0"
|
|
23
|
+
delim = '"' if '"' in line else "'"
|
|
24
|
+
return line.split(delim)[1]
|
|
25
|
+
return "0.0.0"
|
|
26
|
+
|
|
27
|
+
# Find packages in src/ (handles ordinary packages). If none found, try namespace packages.
|
|
28
|
+
packages = find_packages(where="src")
|
|
29
|
+
if not packages:
|
|
30
|
+
try:
|
|
31
|
+
from setuptools import find_namespace_packages
|
|
32
|
+
|
|
33
|
+
packages = find_namespace_packages(where="src")
|
|
34
|
+
except Exception:
|
|
35
|
+
packages = []
|
|
36
|
+
|
|
37
|
+
setup(
|
|
38
|
+
name="sysgraph",
|
|
39
|
+
version=read_version(),
|
|
40
|
+
description="Visualizer for processes and their interconnections",
|
|
41
|
+
long_description=README,
|
|
42
|
+
long_description_content_type="text/markdown",
|
|
43
|
+
author="Eugene Gubenkov",
|
|
44
|
+
author_email="gubenkoved@gmail.com",
|
|
45
|
+
url="https://github.com/gubenkoved/sysgraph",
|
|
46
|
+
packages=packages,
|
|
47
|
+
package_dir={"": "src"},
|
|
48
|
+
include_package_data=True,
|
|
49
|
+
package_data={"sysgraph": ["dist/*", "dist/**/*"]},
|
|
50
|
+
zip_safe=False,
|
|
51
|
+
python_requires=">=3.12",
|
|
52
|
+
install_requires=[
|
|
53
|
+
"psutil",
|
|
54
|
+
"coloredlogs",
|
|
55
|
+
"fastapi>=0.95",
|
|
56
|
+
"uvicorn[standard]>=0.20",
|
|
57
|
+
],
|
|
58
|
+
classifiers=[
|
|
59
|
+
"Programming Language :: Python :: 3",
|
|
60
|
+
"Programming Language :: Python :: 3.12",
|
|
61
|
+
"Programming Language :: Python :: 3.13",
|
|
62
|
+
"License :: OSI Approved :: MIT License",
|
|
63
|
+
"Operating System :: POSIX :: Linux",
|
|
64
|
+
"Topic :: System :: Monitoring",
|
|
65
|
+
"Topic :: System :: Systems Administration",
|
|
66
|
+
"Environment :: Web Environment",
|
|
67
|
+
"Framework :: FastAPI",
|
|
68
|
+
"Intended Audience :: Developers",
|
|
69
|
+
"Intended Audience :: System Administrators",
|
|
70
|
+
],
|
|
71
|
+
keywords=[
|
|
72
|
+
"process",
|
|
73
|
+
"visualization",
|
|
74
|
+
"graph",
|
|
75
|
+
"ipc",
|
|
76
|
+
"system",
|
|
77
|
+
"monitoring",
|
|
78
|
+
"linux",
|
|
79
|
+
"procfs",
|
|
80
|
+
],
|
|
81
|
+
entry_points={
|
|
82
|
+
"console_scripts": [
|
|
83
|
+
"sysgraph=sysgraph.app:main",
|
|
84
|
+
],
|
|
85
|
+
},
|
|
86
|
+
license="MIT",
|
|
87
|
+
project_urls={
|
|
88
|
+
"Source": "https://github.com/gubenkoved/sysgraph",
|
|
89
|
+
"Issues": "https://github.com/gubenkoved/sysgraph/issues",
|
|
90
|
+
},
|
|
91
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.0.11"
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
import os
|
|
5
|
+
from contextlib import asynccontextmanager
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
import coloredlogs
|
|
10
|
+
from fastapi import FastAPI
|
|
11
|
+
from fastapi.middleware.gzip import GZipMiddleware
|
|
12
|
+
from fastapi.responses import FileResponse
|
|
13
|
+
from fastapi.staticfiles import StaticFiles
|
|
14
|
+
from pydantic import BaseModel
|
|
15
|
+
|
|
16
|
+
from sysgraph.discovery import build_graph
|
|
17
|
+
|
|
18
|
+
LOGGER = logging.getLogger(__name__)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@asynccontextmanager
|
|
22
|
+
async def lifespan(app):
|
|
23
|
+
coloredlogs.install()
|
|
24
|
+
logging.info(f"init for process with PID {os.getpid()}")
|
|
25
|
+
yield
|
|
26
|
+
logging.info(f"shutdown for process with PID {os.getpid()}")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
app = FastAPI(title="sysgraph API", version="0.1.0", lifespan=lifespan)
|
|
30
|
+
app.add_middleware(GZipMiddleware, minimum_size=500)
|
|
31
|
+
|
|
32
|
+
# Vite build output — run scripts/build-ui.sh to produce it.
|
|
33
|
+
_dist_dir = Path(__file__).parent / "dist"
|
|
34
|
+
|
|
35
|
+
if not _dist_dir.is_dir():
|
|
36
|
+
LOGGER.warning(
|
|
37
|
+
"dist/ not found — frontend will not be served. "
|
|
38
|
+
"Run scripts/build-ui.sh to produce a production build."
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
# Root route serves the SPA index — defined before the catch-all mount.
|
|
43
|
+
@app.get("/", include_in_schema=False)
|
|
44
|
+
def index():
|
|
45
|
+
index_path = _dist_dir / "index.html"
|
|
46
|
+
return FileResponse(index_path)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class GraphNodeSchema(BaseModel):
|
|
50
|
+
id: str
|
|
51
|
+
type: str
|
|
52
|
+
properties: dict[str, Any]
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class GraphEdgeSchema(BaseModel):
|
|
56
|
+
id: str
|
|
57
|
+
source_id: str
|
|
58
|
+
target_id: str
|
|
59
|
+
type: str
|
|
60
|
+
properties: dict[str, Any]
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class GraphSchema(BaseModel):
|
|
64
|
+
nodes: list[GraphNodeSchema]
|
|
65
|
+
edges: list[GraphEdgeSchema]
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
@app.get("/api/health")
|
|
69
|
+
def health():
|
|
70
|
+
return {"status": "ok"}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@app.get("/api/graph", response_model=GraphSchema)
|
|
74
|
+
def get_graph() -> GraphSchema:
|
|
75
|
+
graph = build_graph()
|
|
76
|
+
graph_dict = graph.as_dict()
|
|
77
|
+
|
|
78
|
+
LOGGER.debug(graph_dict)
|
|
79
|
+
|
|
80
|
+
return GraphSchema(
|
|
81
|
+
nodes=[
|
|
82
|
+
GraphNodeSchema(
|
|
83
|
+
id=node["id"], type=node["type"], properties=node["properties"]
|
|
84
|
+
)
|
|
85
|
+
for node in graph_dict["nodes"]
|
|
86
|
+
],
|
|
87
|
+
edges=[
|
|
88
|
+
GraphEdgeSchema(
|
|
89
|
+
id=edge["id"],
|
|
90
|
+
source_id=edge["source_id"],
|
|
91
|
+
target_id=edge["target_id"],
|
|
92
|
+
type=edge["type"],
|
|
93
|
+
properties=edge["properties"],
|
|
94
|
+
)
|
|
95
|
+
for edge in graph_dict["edges"]
|
|
96
|
+
],
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
# Serve built assets (JS/CSS bundles, Shoelace icons, etc.) from the same
|
|
101
|
+
# directory that provides index.html. This catch-all mount MUST come after
|
|
102
|
+
# all explicit routes so that /api/* and / are matched first.
|
|
103
|
+
if _dist_dir.is_dir():
|
|
104
|
+
app.mount(
|
|
105
|
+
"/", StaticFiles(directory=str(_dist_dir)), name="static"
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def main():
|
|
110
|
+
import argparse
|
|
111
|
+
|
|
112
|
+
import uvicorn
|
|
113
|
+
|
|
114
|
+
parser = argparse.ArgumentParser(description="sysgraph server")
|
|
115
|
+
parser.add_argument(
|
|
116
|
+
"-p",
|
|
117
|
+
"--port",
|
|
118
|
+
type=int,
|
|
119
|
+
default=int(os.environ.get("PORT", 8000)),
|
|
120
|
+
help="port to listen on (default: 8000, or PORT env var)",
|
|
121
|
+
)
|
|
122
|
+
args = parser.parse_args()
|
|
123
|
+
|
|
124
|
+
uvicorn.run(
|
|
125
|
+
"sysgraph.app:app",
|
|
126
|
+
host="0.0.0.0",
|
|
127
|
+
port=args.port,
|
|
128
|
+
reload=True,
|
|
129
|
+
log_level="info",
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
if __name__ == "__main__":
|
|
134
|
+
main()
|