lumen-app 0.4.2__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 (56) hide show
  1. lumen_app/__init__.py +7 -0
  2. lumen_app/core/__init__.py +0 -0
  3. lumen_app/core/config.py +661 -0
  4. lumen_app/core/installer.py +274 -0
  5. lumen_app/core/loader.py +45 -0
  6. lumen_app/core/router.py +87 -0
  7. lumen_app/core/server.py +389 -0
  8. lumen_app/core/service.py +49 -0
  9. lumen_app/core/tests/__init__.py +1 -0
  10. lumen_app/core/tests/test_core_integration.py +561 -0
  11. lumen_app/core/tests/test_env_checker.py +487 -0
  12. lumen_app/proto/README.md +12 -0
  13. lumen_app/proto/ml_service.proto +88 -0
  14. lumen_app/proto/ml_service_pb2.py +66 -0
  15. lumen_app/proto/ml_service_pb2.pyi +136 -0
  16. lumen_app/proto/ml_service_pb2_grpc.py +251 -0
  17. lumen_app/server.py +362 -0
  18. lumen_app/utils/env_checker.py +752 -0
  19. lumen_app/utils/installation/__init__.py +25 -0
  20. lumen_app/utils/installation/env_manager.py +152 -0
  21. lumen_app/utils/installation/micromamba_installer.py +459 -0
  22. lumen_app/utils/installation/package_installer.py +149 -0
  23. lumen_app/utils/installation/verifier.py +95 -0
  24. lumen_app/utils/logger.py +181 -0
  25. lumen_app/utils/mamba/cuda.yaml +12 -0
  26. lumen_app/utils/mamba/default.yaml +6 -0
  27. lumen_app/utils/mamba/openvino.yaml +7 -0
  28. lumen_app/utils/mamba/tensorrt.yaml +13 -0
  29. lumen_app/utils/package_resolver.py +309 -0
  30. lumen_app/utils/preset_registry.py +219 -0
  31. lumen_app/web/__init__.py +3 -0
  32. lumen_app/web/api/__init__.py +1 -0
  33. lumen_app/web/api/config.py +229 -0
  34. lumen_app/web/api/hardware.py +201 -0
  35. lumen_app/web/api/install.py +608 -0
  36. lumen_app/web/api/server.py +253 -0
  37. lumen_app/web/core/__init__.py +1 -0
  38. lumen_app/web/core/server_manager.py +348 -0
  39. lumen_app/web/core/state.py +264 -0
  40. lumen_app/web/main.py +145 -0
  41. lumen_app/web/models/__init__.py +28 -0
  42. lumen_app/web/models/config.py +63 -0
  43. lumen_app/web/models/hardware.py +64 -0
  44. lumen_app/web/models/install.py +134 -0
  45. lumen_app/web/models/server.py +95 -0
  46. lumen_app/web/static/assets/index-CGuhGHC9.css +1 -0
  47. lumen_app/web/static/assets/index-DN6HmxWS.js +56 -0
  48. lumen_app/web/static/index.html +14 -0
  49. lumen_app/web/static/vite.svg +1 -0
  50. lumen_app/web/websockets/__init__.py +1 -0
  51. lumen_app/web/websockets/logs.py +159 -0
  52. lumen_app-0.4.2.dist-info/METADATA +23 -0
  53. lumen_app-0.4.2.dist-info/RECORD +56 -0
  54. lumen_app-0.4.2.dist-info/WHEEL +5 -0
  55. lumen_app-0.4.2.dist-info/entry_points.txt +3 -0
  56. lumen_app-0.4.2.dist-info/top_level.txt +1 -0
@@ -0,0 +1,14 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>web-ui</title>
8
+ <script type="module" crossorigin src="/assets/index-DN6HmxWS.js"></script>
9
+ <link rel="stylesheet" crossorigin href="/assets/index-CGuhGHC9.css">
10
+ </head>
11
+ <body>
12
+ <div id="root"></div>
13
+ </body>
14
+ </html>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
@@ -0,0 +1 @@
1
+ """WebSocket endpoints for real-time communication."""
@@ -0,0 +1,159 @@
1
+ """WebSocket endpoint for real-time log streaming."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import asyncio
6
+ import json
7
+ from datetime import datetime
8
+
9
+ from fastapi import APIRouter, WebSocket, WebSocketDisconnect
10
+
11
+ from lumen_app.utils.logger import get_logger
12
+ from lumen_app.web.core.state import app_state
13
+
14
+ logger = get_logger("lumen.web.ws.logs")
15
+ router = APIRouter()
16
+
17
+
18
+ @router.websocket("/logs")
19
+ async def log_websocket(websocket: WebSocket):
20
+ """WebSocket endpoint for streaming logs."""
21
+ await websocket.accept()
22
+ logger.info("New log WebSocket connection")
23
+
24
+ # Subscribe to logs
25
+ log_queue = await app_state.subscribe_logs()
26
+
27
+ try:
28
+ # Send initial connection message
29
+ await websocket.send_json(
30
+ {
31
+ "type": "connected",
32
+ "timestamp": datetime.utcnow().isoformat(),
33
+ "message": "Connected to log stream",
34
+ }
35
+ )
36
+
37
+ while True:
38
+ try:
39
+ # Wait for log entry with timeout
40
+ log_entry = await asyncio.wait_for(log_queue.get(), timeout=1.0)
41
+
42
+ # Send to client
43
+ await websocket.send_json(
44
+ {
45
+ "type": "log",
46
+ "timestamp": log_entry.get(
47
+ "timestamp", datetime.utcnow().isoformat()
48
+ ),
49
+ "level": log_entry.get("level", "INFO"),
50
+ "message": log_entry.get("message", ""),
51
+ "source": log_entry.get("source", "unknown"),
52
+ }
53
+ )
54
+
55
+ except asyncio.TimeoutError:
56
+ # Send heartbeat to keep connection alive
57
+ await websocket.send_json(
58
+ {
59
+ "type": "heartbeat",
60
+ "timestamp": datetime.utcnow().isoformat(),
61
+ }
62
+ )
63
+
64
+ except WebSocketDisconnect:
65
+ logger.info("Log WebSocket disconnected")
66
+ except Exception as e:
67
+ logger.error(f"Log WebSocket error: {e}")
68
+ try:
69
+ await websocket.send_json(
70
+ {
71
+ "type": "error",
72
+ "message": str(e),
73
+ }
74
+ )
75
+ except:
76
+ pass
77
+ finally:
78
+ # Unsubscribe from logs
79
+ await app_state.unsubscribe_logs(log_queue)
80
+ try:
81
+ await websocket.close()
82
+ except:
83
+ pass
84
+
85
+
86
+ @router.websocket("/install/{task_id}")
87
+ async def install_progress_websocket(websocket: WebSocket, task_id: str):
88
+ """WebSocket endpoint for installation progress updates."""
89
+ await websocket.accept()
90
+ logger.info(f"New install progress WebSocket for task {task_id}")
91
+
92
+ try:
93
+ # Send initial status
94
+ task = await app_state.get_task(task_id)
95
+ if task:
96
+ await websocket.send_json(
97
+ {
98
+ "type": "status",
99
+ "task_id": task_id,
100
+ "task_type": task.type,
101
+ "status": task.status,
102
+ "progress": task.progress,
103
+ "message": task.message,
104
+ }
105
+ )
106
+
107
+ # Poll for updates
108
+ while True:
109
+ await asyncio.sleep(1)
110
+
111
+ task = await app_state.get_task(task_id)
112
+ if not task:
113
+ await websocket.send_json(
114
+ {
115
+ "type": "error",
116
+ "message": f"Task {task_id} not found",
117
+ }
118
+ )
119
+ break
120
+
121
+ await websocket.send_json(
122
+ {
123
+ "type": "status",
124
+ "task_id": task_id,
125
+ "task_type": task.type,
126
+ "status": task.status,
127
+ "progress": task.progress,
128
+ "message": task.message,
129
+ }
130
+ )
131
+
132
+ if task.status in ("completed", "failed", "cancelled"):
133
+ await websocket.send_json(
134
+ {
135
+ "type": "complete",
136
+ "task_id": task_id,
137
+ "status": task.status,
138
+ }
139
+ )
140
+ break
141
+
142
+ except WebSocketDisconnect:
143
+ logger.info(f"Install progress WebSocket for task {task_id} disconnected")
144
+ except Exception as e:
145
+ logger.error(f"Install progress WebSocket error: {e}")
146
+ try:
147
+ await websocket.send_json(
148
+ {
149
+ "type": "error",
150
+ "message": str(e),
151
+ }
152
+ )
153
+ except:
154
+ pass
155
+ finally:
156
+ try:
157
+ await websocket.close()
158
+ except:
159
+ pass
@@ -0,0 +1,23 @@
1
+ Metadata-Version: 2.4
2
+ Name: lumen-app
3
+ Version: 0.4.2
4
+ Summary: Desktop application for Lumen AI services
5
+ Author-email: EdwinZhanCN <support@lumilio.org>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/EdwinZhanCN/Lumen
8
+ Project-URL: Issues, https://github.com/EdwinZhanCN/Lumen/issues
9
+ Requires-Python: >=3.10
10
+ Description-Content-Type: text/markdown
11
+ Requires-Dist: colorlog>=6.10.1
12
+ Requires-Dist: fastapi>=0.115.0
13
+ Requires-Dist: uvicorn[standard]>=0.32.0
14
+ Requires-Dist: websockets>=14.0
15
+ Requires-Dist: pydantic>=2.10.0
16
+ Requires-Dist: lumen-resources
17
+ Requires-Dist: pyyaml>=6.0.3
18
+ Requires-Dist: aiofiles>=24.1.0
19
+ Requires-Dist: psutil>=6.1.0
20
+ Requires-Dist: httpx>=0.28.0
21
+ Requires-Dist: grpcio>=1.68.0
22
+ Requires-Dist: protobuf>=6.30.0
23
+ Requires-Dist: zeroconf>=0.148.0
@@ -0,0 +1,56 @@
1
+ lumen_app/__init__.py,sha256=Dja5CGO83c0zdXHcvlesYLjVzQjBmyTrBu6Q37DpokI,139
2
+ lumen_app/server.py,sha256=GrOhjQ5QxwoYMTSaYIX4LWT6-DSXtf4ArpY1ildA180,11999
3
+ lumen_app/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ lumen_app/core/config.py,sha256=GcPdmNucQyMFI3ao0bpfKeEsy6diBaTrZsewF6HGCdU,26343
5
+ lumen_app/core/installer.py,sha256=xEnG_IIWJ_WnhvMP7vAGgfLsCosyjdeA9uuqdNyDC4A,10189
6
+ lumen_app/core/loader.py,sha256=hZvFJgcEexA4jQHG1T9C7NPO9cvJNzECM9lufkt7cmY,1459
7
+ lumen_app/core/router.py,sha256=CTzpGE4Bd6Y_Cqo0TApzsO6UOh3ZoEsW0d24hzZrBKY,3155
8
+ lumen_app/core/server.py,sha256=8NMwyibEAZMCyswVOREps08ZBwN28kzt9-PWu4YdY2s,13280
9
+ lumen_app/core/service.py,sha256=zIlFMrGtPTHtxZ2Tt5WEDg4dbD7BXPbNGwSrgSSQJPo,1770
10
+ lumen_app/core/tests/__init__.py,sha256=SkFP7Rt_4ARb4aJkRo7GZX0vb2qPUtBCBdb8sqpSWrI,32
11
+ lumen_app/core/tests/test_core_integration.py,sha256=QLEbNB-NdkYaK1SEgxQkvUZecRpcT1kG-YdWRQcJwO8,18965
12
+ lumen_app/core/tests/test_env_checker.py,sha256=J6zscUumwq3f3dZfD2Ce9It7gw2DpBNP3k-IQmM1dZc,16968
13
+ lumen_app/proto/README.md,sha256=MEK0OyXOfoyU1ABpEQQgMsslXr2xSez6fGyOg2MheeI,317
14
+ lumen_app/proto/ml_service.proto,sha256=iqGpErTXNllKXzC__KfE7AONQ5dQUCkh2Ar4vdDOW0I,4661
15
+ lumen_app/proto/ml_service_pb2.py,sha256=ijY4Ed00vOVjA__7ljZG4HB4VjpisVW5W_Hdzk62ZGk,5710
16
+ lumen_app/proto/ml_service_pb2.pyi,sha256=OT5CiA4TLKhv7GE2ASPFgzcCldYeCvwpf2ga3-wAmzQ,6544
17
+ lumen_app/proto/ml_service_pb2_grpc.py,sha256=wFsFzOe83YKJ-fgT6fnByteNDJH6E9SjZsKt7F9iE-8,8763
18
+ lumen_app/utils/env_checker.py,sha256=k2ox2KuVK0XWdgenirIgGkdDfsZIecZIkqJvbP1hxVc,28140
19
+ lumen_app/utils/logger.py,sha256=OXPuVoN0PNqpVc1a8xooYScChNOENsXgelZlU0wiLug,5359
20
+ lumen_app/utils/package_resolver.py,sha256=QdqFYWbm-vSUG1Mz7TUY5wZBx0WJkqsbQqeV9qx9yec,10494
21
+ lumen_app/utils/preset_registry.py,sha256=HBX5jI-4GBiASCpQRMkjnAiAMU_O5j0YLQpZV4ZENqg,7034
22
+ lumen_app/utils/installation/__init__.py,sha256=U7Gn4T15ydBfR5Gbc7LXRZtInuYXEnvytMi3JElg_cM,647
23
+ lumen_app/utils/installation/env_manager.py,sha256=50kO786BslFr_89WnZQZv6-cJL7cE9Tpiycp4Rb3nXI,4650
24
+ lumen_app/utils/installation/micromamba_installer.py,sha256=tzSPQeOKaCJ4qxBCivWglpBwDWwKHFJZjjDAUonfieM,16172
25
+ lumen_app/utils/installation/package_installer.py,sha256=ZyOa3likIyh2QoIjcg-FFI860syewW8e-OZmYUDuIYM,5300
26
+ lumen_app/utils/installation/verifier.py,sha256=aIhJzpTcwFer8eK0orD7EnzEiQZA7M27NlqkswnZGZY,2971
27
+ lumen_app/utils/mamba/cuda.yaml,sha256=HP1AjZBGMa3rdRwnlf7pjZh_8OqIXBFXRgip6hvyRaA,184
28
+ lumen_app/utils/mamba/default.yaml,sha256=ilgKgQ3ERufwCsOu9f-jmctqjPWc11qmNYo-4-_fEsg,85
29
+ lumen_app/utils/mamba/openvino.yaml,sha256=LMXAgJNuxgGTR3NAoar0iBmqU_-Irjjl1JzXQmfuCxk,110
30
+ lumen_app/utils/mamba/tensorrt.yaml,sha256=sTU9xBMApOcMyiNeYpxbEZ1uHJGQwg0X22gsz7bWFX4,199
31
+ lumen_app/web/__init__.py,sha256=paM05riy9ZwowEP-rDumBw9iiCIGvUn8Hctsy73BPuM,96
32
+ lumen_app/web/main.py,sha256=1EkUuNuzHvcEfxA2wvp8I5E7ctkaFIT0pi_yhHh8am4,4614
33
+ lumen_app/web/api/__init__.py,sha256=G42ctPKV56TynlhjT8gzzLe-ABtQi27jzb6blVH6blM,33
34
+ lumen_app/web/api/config.py,sha256=x3d5AG1ELL4511h535Alcz8ZjKU04CltBaqja1l5H7o,7509
35
+ lumen_app/web/api/hardware.py,sha256=_0VDB9i4_ghXiQw5sZSOTq1jOzEKWt67N_NAu5qfOO0,7049
36
+ lumen_app/web/api/install.py,sha256=S2nDv46CyzDV_YzBHwuquTHRSUlcI9jnyWSYkoh45A8,19908
37
+ lumen_app/web/api/server.py,sha256=T1gnu30RiwbiO-LlUSY9sn7BP8Oq3vZ0Ym0yrq7Yqc0,7628
38
+ lumen_app/web/core/__init__.py,sha256=IfEmRNHu-0E1On4a0yGLvoT1brAUV5BD6CdC5D005L8,38
39
+ lumen_app/web/core/server_manager.py,sha256=GUCOSg0RJOjMtaFTeDXHsxmkiT774afY6jTSkl6EmLs,10917
40
+ lumen_app/web/core/state.py,sha256=RB_ZeXSQPyPpwhAJlpcTYXmZkdjVGV8IxrfnpNgc7KA,8882
41
+ lumen_app/web/models/__init__.py,sha256=gFJq1qlM2fkRFHp8tw_4etKz_Xy4hseZge7WhtOAb_o,750
42
+ lumen_app/web/models/config.py,sha256=9kTCA21dNkPe4KM1pFdTbr81UzYeYcBCOpUPieWVo9U,1864
43
+ lumen_app/web/models/hardware.py,sha256=Jn3oKABvcf_CdTkZnL-bwAZcnyLsCGAzj83c10oFunU,1799
44
+ lumen_app/web/models/install.py,sha256=tpwMhQYaEKgiCxMWfdvZrDD4IHpOybMykeBOwcAo4qU,4054
45
+ lumen_app/web/models/server.py,sha256=PN59zeSuHXLuLPi2E515B0ZzB0l36BArZoFqyklDP_8,2252
46
+ lumen_app/web/static/index.html,sha256=maJdFO-RS1JCjo62WkUmrvIfOff5tO8ZwU0XqFelMIM,453
47
+ lumen_app/web/static/vite.svg,sha256=SnSK_UQ5GLsWWRyDTEAdrjPoeGGrXbrQgRw6O0qSFPs,1497
48
+ lumen_app/web/static/assets/index-CGuhGHC9.css,sha256=3b7kbzJRa8Jl3b2Od4dnBL_h2GPazWAvY37A6U0I3B4,30374
49
+ lumen_app/web/static/assets/index-DN6HmxWS.js,sha256=VVyJ43g_tRPB14e22G4SFdUPNuqarT_gqwHY6gwaZDA,422369
50
+ lumen_app/web/websockets/__init__.py,sha256=vMbHZ4P-k7B1UdzE7mjhkZr-RVu6-tOnUnSa073Q7Hc,55
51
+ lumen_app/web/websockets/logs.py,sha256=2TtWw6Ha-zuh2NzVvp0kw2lBHlkiRVSvgwaXXzkWhb8,4800
52
+ lumen_app-0.4.2.dist-info/METADATA,sha256=k2V2upkyv4uwxSPUjAnITugzvEhS2XbVPK-sbKLLtUQ,768
53
+ lumen_app-0.4.2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
54
+ lumen_app-0.4.2.dist-info/entry_points.txt,sha256=QAnWp-NWskToo_G26BlC9PG_BZzay0lOGrY8K7DRZdg,98
55
+ lumen_app-0.4.2.dist-info/top_level.txt,sha256=nnPzHSLoCAfZ0Jzyxta4KXtSbyTfMYt-4eALPzDE4dA,10
56
+ lumen_app-0.4.2.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.10.2)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ lumen = lumen_app.core.server:main
3
+ lumen-webui = lumen_app.web.main:start_webui
@@ -0,0 +1 @@
1
+ lumen_app