dmart 1.4.0__py3-none-any.whl → 1.4.1__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.
- bundler.py +12 -4
- {dmart-1.4.0.dist-info → dmart-1.4.1.dist-info}/METADATA +1 -1
- {dmart-1.4.0.dist-info → dmart-1.4.1.dist-info}/RECORD +8 -8
- dmart.py +70 -8
- main.py +48 -2
- {dmart-1.4.0.dist-info → dmart-1.4.1.dist-info}/WHEEL +0 -0
- {dmart-1.4.0.dist-info → dmart-1.4.1.dist-info}/entry_points.txt +0 -0
- {dmart-1.4.0.dist-info → dmart-1.4.1.dist-info}/top_level.txt +0 -0
bundler.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import json
|
|
3
3
|
import subprocess
|
|
4
4
|
import PyInstaller.__main__
|
|
5
|
-
|
|
5
|
+
import os
|
|
6
6
|
|
|
7
7
|
branch_cmd = "git rev-parse --abbrev-ref HEAD"
|
|
8
8
|
result, _ = subprocess.Popen(branch_cmd.split(" "), stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
|
|
@@ -29,8 +29,7 @@ info = {
|
|
|
29
29
|
|
|
30
30
|
json.dump(info, open('info.json', 'w'))
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
PyInstaller.__main__.run([
|
|
32
|
+
args = [
|
|
34
33
|
'dmart.py',
|
|
35
34
|
'--name=dmart',
|
|
36
35
|
'--onefile',
|
|
@@ -41,4 +40,13 @@ PyInstaller.__main__.run([
|
|
|
41
40
|
'--collect-submodules=concurrent_log_handler',
|
|
42
41
|
'--collect-submodules=pythonjsonlogger',
|
|
43
42
|
'--clean',
|
|
44
|
-
]
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
cxb_path = 'cxb'
|
|
46
|
+
if not os.path.isdir(cxb_path):
|
|
47
|
+
cxb_path = '../cxb/dist/client'
|
|
48
|
+
|
|
49
|
+
if os.path.isdir(cxb_path):
|
|
50
|
+
args.append(f'--add-data={cxb_path}:cxb')
|
|
51
|
+
|
|
52
|
+
PyInstaller.__main__.run(args)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
bundler.py,sha256=
|
|
1
|
+
bundler.py,sha256=so8ZJResb1PcOH5vboa_mpFAdYr_T8u8DbbFXd570Lg,1704
|
|
2
2
|
data_generator.py,sha256=CnE-VHEeX7-lAXtqCgbRqR9WHjTuOgeiZcviYrHAmho,2287
|
|
3
|
-
dmart.py,sha256=
|
|
3
|
+
dmart.py,sha256=QZQvR0q3CGOJy8KzXh7m8wW51JqILw--xvC0N4akjnY,21683
|
|
4
4
|
get_settings.py,sha256=Sbe2WCoiK398E7HY4SNLfDN_GmE8knR4M-YJWF31jcg,153
|
|
5
|
-
main.py,sha256=
|
|
5
|
+
main.py,sha256=0jguG9WZMYJgYAR_JO95GrSFM8Hu5qbInABMxWvoY3I,19526
|
|
6
6
|
migrate.py,sha256=hn1MZoVby_Jjqhc7y3CrLcGD619QmVZv3PONNvO7VKQ,665
|
|
7
7
|
password_gen.py,sha256=xjx8wi105ZYvhLBBQj7_rugACpxifGXHse6f7YlGXWQ,196
|
|
8
8
|
run_notification_campaign.py,sha256=ZCvHfaimK4W6q4XuHs2r6wavMGipYYw4aUkNlxmGUd8,2652
|
|
@@ -142,8 +142,8 @@ utils/ticket_sys_utils.py,sha256=9QAlW2iiy8KyxQRBDj_WmzS5kKb0aYJmGwd4qzmGVqo,700
|
|
|
142
142
|
utils/web_notifier.py,sha256=QM87VVid2grC5lK3NdS1yzz0z1wXljr4GChJOeK86W4,843
|
|
143
143
|
utils/templates/activation.html.j2,sha256=XAMKCdoqONoc4ZQucD0yV-Pg5DlHHASZrTVItNS-iBE,640
|
|
144
144
|
utils/templates/reminder.html.j2,sha256=aoS8bTs56q4hjAZKsb0jV9c-PIURBELuBOpT_qPZNVU,639
|
|
145
|
-
dmart-1.4.
|
|
146
|
-
dmart-1.4.
|
|
147
|
-
dmart-1.4.
|
|
148
|
-
dmart-1.4.
|
|
149
|
-
dmart-1.4.
|
|
145
|
+
dmart-1.4.1.dist-info/METADATA,sha256=Xx4kYj7woXX61a2PqjZnthP2Ud5fVUpbly5mCg6xWCk,2068
|
|
146
|
+
dmart-1.4.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
147
|
+
dmart-1.4.1.dist-info/entry_points.txt,sha256=GjfoGh1bpxuU9HHGJzbtCFPNptHv9TryxHMN3uBSKpg,37
|
|
148
|
+
dmart-1.4.1.dist-info/top_level.txt,sha256=JTypu1r5v9v7ru-60JSSbnSMEESHFRMacpcz-rPJx_U,262
|
|
149
|
+
dmart-1.4.1.dist-info/RECORD,,
|
dmart.py
CHANGED
|
@@ -11,6 +11,7 @@ import subprocess
|
|
|
11
11
|
import sys
|
|
12
12
|
import time
|
|
13
13
|
import warnings
|
|
14
|
+
import webbrowser
|
|
14
15
|
from multiprocessing import freeze_support
|
|
15
16
|
from pathlib import Path
|
|
16
17
|
|
|
@@ -29,6 +30,7 @@ from utils.settings import settings
|
|
|
29
30
|
freeze_support()
|
|
30
31
|
|
|
31
32
|
commands = """ server
|
|
33
|
+
serve
|
|
32
34
|
hyper
|
|
33
35
|
health-check
|
|
34
36
|
create-index
|
|
@@ -49,7 +51,10 @@ sentinel = object()
|
|
|
49
51
|
def hypercorn_main() -> int:
|
|
50
52
|
parser = argparse.ArgumentParser()
|
|
51
53
|
parser.add_argument(
|
|
52
|
-
"application",
|
|
54
|
+
"application",
|
|
55
|
+
help="The application to dispatch to as path.to.module:instance.path",
|
|
56
|
+
nargs="?",
|
|
57
|
+
default="main:app"
|
|
53
58
|
)
|
|
54
59
|
parser.add_argument("--access-log", help="Deprecated, see access-logfile", default=sentinel)
|
|
55
60
|
parser.add_argument(
|
|
@@ -83,7 +88,7 @@ def hypercorn_main() -> int:
|
|
|
83
88
|
"-c",
|
|
84
89
|
"--config",
|
|
85
90
|
help="Location of a TOML config file, or when prefixed with `file:` a Python file, or when prefixed with `python:` a Python module.", # noqa: E501
|
|
86
|
-
default=
|
|
91
|
+
default="hypercorn_config.toml",
|
|
87
92
|
)
|
|
88
93
|
parser.add_argument(
|
|
89
94
|
"--debug",
|
|
@@ -210,6 +215,17 @@ def hypercorn_main() -> int:
|
|
|
210
215
|
parser.add_argument(
|
|
211
216
|
"-u", "--user", help="User to own any unix sockets.", default=sentinel, type=int
|
|
212
217
|
)
|
|
218
|
+
parser.add_argument(
|
|
219
|
+
"--open-cxb",
|
|
220
|
+
help="Open CXB page in browser after server starts",
|
|
221
|
+
action="store_true",
|
|
222
|
+
default=False,
|
|
223
|
+
)
|
|
224
|
+
parser.add_argument(
|
|
225
|
+
"--cxb-config",
|
|
226
|
+
help="Path to CXB config.json",
|
|
227
|
+
default=sentinel,
|
|
228
|
+
)
|
|
213
229
|
|
|
214
230
|
def _convert_verify_mode(value: str) -> ssl.VerifyMode:
|
|
215
231
|
try:
|
|
@@ -314,6 +330,9 @@ def hypercorn_main() -> int:
|
|
|
314
330
|
config.websocket_ping_interval = args.websocket_ping_interval
|
|
315
331
|
if args.workers is not sentinel:
|
|
316
332
|
config.workers = args.workers
|
|
333
|
+
|
|
334
|
+
if args.cxb_config is not sentinel:
|
|
335
|
+
os.environ["DMART_CXB_CONFIG"] = args.cxb_config
|
|
317
336
|
|
|
318
337
|
if len(args.binds) > 0:
|
|
319
338
|
config.bind = args.binds
|
|
@@ -323,6 +342,32 @@ def hypercorn_main() -> int:
|
|
|
323
342
|
config.quic_bind = args.quic_binds
|
|
324
343
|
if len(args.server_names) > 0:
|
|
325
344
|
config.server_names = args.server_names
|
|
345
|
+
|
|
346
|
+
if args.open_cxb:
|
|
347
|
+
# Assuming default port 8282 if not specified in binds
|
|
348
|
+
port = 8282
|
|
349
|
+
host = "127.0.0.1"
|
|
350
|
+
|
|
351
|
+
# Try to parse bind address if available
|
|
352
|
+
if len(args.binds) > 0:
|
|
353
|
+
try:
|
|
354
|
+
bind_parts = args.binds[0].split(":")
|
|
355
|
+
if len(bind_parts) == 2:
|
|
356
|
+
host = bind_parts[0]
|
|
357
|
+
port = int(bind_parts[1])
|
|
358
|
+
elif len(bind_parts) == 1:
|
|
359
|
+
host = bind_parts[0]
|
|
360
|
+
except:
|
|
361
|
+
pass
|
|
362
|
+
|
|
363
|
+
url = f"http://{host}:{port}/cxb/"
|
|
364
|
+
|
|
365
|
+
def open_browser():
|
|
366
|
+
time.sleep(2) # Give server a moment to start
|
|
367
|
+
webbrowser.open(url)
|
|
368
|
+
|
|
369
|
+
import threading
|
|
370
|
+
threading.Thread(target=open_browser, daemon=True).start()
|
|
326
371
|
|
|
327
372
|
return run(config)
|
|
328
373
|
|
|
@@ -336,13 +381,30 @@ def main():
|
|
|
336
381
|
|
|
337
382
|
match sys.argv[0]:
|
|
338
383
|
case "hyper":
|
|
339
|
-
if len(sys.argv) == 1:
|
|
340
|
-
print("Running Hypercorn with default settings")
|
|
341
|
-
default_params = "main:app --config hypercorn_config.toml"
|
|
342
|
-
print(f">{default_params}")
|
|
343
|
-
sys.argv = ["hyper"] + default_params.split(" ")
|
|
344
384
|
hypercorn_main()
|
|
345
|
-
case "server":
|
|
385
|
+
case "server" | "serve":
|
|
386
|
+
# Check for --open-cxb flag in server command arguments
|
|
387
|
+
open_cxb = False
|
|
388
|
+
if "--open-cxb" in sys.argv:
|
|
389
|
+
open_cxb = True
|
|
390
|
+
sys.argv.remove("--open-cxb")
|
|
391
|
+
|
|
392
|
+
if "--cxb-config" in sys.argv:
|
|
393
|
+
idx = sys.argv.index("--cxb-config")
|
|
394
|
+
if idx + 1 < len(sys.argv):
|
|
395
|
+
os.environ["DMART_CXB_CONFIG"] = sys.argv[idx + 1]
|
|
396
|
+
sys.argv.pop(idx + 1)
|
|
397
|
+
sys.argv.pop(idx)
|
|
398
|
+
|
|
399
|
+
if open_cxb:
|
|
400
|
+
url = f"http://{settings.listening_host}:{settings.listening_port}/cxb/"
|
|
401
|
+
def open_browser():
|
|
402
|
+
time.sleep(2) # Give server a moment to start
|
|
403
|
+
webbrowser.open(url)
|
|
404
|
+
|
|
405
|
+
import threading
|
|
406
|
+
threading.Thread(target=open_browser, daemon=True).start()
|
|
407
|
+
|
|
346
408
|
asyncio.run(server())
|
|
347
409
|
case "health-check":
|
|
348
410
|
parser = argparse.ArgumentParser(
|
main.py
CHANGED
|
@@ -5,6 +5,7 @@ from starlette.datastructures import UploadFile
|
|
|
5
5
|
from contextlib import asynccontextmanager
|
|
6
6
|
import asyncio
|
|
7
7
|
import json
|
|
8
|
+
import os
|
|
8
9
|
from os import getpid
|
|
9
10
|
import sys
|
|
10
11
|
import time
|
|
@@ -24,11 +25,12 @@ from fastapi.logger import logger
|
|
|
24
25
|
from fastapi.encoders import jsonable_encoder
|
|
25
26
|
from fastapi.exceptions import RequestValidationError
|
|
26
27
|
from utils.access_control import access_control
|
|
27
|
-
from fastapi.responses import ORJSONResponse
|
|
28
|
+
from fastapi.responses import ORJSONResponse, FileResponse
|
|
28
29
|
from hypercorn.asyncio import serve
|
|
29
30
|
from hypercorn.config import Config
|
|
30
31
|
from starlette.concurrency import iterate_in_threadpool
|
|
31
32
|
from starlette.exceptions import HTTPException as StarletteHTTPException
|
|
33
|
+
from starlette.staticfiles import StaticFiles
|
|
32
34
|
import models.api as api
|
|
33
35
|
from utils.settings import settings
|
|
34
36
|
from asgi_correlation_id import CorrelationIdMiddleware
|
|
@@ -462,6 +464,51 @@ app.include_router(
|
|
|
462
464
|
# load plugins
|
|
463
465
|
asyncio.run(plugin_manager.load_plugins(app, capture_body))
|
|
464
466
|
|
|
467
|
+
# Serve CXB
|
|
468
|
+
cxb_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "cxb")
|
|
469
|
+
if not os.path.exists(cxb_path):
|
|
470
|
+
# Try relative to project root (development mode)
|
|
471
|
+
project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
472
|
+
cxb_dist_path = os.path.join(project_root, "cxb", "dist", "client")
|
|
473
|
+
if os.path.isdir(cxb_dist_path):
|
|
474
|
+
cxb_path = cxb_dist_path
|
|
475
|
+
|
|
476
|
+
if os.path.isdir(cxb_path):
|
|
477
|
+
@app.get("/cxb/config.json", include_in_schema=False)
|
|
478
|
+
async def get_cxb_config():
|
|
479
|
+
# Priority 0: Explicit path from flag
|
|
480
|
+
cxb_config = os.getenv("DMART_CXB_CONFIG")
|
|
481
|
+
if cxb_config and os.path.exists(cxb_config):
|
|
482
|
+
return FileResponse(cxb_config)
|
|
483
|
+
|
|
484
|
+
# Priority 1: Check in current directory (where dmart is run)
|
|
485
|
+
if os.path.exists("config.json"):
|
|
486
|
+
return FileResponse("config.json")
|
|
487
|
+
|
|
488
|
+
# Priority 2: Check in spaces folder (user directory)
|
|
489
|
+
user_config = settings.spaces_folder / "config.json"
|
|
490
|
+
if user_config.exists():
|
|
491
|
+
return FileResponse(user_config)
|
|
492
|
+
|
|
493
|
+
# Priority 3: Check in bundled CXB directory
|
|
494
|
+
bundled_config = os.path.join(cxb_path, "config.json")
|
|
495
|
+
if os.path.exists(bundled_config):
|
|
496
|
+
return FileResponse(bundled_config)
|
|
497
|
+
|
|
498
|
+
# Fallback to defaults generated from settings
|
|
499
|
+
return {
|
|
500
|
+
"title": "DMART Unified Data Platform",
|
|
501
|
+
"footer": "dmart.cc unified data platform",
|
|
502
|
+
"short_name": "dmart",
|
|
503
|
+
"display_name": "dmart",
|
|
504
|
+
"description": "dmart unified data platform",
|
|
505
|
+
"default_language": "en",
|
|
506
|
+
"languages": { "ar": "العربية", "en": "English" },
|
|
507
|
+
"backend": f"{settings.app_url}" if settings.app_url else f"http://{settings.listening_host}:{settings.listening_port}",
|
|
508
|
+
"websocket": settings.websocket_url if settings.websocket_url else f"ws://{settings.listening_host}:{settings.websocket_port}/ws"
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
app.mount("/cxb", StaticFiles(directory=cxb_path, html=True), name="cxb")
|
|
465
512
|
|
|
466
513
|
@app.options("/{x:path}", include_in_schema=False)
|
|
467
514
|
async def myoptions():
|
|
@@ -503,4 +550,3 @@ if __name__ == "__main__":
|
|
|
503
550
|
asyncio.run(main())
|
|
504
551
|
except Exception as e:
|
|
505
552
|
print("[!1server]", e)
|
|
506
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|