feat: initialize netx ops tool repository

Set up netx as a standalone git-managed project with isolated Python dependencies, alarm ingestion/query APIs, oclaw bridge integration, and ops-focused UI enhancements including history and raw field access.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
oliver 2026-05-03 23:43:21 +08:00
commit f49c0b5bad
56 changed files with 6974 additions and 0 deletions

13
scripts/.run/netx.err.log Normal file
View file

@ -0,0 +1,13 @@
D:\project\chatgpt\netx\netx_api\main.py:112: DeprecationWarning:
on_event is deprecated, use lifespan event handlers instead.
Read more about it in the
[FastAPI docs for Lifespan Events](https://fastapi.tiangolo.com/advanced/events/).
@app.on_event("startup")
INFO: Started server process [24088]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:8890 (Press CTRL+C to quit)
C:\Users\zhout\AppData\Local\Python\pythoncore-3.14-64\Lib\site-packages\openpyxl\styles\stylesheet.py:237: UserWarning: Workbook contains no default style, apply openpyxl's default
warn("Workbook contains no default style, apply openpyxl's default")

206
scripts/.run/netx.out.log Normal file
View file

@ -0,0 +1,206 @@
INFO: 127.0.0.1:53699 - "GET /v1/batches?limit=30 HTTP/1.1" 200 OK
INFO: 127.0.0.1:50679 - "GET /v1/ap/history?batch_id=5077d7cfdf524aed982da687cfe6919e&page=1&page_size=10 HTTP/1.1" 200 OK
INFO: 127.0.0.1:50681 - "GET /v1/batches?limit=30 HTTP/1.1" 200 OK
INFO: 127.0.0.1:50680 - "GET /v1/alarms?batch_id=5077d7cfdf524aed982da687cfe6919e&page=1&page_size=50 HTTP/1.1" 200 OK
INFO: 127.0.0.1:50684 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:50682 - "GET /v1/diagnostics?batch_id=5077d7cfdf524aed982da687cfe6919e HTTP/1.1" 200 OK
INFO: 127.0.0.1:50128 - "GET /v1/ap/history?batch_id=5077d7cfdf524aed982da687cfe6919e&page=1&page_size=10 HTTP/1.1" 200 OK
INFO: 127.0.0.1:50129 - "GET /v1/batches?limit=30 HTTP/1.1" 200 OK
INFO: 127.0.0.1:50133 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:50130 - "GET /v1/alarms?batch_id=5077d7cfdf524aed982da687cfe6919e&page=1&page_size=50 HTTP/1.1" 200 OK
INFO: 127.0.0.1:50131 - "GET /v1/diagnostics?batch_id=5077d7cfdf524aed982da687cfe6919e HTTP/1.1" 200 OK
INFO: 127.0.0.1:50132 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:55903 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:50412 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:63672 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:50959 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:51822 - "DELETE /v1/batches HTTP/1.1" 200 OK
INFO: 127.0.0.1:53625 - "GET /v1/batches?limit=30 HTTP/1.1" 200 OK
INFO: 127.0.0.1:63958 - "GET /v1/diagnostics?batch_id=5077d7cfdf524aed982da687cfe6919e HTTP/1.1" 200 OK
INFO: 127.0.0.1:53087 - "GET /v1/alarms?batch_id=5077d7cfdf524aed982da687cfe6919e&page=1&page_size=50 HTTP/1.1" 200 OK
INFO: 127.0.0.1:56843 - "GET /v1/alarms?batch_id=5077d7cfdf524aed982da687cfe6919e&page=1&page_size=50 HTTP/1.1" 200 OK
INFO: 127.0.0.1:60234 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:52336 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:54662 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:53001 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59095 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:51558 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:61415 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:62982 - "GET /v1/batches?limit=30 HTTP/1.1" 200 OK
INFO: 127.0.0.1:60448 - "GET /v1/alarms?batch_id=5077d7cfdf524aed982da687cfe6919e&page=1&page_size=50 HTTP/1.1" 200 OK
INFO: 127.0.0.1:60449 - "GET /v1/diagnostics?batch_id=5077d7cfdf524aed982da687cfe6919e HTTP/1.1" 200 OK
INFO: 127.0.0.1:60451 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:60450 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:63381 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:57208 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:58447 - "POST /v1/alarms/import HTTP/1.1" 200 OK
INFO: 127.0.0.1:55577 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:56709 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:49805 - "GET /v1/batches?limit=30 HTTP/1.1" 200 OK
INFO: 127.0.0.1:55972 - "GET /v1/alarms?batch_id=5077d7cfdf524aed982da687cfe6919e&page=1&page_size=50 HTTP/1.1" 200 OK
INFO: 127.0.0.1:50230 - "GET /v1/alarms?batch_id=e94cad728d3644ef9e70e54430ff83fb&page=1&page_size=50 HTTP/1.1" 200 OK
INFO: 127.0.0.1:49614 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:56075 - "GET /v1/diagnostics?batch_id=e94cad728d3644ef9e70e54430ff83fb HTTP/1.1" 200 OK
INFO: 127.0.0.1:56138 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:63784 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:56831 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:57035 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:56807 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:58155 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:54924 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59299 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:60141 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:60215 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:49289 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:50308 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:58794 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:50142 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:63565 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:63233 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:55024 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:55403 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:52894 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:52899 - "GET /v1/batches?limit=1 HTTP/1.1" 200 OK
INFO: 127.0.0.1:58471 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:64204 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:56225 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:58654 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:62191 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:53468 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59075 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:61624 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:54981 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:52435 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:52438 - "GET /v1/batches?limit=1 HTTP/1.1" 200 OK
INFO: 127.0.0.1:52439 - "GET /v1/alarms/raw?batch_id=e94cad728d3644ef9e70e54430ff83fb&page=1&page_size=5&order_by=alarm_time&order=desc HTTP/1.1" 200 OK
INFO: 127.0.0.1:52444 - "GET /v1/batches?limit=1 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59220 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:54682 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:55254 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:61399 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:53659 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:61220 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:56157 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:51728 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:64988 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:63206 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:50852 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:63433 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:50333 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:50341 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:57348 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:53773 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:63765 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:53389 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:58475 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:58988 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:64306 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:57293 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:52071 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:60569 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:54060 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:51111 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:50557 - "GET /v1/batches?limit=1 HTTP/1.1" 200 OK
INFO: 127.0.0.1:54845 - "GET /v1/batches?limit=1 HTTP/1.1" 200 OK
INFO: 127.0.0.1:54846 - "GET /v1/alarms/raw?batch_id=e94cad728d3644ef9e70e54430ff83fb&page=1&page_size=5&q=clear&order_by=alarm_time&order=desc HTTP/1.1" 200 OK
INFO: 127.0.0.1:54851 - "GET /v1/batches?limit=1 HTTP/1.1" 200 OK
INFO: 127.0.0.1:54857 - "GET /v1/batches?limit=1 HTTP/1.1" 200 OK
INFO: 127.0.0.1:54858 - "POST /v1/sql/query HTTP/1.1" 200 OK
INFO: 127.0.0.1:54863 - "GET /v1/batches?limit=1 HTTP/1.1" 200 OK
INFO: 127.0.0.1:49581 - "GET /v1/batches?limit=1 HTTP/1.1" 200 OK
INFO: 127.0.0.1:49582 - "POST /v1/sql/query HTTP/1.1" 200 OK
INFO: 127.0.0.1:49587 - "GET /v1/batches?limit=1 HTTP/1.1" 200 OK
INFO: 127.0.0.1:52029 - "GET /v1/batches?limit=1 HTTP/1.1" 200 OK
INFO: 127.0.0.1:52036 - "GET /v1/batches?limit=1 HTTP/1.1" 200 OK
INFO: 127.0.0.1:52037 - "POST /v1/sql/query HTTP/1.1" 200 OK
INFO: 127.0.0.1:52042 - "GET /v1/batches?limit=1 HTTP/1.1" 200 OK
INFO: 127.0.0.1:52057 - "GET /v1/batches?limit=1 HTTP/1.1" 200 OK
INFO: 127.0.0.1:52058 - "POST /v1/sql/query HTTP/1.1" 200 OK
INFO: 127.0.0.1:52063 - "GET /v1/batches?limit=1 HTTP/1.1" 200 OK
INFO: 127.0.0.1:53034 - "GET /v1/batches?limit=30 HTTP/1.1" 200 OK
INFO: 127.0.0.1:58501 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:58502 - "GET /v1/alarms?batch_id=e94cad728d3644ef9e70e54430ff83fb&page=1&page_size=50 HTTP/1.1" 200 OK
INFO: 127.0.0.1:58503 - "GET /v1/diagnostics?batch_id=e94cad728d3644ef9e70e54430ff83fb HTTP/1.1" 200 OK
INFO: 127.0.0.1:57637 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:50493 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:53769 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:50863 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:62531 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:58215 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:52874 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:60083 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:64296 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:52390 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:58255 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:59034 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:58608 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:65151 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:60266 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:64098 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:63464 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:60172 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:55884 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:60837 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:58629 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:57773 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:55154 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:64743 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:53140 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:56479 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:55490 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:59339 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:50152 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:62680 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:50194 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:60458 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:52706 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:65229 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:62670 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:49803 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:59069 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59818 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:61263 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:51707 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:58580 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:52500 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:64450 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:52987 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:60851 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:52434 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:54219 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:63864 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:53415 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:60700 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:62639 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:56854 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:61734 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:63893 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:55580 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:63652 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:65208 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:63377 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:54536 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:60130 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:57014 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:58693 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:53500 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:56458 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:49238 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:53638 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:54711 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59241 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:55133 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:49518 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:62518 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:58671 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:58195 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:60203 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:63966 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:63003 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:57340 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:60285 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:65381 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:54301 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:51225 - "GET /v1/integrations/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:56836 - "GET /v1/jobs?limit=20 HTTP/1.1" 200 OK
INFO: 127.0.0.1:49260 - "GET /v1/integrations/status HTTP/1.1" 200 OK

1
scripts/.run/netx.pid Normal file
View file

@ -0,0 +1 @@
37360

0
scripts/.run/web.err.log Normal file
View file

9
scripts/.run/web.out.log Normal file
View file

@ -0,0 +1,9 @@
> web@0.0.0 dev
> vite --host 127.0.0.1 --port 5173
VITE v8.0.10 ready in 269 ms
➜ Local: http://127.0.0.1:5173/
 ➜ press h + enter to show help

1
scripts/.run/web.pid Normal file
View file

@ -0,0 +1 @@
38188

35
scripts/reset_db.py Normal file
View file

@ -0,0 +1,35 @@
from __future__ import annotations
"""
Dangerous: drop all netx tables and recreate schema.
Usage (PowerShell):
Set-Location D:\\project\\chatgpt\\netx
python scripts\\reset_db.py
It uses NETX_DATABASE_URL (via netx_api.config settings).
"""
import sys
from pathlib import Path
# Ensure `import netx_api` works when executed as a script.
ROOT = Path(__file__).resolve().parents[1]
if str(ROOT) not in sys.path:
sys.path.insert(0, str(ROOT))
import netx_api.models # noqa: F401,E402 # ensure SQLAlchemy models are registered to Base.metadata
from netx_api.db import Base, engine # noqa: E402
def main() -> None:
# Drop all tables first (data loss).
Base.metadata.drop_all(bind=engine)
# Recreate with current models.
Base.metadata.create_all(bind=engine)
print("ok: dropped and recreated all tables")
if __name__ == "__main__":
main()

92
scripts/start_netx.ps1 Normal file
View file

@ -0,0 +1,92 @@
param(
[string]$BindHost = "127.0.0.1",
[int]$Port = 8890,
[int]$WebPort = 5173,
[switch]$SkipInstall = $false,
[switch]$Background = $false,
[switch]$WithWeb = $false
)
$ErrorActionPreference = "Stop"
$projectRoot = Split-Path -Parent $PSScriptRoot
Set-Location $projectRoot
$runDir = Join-Path $PSScriptRoot ".run"
if (-not (Test-Path $runDir)) {
New-Item -ItemType Directory -Path $runDir | Out-Null
}
$pidFile = Join-Path $runDir "netx.pid"
$logFile = Join-Path $runDir "netx.out.log"
$errFile = Join-Path $runDir "netx.err.log"
$webPidFile = Join-Path $runDir "web.pid"
$webLogFile = Join-Path $runDir "web.out.log"
$webErrFile = Join-Path $runDir "web.err.log"
$venvPython = Join-Path $projectRoot ".venv\\Scripts\\python.exe"
$pythonExe = if (Test-Path $venvPython) { $venvPython } else { "python" }
Write-Host "==> Project root: $projectRoot"
Write-Host "==> Using python: $pythonExe"
if (-not $SkipInstall) {
Write-Host "==> Installing dependencies"
& $pythonExe -m pip install -r (Join-Path $projectRoot "requirements.txt")
} else {
Write-Host "==> Skip dependency install"
}
$env:NETX_HOST = $BindHost
$env:NETX_PORT = "$Port"
$baseUrl = "http://$BindHost`:$Port"
$webUrl = "http://$BindHost`:$WebPort"
Write-Host ""
Write-Host "==> netx API URL"
Write-Host "Base: $baseUrl/"
Write-Host "Health: $baseUrl/health"
Write-Host "Integrations: $baseUrl/v1/integrations/status"
if ($WithWeb) {
Write-Host ""
Write-Host "==> netx UI URL"
Write-Host "Vite Dev UI: $webUrl/"
}
Write-Host ""
if ($Background) {
Write-Host "==> Starting netx in background"
$proc = Start-Process -FilePath $pythonExe `
-ArgumentList @("-m", "netx_api.main") `
-WorkingDirectory $projectRoot `
-WindowStyle Hidden `
-RedirectStandardOutput $logFile `
-RedirectStandardError $errFile `
-PassThru
Set-Content -Path $pidFile -Value "$($proc.Id)"
Write-Host "netx.pid = $pidFile"
Write-Host "PID = $($proc.Id)"
Write-Host "Log = $logFile"
Write-Host "Err = $errFile"
if ($WithWeb) {
Write-Host "==> Starting Vite dev server in background"
$webRoot = Join-Path $projectRoot "web"
$webProc = Start-Process -FilePath "npm.cmd" `
-ArgumentList @("run", "dev", "--", "--host", $BindHost, "--port", "$WebPort") `
-WorkingDirectory $webRoot `
-WindowStyle Hidden `
-RedirectStandardOutput $webLogFile `
-RedirectStandardError $webErrFile `
-PassThru
Set-Content -Path $webPidFile -Value "$($webProc.Id)"
Write-Host "web.pid = $webPidFile"
Write-Host "PID = $($webProc.Id)"
Write-Host "Log = $webLogFile"
Write-Host "Err = $webErrFile"
}
exit 0
}
Write-Host "==> Starting netx in foreground"
& $pythonExe -m netx_api.main

76
scripts/stop_netx.ps1 Normal file
View file

@ -0,0 +1,76 @@
param(
[int]$Port = 8890,
[int]$WebPort = 5173,
[switch]$Force = $false
)
$ErrorActionPreference = "Continue"
$runDir = Join-Path $PSScriptRoot ".run"
$pidFile = Join-Path $runDir "netx.pid"
$webPidFile = Join-Path $runDir "web.pid"
Write-Host "==> Stopping netx"
if (Test-Path $pidFile) {
$pidText = (Get-Content -Path $pidFile -ErrorAction SilentlyContinue | Select-Object -First 1)
$procId = 0
[void][int]::TryParse("$pidText", [ref]$procId)
if ($procId -gt 0) {
try {
Stop-Process -Id $procId -Force:$Force -ErrorAction Stop
Write-Host "Stopped PID=$procId"
} catch {
Write-Host "[WARN] PID file process not running: $procId"
}
}
Remove-Item -Path $pidFile -Force -ErrorAction SilentlyContinue
} else {
Write-Host "==> No PID file, try by port $Port"
}
if (Test-Path $webPidFile) {
$webPidText = (Get-Content -Path $webPidFile -ErrorAction SilentlyContinue | Select-Object -First 1)
$webProcId = 0
[void][int]::TryParse("$webPidText", [ref]$webProcId)
if ($webProcId -gt 0) {
try {
Stop-Process -Id $webProcId -Force:$Force -ErrorAction Stop
Write-Host "Stopped web PID=$webProcId"
} catch {
Write-Host "[WARN] web PID file process not running: $webProcId"
}
}
Remove-Item -Path $webPidFile -Force -ErrorAction SilentlyContinue
}
$listeners = Get-NetTCPConnection -LocalPort $Port -State Listen -ErrorAction SilentlyContinue
if ($listeners) {
$owning = $listeners | Select-Object -ExpandProperty OwningProcess -Unique
foreach ($p in $owning) {
try {
Stop-Process -Id $p -Force:$Force -ErrorAction Stop
Write-Host "Stopped by port PID=$p"
} catch {
Write-Host "[WARN] Failed to stop PID=$p by port"
}
}
} else {
Write-Host "[INFO] No listener found on port $Port"
}
$webListeners = Get-NetTCPConnection -LocalPort $WebPort -State Listen -ErrorAction SilentlyContinue
if ($webListeners) {
$webOwning = $webListeners | Select-Object -ExpandProperty OwningProcess -Unique
foreach ($p in $webOwning) {
try {
Stop-Process -Id $p -Force:$Force -ErrorAction Stop
Write-Host "Stopped web by port PID=$p"
} catch {
Write-Host "[WARN] Failed to stop web PID=$p by port"
}
}
} else {
Write-Host "[INFO] No listener found on web port $WebPort"
}