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.
Files changed (86) hide show
  1. dbgr_server/__init__.py +1 -0
  2. dbgr_server/__main__.py +61 -0
  3. dbgr_server/app.py +139 -0
  4. dbgr_server/constants.py +10 -0
  5. dbgr_server/routes.py +22 -0
  6. dbgr_server/static/fonts/MapleMono-NF-Bold.ttf +0 -0
  7. dbgr_server/static/fonts/MapleMono-NF-BoldItalic.ttf +0 -0
  8. dbgr_server/static/fonts/MapleMono-NF-Italic.ttf +0 -0
  9. dbgr_server/static/fonts/MapleMono-NF-Regular.ttf +0 -0
  10. dbgr_server/static/images/favicon.ico +0 -0
  11. dbgr_server/static/javascripts/dist/0d8bb5b3ee5f5dac9e44.woff2 +0 -0
  12. dbgr_server/static/javascripts/dist/16b1558858fe1064b5af.woff +0 -0
  13. dbgr_server/static/javascripts/dist/176f8f5bd5f02b3abfcf.woff2 +0 -0
  14. dbgr_server/static/javascripts/dist/18d00f739ff1e1c52db1.woff +0 -0
  15. dbgr_server/static/javascripts/dist/1b3b4f49d5b3b3fb2c20.jpg +0 -0
  16. dbgr_server/static/javascripts/dist/1ce08cfde36c0d81af5b.woff +0 -0
  17. dbgr_server/static/javascripts/dist/213eedde97d22010287c.woff +0 -0
  18. dbgr_server/static/javascripts/dist/2267169ee7270a22a963.woff +0 -0
  19. dbgr_server/static/javascripts/dist/24a9d3bbf9b715214bf5.woff +0 -0
  20. dbgr_server/static/javascripts/dist/2900d24e7347deaf65cd.woff +0 -0
  21. dbgr_server/static/javascripts/dist/2ed4651232a34d737777.woff +0 -0
  22. dbgr_server/static/javascripts/dist/37a7069dc30fc663c878.woff2 +0 -0
  23. dbgr_server/static/javascripts/dist/451d4e559d6f57cdf6a1.woff +0 -0
  24. dbgr_server/static/javascripts/dist/4674f8ded773cb03e824.eot +0 -0
  25. dbgr_server/static/javascripts/dist/498042b7fe9cd07b4fd1.woff +0 -0
  26. dbgr_server/static/javascripts/dist/49ae34d4cc6b98c00c69.woff +0 -0
  27. dbgr_server/static/javascripts/dist/51aa168dd4ba03bd83f0.woff2 +0 -0
  28. dbgr_server/static/javascripts/dist/535bc89d4af715503b01.woff2 +0 -0
  29. dbgr_server/static/javascripts/dist/53b43867955fbecc811a.woff2 +0 -0
  30. dbgr_server/static/javascripts/dist/5e7382c63da0098d634a.ttf +0 -0
  31. dbgr_server/static/javascripts/dist/640f8692dc49a19f1541.woff +0 -0
  32. dbgr_server/static/javascripts/dist/79f21d796f266ce0ea70.woff +0 -0
  33. dbgr_server/static/javascripts/dist/7d8125ff7f707231fd89.woff2 +0 -0
  34. dbgr_server/static/javascripts/dist/7f7e9cd596438fea4b02.woff2 +0 -0
  35. dbgr_server/static/javascripts/dist/7f839a8652da29745ce4.woff2 +0 -0
  36. dbgr_server/static/javascripts/dist/83bebaf37c09c7e1c3ee.woff +0 -0
  37. dbgr_server/static/javascripts/dist/865f928cbabcc9f8f2b5.woff +0 -0
  38. dbgr_server/static/javascripts/dist/870c8c1486f76054301a.woff2 +0 -0
  39. dbgr_server/static/javascripts/dist/9216be4e13fe7dbe70ef.woff2 +0 -0
  40. dbgr_server/static/javascripts/dist/9360531f9bb817f917f0.woff +0 -0
  41. dbgr_server/static/javascripts/dist/969a44e1b6fc26105bd6.woff2 +0 -0
  42. dbgr_server/static/javascripts/dist/a45108d3b34af91f9113.woff +0 -0
  43. dbgr_server/static/javascripts/dist/b1d9d9904bfca8802a63.woff +0 -0
  44. dbgr_server/static/javascripts/dist/b39a11f9a6107e57a21f.woff2 +0 -0
  45. dbgr_server/static/javascripts/dist/bac8362e7a6ea60b6983.woff +0 -0
  46. dbgr_server/static/javascripts/dist/bbbf6951525a78fff340.woff +0 -0
  47. dbgr_server/static/javascripts/dist/bc628a95b5026af0df2c.woff2 +0 -0
  48. dbgr_server/static/javascripts/dist/bd5b7a13f2c52b531a2a.woff +0 -0
  49. dbgr_server/static/javascripts/dist/bf4b4e73015a3066da91.woff +0 -0
  50. dbgr_server/static/javascripts/dist/bfe6eaec56c141a0bd72.woff2 +0 -0
  51. dbgr_server/static/javascripts/dist/c18ee39fb002ad58b6dc.woff2 +0 -0
  52. dbgr_server/static/javascripts/dist/c1f17364fee75703a7ee.woff2 +0 -0
  53. dbgr_server/static/javascripts/dist/c20d916c1a1b094c1cec.woff +0 -0
  54. dbgr_server/static/javascripts/dist/c2aa4ab115bf9c6057cb.woff2 +0 -0
  55. dbgr_server/static/javascripts/dist/c5c3959c04004102ea46.woff2 +0 -0
  56. dbgr_server/static/javascripts/dist/c64e7e354c88e613c77c.woff2 +0 -0
  57. dbgr_server/static/javascripts/dist/ca100b2be6274105bb16.woff +0 -0
  58. dbgr_server/static/javascripts/dist/cb5ad999740e9d8a8bd1.woff2 +0 -0
  59. dbgr_server/static/javascripts/dist/cc9e42999888377183f8.woff2 +0 -0
  60. dbgr_server/static/javascripts/dist/cea99d3e3e13a3a599a0.woff +0 -0
  61. dbgr_server/static/javascripts/dist/cff684e59ffb052d72cb.woff2 +0 -0
  62. dbgr_server/static/javascripts/dist/d022bc70dc1bf7b3425d.woff2 +0 -0
  63. dbgr_server/static/javascripts/dist/d97850bb044fb5584361.woff2 +0 -0
  64. dbgr_server/static/javascripts/dist/da65dcd09cdc4863ece2.woff +0 -0
  65. dbgr_server/static/javascripts/dist/dbgr.js +1463 -0
  66. dbgr_server/static/javascripts/dist/eba647ae67ba7dc20f05.woff +0 -0
  67. dbgr_server/static/javascripts/dist/f5b74d7ffcdf85b9dd60.woff2 +0 -0
  68. dbgr_server/static/javascripts/dist/ff2c5c919a01e9ddda85.woff2 +0 -0
  69. dbgr_server/static/javascripts/dist/home.js +1037 -0
  70. dbgr_server/static/libs/material-design-lite/material.indigo-red.min.css +8 -0
  71. dbgr_server/templates/_layout.html +17 -0
  72. dbgr_server/templates/dbgr.html +138 -0
  73. dbgr_server/templates/home.html +115 -0
  74. dbgr_server/utils/__init__.py +0 -0
  75. dbgr_server/utils/state.py +249 -0
  76. dbgr_server/utils/streams.py +151 -0
  77. dbgr_server/utils/technical.py +132 -0
  78. dbgr_server/views.py +298 -0
  79. dbgr_server-1.1.0.dev1.data/scripts/dbgr.server.py +105 -0
  80. dbgr_server-1.1.0.dev1.dist-info/METADATA +534 -0
  81. dbgr_server-1.1.0.dev1.dist-info/RECORD +86 -0
  82. dbgr_server-1.1.0.dev1.dist-info/WHEEL +5 -0
  83. dbgr_server-1.1.0.dev1.dist-info/licenses/LICENSE +674 -0
  84. dbgr_server-1.1.0.dev1.dist-info/top_level.txt +2 -0
  85. tests/__init__.py +0 -0
  86. tests/test_app.py +84 -0
@@ -0,0 +1 @@
1
+ __version__ = "1.1.0-dev1"
@@ -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
@@ -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