dbgr-server 1.1.0.dev1__py3-none-any.whl
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.
- dbgr_server/__init__.py +1 -0
- dbgr_server/__main__.py +61 -0
- dbgr_server/app.py +139 -0
- dbgr_server/constants.py +10 -0
- dbgr_server/routes.py +22 -0
- dbgr_server/static/fonts/MapleMono-NF-Bold.ttf +0 -0
- dbgr_server/static/fonts/MapleMono-NF-BoldItalic.ttf +0 -0
- dbgr_server/static/fonts/MapleMono-NF-Italic.ttf +0 -0
- dbgr_server/static/fonts/MapleMono-NF-Regular.ttf +0 -0
- dbgr_server/static/images/favicon.ico +0 -0
- dbgr_server/static/javascripts/dist/0d8bb5b3ee5f5dac9e44.woff2 +0 -0
- dbgr_server/static/javascripts/dist/16b1558858fe1064b5af.woff +0 -0
- dbgr_server/static/javascripts/dist/176f8f5bd5f02b3abfcf.woff2 +0 -0
- dbgr_server/static/javascripts/dist/18d00f739ff1e1c52db1.woff +0 -0
- dbgr_server/static/javascripts/dist/1b3b4f49d5b3b3fb2c20.jpg +0 -0
- dbgr_server/static/javascripts/dist/1ce08cfde36c0d81af5b.woff +0 -0
- dbgr_server/static/javascripts/dist/213eedde97d22010287c.woff +0 -0
- dbgr_server/static/javascripts/dist/2267169ee7270a22a963.woff +0 -0
- dbgr_server/static/javascripts/dist/24a9d3bbf9b715214bf5.woff +0 -0
- dbgr_server/static/javascripts/dist/2900d24e7347deaf65cd.woff +0 -0
- dbgr_server/static/javascripts/dist/2ed4651232a34d737777.woff +0 -0
- dbgr_server/static/javascripts/dist/37a7069dc30fc663c878.woff2 +0 -0
- dbgr_server/static/javascripts/dist/451d4e559d6f57cdf6a1.woff +0 -0
- dbgr_server/static/javascripts/dist/4674f8ded773cb03e824.eot +0 -0
- dbgr_server/static/javascripts/dist/498042b7fe9cd07b4fd1.woff +0 -0
- dbgr_server/static/javascripts/dist/49ae34d4cc6b98c00c69.woff +0 -0
- dbgr_server/static/javascripts/dist/51aa168dd4ba03bd83f0.woff2 +0 -0
- dbgr_server/static/javascripts/dist/535bc89d4af715503b01.woff2 +0 -0
- dbgr_server/static/javascripts/dist/53b43867955fbecc811a.woff2 +0 -0
- dbgr_server/static/javascripts/dist/5e7382c63da0098d634a.ttf +0 -0
- dbgr_server/static/javascripts/dist/640f8692dc49a19f1541.woff +0 -0
- dbgr_server/static/javascripts/dist/79f21d796f266ce0ea70.woff +0 -0
- dbgr_server/static/javascripts/dist/7d8125ff7f707231fd89.woff2 +0 -0
- dbgr_server/static/javascripts/dist/7f7e9cd596438fea4b02.woff2 +0 -0
- dbgr_server/static/javascripts/dist/7f839a8652da29745ce4.woff2 +0 -0
- dbgr_server/static/javascripts/dist/83bebaf37c09c7e1c3ee.woff +0 -0
- dbgr_server/static/javascripts/dist/865f928cbabcc9f8f2b5.woff +0 -0
- dbgr_server/static/javascripts/dist/870c8c1486f76054301a.woff2 +0 -0
- dbgr_server/static/javascripts/dist/9216be4e13fe7dbe70ef.woff2 +0 -0
- dbgr_server/static/javascripts/dist/9360531f9bb817f917f0.woff +0 -0
- dbgr_server/static/javascripts/dist/969a44e1b6fc26105bd6.woff2 +0 -0
- dbgr_server/static/javascripts/dist/a45108d3b34af91f9113.woff +0 -0
- dbgr_server/static/javascripts/dist/b1d9d9904bfca8802a63.woff +0 -0
- dbgr_server/static/javascripts/dist/b39a11f9a6107e57a21f.woff2 +0 -0
- dbgr_server/static/javascripts/dist/bac8362e7a6ea60b6983.woff +0 -0
- dbgr_server/static/javascripts/dist/bbbf6951525a78fff340.woff +0 -0
- dbgr_server/static/javascripts/dist/bc628a95b5026af0df2c.woff2 +0 -0
- dbgr_server/static/javascripts/dist/bd5b7a13f2c52b531a2a.woff +0 -0
- dbgr_server/static/javascripts/dist/bf4b4e73015a3066da91.woff +0 -0
- dbgr_server/static/javascripts/dist/bfe6eaec56c141a0bd72.woff2 +0 -0
- dbgr_server/static/javascripts/dist/c18ee39fb002ad58b6dc.woff2 +0 -0
- dbgr_server/static/javascripts/dist/c1f17364fee75703a7ee.woff2 +0 -0
- dbgr_server/static/javascripts/dist/c20d916c1a1b094c1cec.woff +0 -0
- dbgr_server/static/javascripts/dist/c2aa4ab115bf9c6057cb.woff2 +0 -0
- dbgr_server/static/javascripts/dist/c5c3959c04004102ea46.woff2 +0 -0
- dbgr_server/static/javascripts/dist/c64e7e354c88e613c77c.woff2 +0 -0
- dbgr_server/static/javascripts/dist/ca100b2be6274105bb16.woff +0 -0
- dbgr_server/static/javascripts/dist/cb5ad999740e9d8a8bd1.woff2 +0 -0
- dbgr_server/static/javascripts/dist/cc9e42999888377183f8.woff2 +0 -0
- dbgr_server/static/javascripts/dist/cea99d3e3e13a3a599a0.woff +0 -0
- dbgr_server/static/javascripts/dist/cff684e59ffb052d72cb.woff2 +0 -0
- dbgr_server/static/javascripts/dist/d022bc70dc1bf7b3425d.woff2 +0 -0
- dbgr_server/static/javascripts/dist/d97850bb044fb5584361.woff2 +0 -0
- dbgr_server/static/javascripts/dist/da65dcd09cdc4863ece2.woff +0 -0
- dbgr_server/static/javascripts/dist/dbgr.js +1463 -0
- dbgr_server/static/javascripts/dist/eba647ae67ba7dc20f05.woff +0 -0
- dbgr_server/static/javascripts/dist/f5b74d7ffcdf85b9dd60.woff2 +0 -0
- dbgr_server/static/javascripts/dist/ff2c5c919a01e9ddda85.woff2 +0 -0
- dbgr_server/static/javascripts/dist/home.js +1037 -0
- dbgr_server/static/libs/material-design-lite/material.indigo-red.min.css +8 -0
- dbgr_server/templates/_layout.html +17 -0
- dbgr_server/templates/dbgr.html +138 -0
- dbgr_server/templates/home.html +115 -0
- dbgr_server/utils/__init__.py +0 -0
- dbgr_server/utils/state.py +249 -0
- dbgr_server/utils/streams.py +151 -0
- dbgr_server/utils/technical.py +132 -0
- dbgr_server/views.py +298 -0
- dbgr_server-1.1.0.dev1.data/scripts/dbgr.server.py +105 -0
- dbgr_server-1.1.0.dev1.dist-info/METADATA +534 -0
- dbgr_server-1.1.0.dev1.dist-info/RECORD +86 -0
- dbgr_server-1.1.0.dev1.dist-info/WHEEL +5 -0
- dbgr_server-1.1.0.dev1.dist-info/licenses/LICENSE +674 -0
- dbgr_server-1.1.0.dev1.dist-info/top_level.txt +2 -0
- tests/__init__.py +0 -0
- tests/test_app.py +84 -0
dbgr_server/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.1.0-dev1"
|
dbgr_server/__main__.py
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Stdlib:
|
|
2
|
+
import asyncio
|
|
3
|
+
import argparse
|
|
4
|
+
from logging import DEBUG, INFO, WARNING, getLogger
|
|
5
|
+
|
|
6
|
+
# Thirdparty:
|
|
7
|
+
import uvicorn
|
|
8
|
+
|
|
9
|
+
# Firstparty:
|
|
10
|
+
from dbgr_server.app import init_app
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def main() -> None:
|
|
14
|
+
parser = argparse.ArgumentParser()
|
|
15
|
+
parser.add_argument("--debug", action="store_true")
|
|
16
|
+
parser.add_argument("--extra-search-path", action="store_true")
|
|
17
|
+
parser.add_argument("--more", action="store_true")
|
|
18
|
+
parser.add_argument("--detached_session", action="store_true")
|
|
19
|
+
parser.add_argument("--show-filename", action="store_true")
|
|
20
|
+
parser.add_argument("--server-host", type=str, default="localhost")
|
|
21
|
+
parser.add_argument("--server-port", type=int, default=1984)
|
|
22
|
+
parser.add_argument("--socket-host", type=str, default="localhost")
|
|
23
|
+
parser.add_argument("--socket-port", type=int, default=19840)
|
|
24
|
+
args = parser.parse_args()
|
|
25
|
+
|
|
26
|
+
log = getLogger("dbgr_server")
|
|
27
|
+
if args.debug:
|
|
28
|
+
log.setLevel(INFO)
|
|
29
|
+
if args.more:
|
|
30
|
+
log.setLevel(DEBUG)
|
|
31
|
+
else:
|
|
32
|
+
log.setLevel(WARNING)
|
|
33
|
+
|
|
34
|
+
try:
|
|
35
|
+
import uvloop # pylint: disable=import-outside-toplevel
|
|
36
|
+
uvloop.install()
|
|
37
|
+
except ImportError: # pragma: no cover
|
|
38
|
+
pass
|
|
39
|
+
|
|
40
|
+
settings = {
|
|
41
|
+
"debug": args.debug,
|
|
42
|
+
"extra_search_path": args.extra_search_path,
|
|
43
|
+
"more": args.more,
|
|
44
|
+
"detached_session": args.detached_session,
|
|
45
|
+
"show_filename": args.show_filename,
|
|
46
|
+
"socket_host": args.socket_host,
|
|
47
|
+
"socket_port": args.socket_port,
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
app = asyncio.run(init_app(settings))
|
|
51
|
+
|
|
52
|
+
uvicorn.run(
|
|
53
|
+
app,
|
|
54
|
+
host=args.server_host,
|
|
55
|
+
port=args.server_port,
|
|
56
|
+
loop="none", # event loop already configured
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
if __name__ == "__main__":
|
|
61
|
+
main()
|
dbgr_server/app.py
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Stdlib:
|
|
2
|
+
import asyncio
|
|
3
|
+
import logging
|
|
4
|
+
import mimetypes
|
|
5
|
+
import sys
|
|
6
|
+
from contextlib import asynccontextmanager
|
|
7
|
+
from json import JSONDecodeError
|
|
8
|
+
from typing import Any, Dict, Optional
|
|
9
|
+
|
|
10
|
+
# Register font MIME types missing from some system mimetypes databases
|
|
11
|
+
mimetypes.add_type("font/woff2", ".woff2")
|
|
12
|
+
mimetypes.add_type("font/woff", ".woff")
|
|
13
|
+
mimetypes.add_type("font/ttf", ".ttf")
|
|
14
|
+
mimetypes.add_type("font/eot", ".eot")
|
|
15
|
+
|
|
16
|
+
# Thirdparty:
|
|
17
|
+
import httpx
|
|
18
|
+
from fastapi import FastAPI
|
|
19
|
+
from fastapi.staticfiles import StaticFiles
|
|
20
|
+
from fastapi.templating import Jinja2Templates
|
|
21
|
+
|
|
22
|
+
# Firstparty:
|
|
23
|
+
import dbgr_server
|
|
24
|
+
from dbgr_server.constants import PROJECT_DIR, THEME
|
|
25
|
+
from dbgr_server.routes import router
|
|
26
|
+
from dbgr_server.utils.state import settings as settings_store
|
|
27
|
+
from dbgr_server.utils.technical import LibPythonWatcher
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
async def init_versions(app: FastAPI) -> None:
|
|
31
|
+
async with httpx.AsyncClient(timeout=1) as client:
|
|
32
|
+
try:
|
|
33
|
+
resp = await client.get("https://pypi.org/pypi/dbgr-server/json")
|
|
34
|
+
info = resp.json()
|
|
35
|
+
pypi_version = info["info"]["version"]
|
|
36
|
+
app.state.pypi_version = pypi_version
|
|
37
|
+
except httpx.TimeoutException:
|
|
38
|
+
app.state.pypi_version = "pypi_error"
|
|
39
|
+
except (JSONDecodeError, KeyError):
|
|
40
|
+
app.state.pypi_version = "parsing_error"
|
|
41
|
+
except Exception: # pylint: disable=broad-except
|
|
42
|
+
app.state.pypi_version = "unknown_error"
|
|
43
|
+
|
|
44
|
+
app.state.version = dbgr_server.__version__
|
|
45
|
+
new_version: Any = False
|
|
46
|
+
if app.state.pypi_version not in (
|
|
47
|
+
"pypi_error",
|
|
48
|
+
"parsing_error",
|
|
49
|
+
"unknown_error",
|
|
50
|
+
app.state.version,
|
|
51
|
+
):
|
|
52
|
+
new_version = app.state.pypi_version
|
|
53
|
+
app.state.new_version = new_version
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def create_templates() -> Jinja2Templates:
|
|
57
|
+
templates = Jinja2Templates(directory=str(PROJECT_DIR / "templates"))
|
|
58
|
+
|
|
59
|
+
def asset(path: str) -> str:
|
|
60
|
+
"""Static URL with a mtime query string so browsers refetch after a rebuild."""
|
|
61
|
+
rel = path.lstrip("/")
|
|
62
|
+
try:
|
|
63
|
+
version = int((PROJECT_DIR / "static" / rel).stat().st_mtime)
|
|
64
|
+
except OSError:
|
|
65
|
+
version = 0
|
|
66
|
+
return f"/static/{rel}?v={version}"
|
|
67
|
+
|
|
68
|
+
templates.env.globals.update(
|
|
69
|
+
static=lambda path: f"/static{path}",
|
|
70
|
+
asset=asset,
|
|
71
|
+
url=lambda route, **kwargs: (
|
|
72
|
+
f"/static/{kwargs.get('filename', '')}"
|
|
73
|
+
if route == "static"
|
|
74
|
+
else "/"
|
|
75
|
+
),
|
|
76
|
+
)
|
|
77
|
+
return templates
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
@asynccontextmanager
|
|
81
|
+
async def lifespan(app: FastAPI): # type: ignore[type-arg]
|
|
82
|
+
socket_host: str = getattr(app.state, "socket_host", "localhost")
|
|
83
|
+
socket_port: Optional[int] = getattr(app.state, "socket_port", None)
|
|
84
|
+
|
|
85
|
+
if not socket_port:
|
|
86
|
+
yield
|
|
87
|
+
return
|
|
88
|
+
|
|
89
|
+
from dbgr_server.utils.streams import handle_tcp_connection # pylint: disable=import-outside-toplevel
|
|
90
|
+
|
|
91
|
+
tcp_server = await asyncio.start_server(
|
|
92
|
+
handle_tcp_connection, socket_host, socket_port
|
|
93
|
+
)
|
|
94
|
+
async with tcp_server:
|
|
95
|
+
tcp_server_task = asyncio.ensure_future(tcp_server.serve_forever())
|
|
96
|
+
try:
|
|
97
|
+
yield
|
|
98
|
+
finally:
|
|
99
|
+
tcp_server_task.cancel()
|
|
100
|
+
try:
|
|
101
|
+
await tcp_server_task
|
|
102
|
+
except asyncio.CancelledError:
|
|
103
|
+
pass
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
async def init_app(settings: Optional[Dict[str, Any]] = None) -> FastAPI:
|
|
107
|
+
if settings is None:
|
|
108
|
+
settings = {}
|
|
109
|
+
|
|
110
|
+
if LibPythonWatcher: # pragma: no cover
|
|
111
|
+
LibPythonWatcher(
|
|
112
|
+
sys.base_prefix if settings.get("extra_search_path") else None
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
app = FastAPI(lifespan=lifespan)
|
|
116
|
+
|
|
117
|
+
settings_store.update(**{
|
|
118
|
+
k: v for k, v in settings.items()
|
|
119
|
+
if k in ("debug", "extra_search_path", "more", "detached_session", "show_filename")
|
|
120
|
+
})
|
|
121
|
+
app.state.settings = settings_store
|
|
122
|
+
app.state.socket_host = settings.get("socket_host", "localhost")
|
|
123
|
+
app.state.socket_port = settings.get("socket_port", None)
|
|
124
|
+
|
|
125
|
+
logging.basicConfig(level=logging.DEBUG)
|
|
126
|
+
await init_versions(app)
|
|
127
|
+
app.state.theme = THEME
|
|
128
|
+
|
|
129
|
+
templates = create_templates()
|
|
130
|
+
app.state.templates = templates
|
|
131
|
+
|
|
132
|
+
app.include_router(router)
|
|
133
|
+
app.mount(
|
|
134
|
+
"/static",
|
|
135
|
+
StaticFiles(directory=str(PROJECT_DIR / "static")),
|
|
136
|
+
name="static",
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
return app
|
dbgr_server/constants.py
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Stdlib:
|
|
2
|
+
import pathlib
|
|
3
|
+
|
|
4
|
+
PROJECT_DIR = pathlib.Path(__file__).parent
|
|
5
|
+
THEME = "indigo-red"
|
|
6
|
+
DBGR_TYPES = ("home", "pm", "shell", "debug")
|
|
7
|
+
UUID_REGEXP = (
|
|
8
|
+
"[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}"
|
|
9
|
+
)
|
|
10
|
+
UNKNOWN_UUID = "UNKNOWN_UUID"
|
dbgr_server/routes.py
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Thirdparty:
|
|
2
|
+
from fastapi import APIRouter
|
|
3
|
+
|
|
4
|
+
# Firstparty:
|
|
5
|
+
from dbgr_server.views import (
|
|
6
|
+
debug_get,
|
|
7
|
+
debug_post_form,
|
|
8
|
+
home_get,
|
|
9
|
+
main_get,
|
|
10
|
+
status_ws,
|
|
11
|
+
websocket_ws,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
router = APIRouter()
|
|
15
|
+
|
|
16
|
+
router.add_api_route("/", home_get, methods=["GET"])
|
|
17
|
+
router.add_api_route("/{type_}/session/{uuid}", main_get, methods=["GET"])
|
|
18
|
+
router.add_api_route("/debug/file/{fn:path}", debug_get, methods=["GET"])
|
|
19
|
+
router.add_api_route("/debug/file/{fn:path}", debug_post_form, methods=["POST"])
|
|
20
|
+
router.add_api_route("/debug/file/", debug_post_form, methods=["POST"])
|
|
21
|
+
router.add_api_websocket_route("/websocket/{uuid}", websocket_ws)
|
|
22
|
+
router.add_api_websocket_route("/status", status_ws)
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|