QuLab 2.12.1__tar.gz → 2.12.3__tar.gz

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 (115) hide show
  1. {qulab-2.12.1 → qulab-2.12.3}/PKG-INFO +3 -1
  2. {qulab-2.12.1 → qulab-2.12.3}/QuLab.egg-info/PKG-INFO +3 -1
  3. {qulab-2.12.1 → qulab-2.12.3}/QuLab.egg-info/SOURCES.txt +1 -0
  4. {qulab-2.12.1 → qulab-2.12.3}/QuLab.egg-info/requires.txt +2 -0
  5. {qulab-2.12.1 → qulab-2.12.3}/pyproject.toml +2 -0
  6. {qulab-2.12.1 → qulab-2.12.3}/qulab/cli/config.py +3 -2
  7. qulab-2.12.3/qulab/tools/xlsx.py +81 -0
  8. qulab-2.12.3/qulab/version.py +1 -0
  9. qulab-2.12.1/qulab/version.py +0 -1
  10. {qulab-2.12.1 → qulab-2.12.3}/LICENSE +0 -0
  11. {qulab-2.12.1 → qulab-2.12.3}/MANIFEST.in +0 -0
  12. {qulab-2.12.1 → qulab-2.12.3}/QuLab.egg-info/dependency_links.txt +0 -0
  13. {qulab-2.12.1 → qulab-2.12.3}/QuLab.egg-info/entry_points.txt +0 -0
  14. {qulab-2.12.1 → qulab-2.12.3}/QuLab.egg-info/top_level.txt +0 -0
  15. {qulab-2.12.1 → qulab-2.12.3}/README.md +0 -0
  16. {qulab-2.12.1 → qulab-2.12.3}/qulab/__init__.py +0 -0
  17. {qulab-2.12.1 → qulab-2.12.3}/qulab/__main__.py +0 -0
  18. {qulab-2.12.1 → qulab-2.12.3}/qulab/cli/__init__.py +0 -0
  19. {qulab-2.12.1 → qulab-2.12.3}/qulab/cli/commands.py +0 -0
  20. {qulab-2.12.1 → qulab-2.12.3}/qulab/cli/decorators.py +0 -0
  21. {qulab-2.12.1 → qulab-2.12.3}/qulab/executor/__init__.py +0 -0
  22. {qulab-2.12.1 → qulab-2.12.3}/qulab/executor/analyze.py +0 -0
  23. {qulab-2.12.1 → qulab-2.12.3}/qulab/executor/cli.py +0 -0
  24. {qulab-2.12.1 → qulab-2.12.3}/qulab/executor/load.py +0 -0
  25. {qulab-2.12.1 → qulab-2.12.3}/qulab/executor/registry.py +0 -0
  26. {qulab-2.12.1 → qulab-2.12.3}/qulab/executor/schedule.py +0 -0
  27. {qulab-2.12.1 → qulab-2.12.3}/qulab/executor/storage.py +0 -0
  28. {qulab-2.12.1 → qulab-2.12.3}/qulab/executor/template.py +0 -0
  29. {qulab-2.12.1 → qulab-2.12.3}/qulab/executor/utils.py +0 -0
  30. {qulab-2.12.1 → qulab-2.12.3}/qulab/monitor/__init__.py +0 -0
  31. {qulab-2.12.1 → qulab-2.12.3}/qulab/monitor/__main__.py +0 -0
  32. {qulab-2.12.1 → qulab-2.12.3}/qulab/monitor/config.py +0 -0
  33. {qulab-2.12.1 → qulab-2.12.3}/qulab/monitor/dataset.py +0 -0
  34. {qulab-2.12.1 → qulab-2.12.3}/qulab/monitor/event_queue.py +0 -0
  35. {qulab-2.12.1 → qulab-2.12.3}/qulab/monitor/mainwindow.py +0 -0
  36. {qulab-2.12.1 → qulab-2.12.3}/qulab/monitor/monitor.py +0 -0
  37. {qulab-2.12.1 → qulab-2.12.3}/qulab/monitor/ploter.py +0 -0
  38. {qulab-2.12.1 → qulab-2.12.3}/qulab/monitor/qt_compat.py +0 -0
  39. {qulab-2.12.1 → qulab-2.12.3}/qulab/monitor/toolbar.py +0 -0
  40. {qulab-2.12.1 → qulab-2.12.3}/qulab/scan/__init__.py +0 -0
  41. {qulab-2.12.1 → qulab-2.12.3}/qulab/scan/curd.py +0 -0
  42. {qulab-2.12.1 → qulab-2.12.3}/qulab/scan/models.py +0 -0
  43. {qulab-2.12.1 → qulab-2.12.3}/qulab/scan/optimize.py +0 -0
  44. {qulab-2.12.1 → qulab-2.12.3}/qulab/scan/query.py +0 -0
  45. {qulab-2.12.1 → qulab-2.12.3}/qulab/scan/record.py +0 -0
  46. {qulab-2.12.1 → qulab-2.12.3}/qulab/scan/scan.py +0 -0
  47. {qulab-2.12.1 → qulab-2.12.3}/qulab/scan/server.py +0 -0
  48. {qulab-2.12.1 → qulab-2.12.3}/qulab/scan/space.py +0 -0
  49. {qulab-2.12.1 → qulab-2.12.3}/qulab/scan/utils.py +0 -0
  50. {qulab-2.12.1 → qulab-2.12.3}/qulab/storage/__init__.py +0 -0
  51. {qulab-2.12.1 → qulab-2.12.3}/qulab/storage/__main__.py +0 -0
  52. {qulab-2.12.1 → qulab-2.12.3}/qulab/storage/backend/__init__.py +0 -0
  53. {qulab-2.12.1 → qulab-2.12.3}/qulab/storage/backend/redis.py +0 -0
  54. {qulab-2.12.1 → qulab-2.12.3}/qulab/storage/base_dataset.py +0 -0
  55. {qulab-2.12.1 → qulab-2.12.3}/qulab/storage/chunk.py +0 -0
  56. {qulab-2.12.1 → qulab-2.12.3}/qulab/storage/dataset.py +0 -0
  57. {qulab-2.12.1 → qulab-2.12.3}/qulab/storage/file.py +0 -0
  58. {qulab-2.12.1 → qulab-2.12.3}/qulab/storage/models/__init__.py +0 -0
  59. {qulab-2.12.1 → qulab-2.12.3}/qulab/storage/models/base.py +0 -0
  60. {qulab-2.12.1 → qulab-2.12.3}/qulab/storage/models/config.py +0 -0
  61. {qulab-2.12.1 → qulab-2.12.3}/qulab/storage/models/file.py +0 -0
  62. {qulab-2.12.1 → qulab-2.12.3}/qulab/storage/models/ipy.py +0 -0
  63. {qulab-2.12.1 → qulab-2.12.3}/qulab/storage/models/models.py +0 -0
  64. {qulab-2.12.1 → qulab-2.12.3}/qulab/storage/models/record.py +0 -0
  65. {qulab-2.12.1 → qulab-2.12.3}/qulab/storage/models/report.py +0 -0
  66. {qulab-2.12.1 → qulab-2.12.3}/qulab/storage/models/tag.py +0 -0
  67. {qulab-2.12.1 → qulab-2.12.3}/qulab/storage/storage.py +0 -0
  68. {qulab-2.12.1 → qulab-2.12.3}/qulab/sys/__init__.py +0 -0
  69. {qulab-2.12.1 → qulab-2.12.3}/qulab/sys/chat.py +0 -0
  70. {qulab-2.12.1 → qulab-2.12.3}/qulab/sys/device/__init__.py +0 -0
  71. {qulab-2.12.1 → qulab-2.12.3}/qulab/sys/device/basedevice.py +0 -0
  72. {qulab-2.12.1 → qulab-2.12.3}/qulab/sys/device/loader.py +0 -0
  73. {qulab-2.12.1 → qulab-2.12.3}/qulab/sys/device/utils.py +0 -0
  74. {qulab-2.12.1 → qulab-2.12.3}/qulab/sys/drivers/FakeInstrument.py +0 -0
  75. {qulab-2.12.1 → qulab-2.12.3}/qulab/sys/drivers/__init__.py +0 -0
  76. {qulab-2.12.1 → qulab-2.12.3}/qulab/sys/ipy_events.py +0 -0
  77. {qulab-2.12.1 → qulab-2.12.3}/qulab/sys/net/__init__.py +0 -0
  78. {qulab-2.12.1 → qulab-2.12.3}/qulab/sys/net/bencoder.py +0 -0
  79. {qulab-2.12.1 → qulab-2.12.3}/qulab/sys/net/cli.py +0 -0
  80. {qulab-2.12.1 → qulab-2.12.3}/qulab/sys/net/dhcp.py +0 -0
  81. {qulab-2.12.1 → qulab-2.12.3}/qulab/sys/net/dhcpd.py +0 -0
  82. {qulab-2.12.1 → qulab-2.12.3}/qulab/sys/net/kad.py +0 -0
  83. {qulab-2.12.1 → qulab-2.12.3}/qulab/sys/net/kcp.py +0 -0
  84. {qulab-2.12.1 → qulab-2.12.3}/qulab/sys/net/nginx.py +0 -0
  85. {qulab-2.12.1 → qulab-2.12.3}/qulab/sys/progress.py +0 -0
  86. {qulab-2.12.1 → qulab-2.12.3}/qulab/sys/rpc/__init__.py +0 -0
  87. {qulab-2.12.1 → qulab-2.12.3}/qulab/sys/rpc/client.py +0 -0
  88. {qulab-2.12.1 → qulab-2.12.3}/qulab/sys/rpc/exceptions.py +0 -0
  89. {qulab-2.12.1 → qulab-2.12.3}/qulab/sys/rpc/msgpack.py +0 -0
  90. {qulab-2.12.1 → qulab-2.12.3}/qulab/sys/rpc/msgpack.pyi +0 -0
  91. {qulab-2.12.1 → qulab-2.12.3}/qulab/sys/rpc/router.py +0 -0
  92. {qulab-2.12.1 → qulab-2.12.3}/qulab/sys/rpc/rpc.py +0 -0
  93. {qulab-2.12.1 → qulab-2.12.3}/qulab/sys/rpc/serialize.py +0 -0
  94. {qulab-2.12.1 → qulab-2.12.3}/qulab/sys/rpc/server.py +0 -0
  95. {qulab-2.12.1 → qulab-2.12.3}/qulab/sys/rpc/socket.py +0 -0
  96. {qulab-2.12.1 → qulab-2.12.3}/qulab/sys/rpc/utils.py +0 -0
  97. {qulab-2.12.1 → qulab-2.12.3}/qulab/sys/rpc/worker.py +0 -0
  98. {qulab-2.12.1 → qulab-2.12.3}/qulab/sys/rpc/zmq_socket.py +0 -0
  99. {qulab-2.12.1 → qulab-2.12.3}/qulab/tools/__init__.py +0 -0
  100. {qulab-2.12.1 → qulab-2.12.3}/qulab/tools/connection_helper.py +0 -0
  101. {qulab-2.12.1 → qulab-2.12.3}/qulab/typing.py +0 -0
  102. {qulab-2.12.1 → qulab-2.12.3}/qulab/utils.py +0 -0
  103. {qulab-2.12.1 → qulab-2.12.3}/qulab/visualization/__init__.py +0 -0
  104. {qulab-2.12.1 → qulab-2.12.3}/qulab/visualization/__main__.py +0 -0
  105. {qulab-2.12.1 → qulab-2.12.3}/qulab/visualization/_autoplot.py +0 -0
  106. {qulab-2.12.1 → qulab-2.12.3}/qulab/visualization/plot_circ.py +0 -0
  107. {qulab-2.12.1 → qulab-2.12.3}/qulab/visualization/plot_layout.py +0 -0
  108. {qulab-2.12.1 → qulab-2.12.3}/qulab/visualization/plot_seq.py +0 -0
  109. {qulab-2.12.1 → qulab-2.12.3}/qulab/visualization/qdat.py +0 -0
  110. {qulab-2.12.1 → qulab-2.12.3}/qulab/visualization/rot3d.py +0 -0
  111. {qulab-2.12.1 → qulab-2.12.3}/qulab/visualization/widgets.py +0 -0
  112. {qulab-2.12.1 → qulab-2.12.3}/setup.cfg +0 -0
  113. {qulab-2.12.1 → qulab-2.12.3}/setup.py +0 -0
  114. {qulab-2.12.1 → qulab-2.12.3}/src/qulab.h +0 -0
  115. {qulab-2.12.1 → qulab-2.12.3}/tests/test_scan.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: QuLab
3
- Version: 2.12.1
3
+ Version: 2.12.3
4
4
  Summary: contral instruments and manage data
5
5
  Author-email: feihoo87 <feihoo87@gmail.com>
6
6
  Maintainer-email: feihoo87 <feihoo87@gmail.com>
@@ -48,6 +48,8 @@ Requires-Dist: watchdog>=4.0.0
48
48
  Requires-Dist: wath>=1.1.6
49
49
  Requires-Dist: waveforms>=1.9.4
50
50
  Requires-Dist: rich>=14.0.0
51
+ Requires-Dist: pydantic>=2.12.5
52
+ Requires-Dist: openpyxl>=3.1.5
51
53
  Provides-Extra: full
52
54
  Requires-Dist: paramiko>=3.5.1; extra == "full"
53
55
  Requires-Dist: uvloop>=0.19.0; extra == "full"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: QuLab
3
- Version: 2.12.1
3
+ Version: 2.12.3
4
4
  Summary: contral instruments and manage data
5
5
  Author-email: feihoo87 <feihoo87@gmail.com>
6
6
  Maintainer-email: feihoo87 <feihoo87@gmail.com>
@@ -48,6 +48,8 @@ Requires-Dist: watchdog>=4.0.0
48
48
  Requires-Dist: wath>=1.1.6
49
49
  Requires-Dist: waveforms>=1.9.4
50
50
  Requires-Dist: rich>=14.0.0
51
+ Requires-Dist: pydantic>=2.12.5
52
+ Requires-Dist: openpyxl>=3.1.5
51
53
  Provides-Extra: full
52
54
  Requires-Dist: paramiko>=3.5.1; extra == "full"
53
55
  Requires-Dist: uvloop>=0.19.0; extra == "full"
@@ -98,6 +98,7 @@ qulab/sys/rpc/worker.py
98
98
  qulab/sys/rpc/zmq_socket.py
99
99
  qulab/tools/__init__.py
100
100
  qulab/tools/connection_helper.py
101
+ qulab/tools/xlsx.py
101
102
  qulab/visualization/__init__.py
102
103
  qulab/visualization/__main__.py
103
104
  qulab/visualization/_autoplot.py
@@ -22,6 +22,8 @@ watchdog>=4.0.0
22
22
  wath>=1.1.6
23
23
  waveforms>=1.9.4
24
24
  rich>=14.0.0
25
+ pydantic>=2.12.5
26
+ openpyxl>=3.1.5
25
27
 
26
28
  [full]
27
29
  paramiko>=3.5.1
@@ -52,6 +52,8 @@ dependencies = [
52
52
  "wath>=1.1.6",
53
53
  "waveforms>=1.9.4",
54
54
  "rich>=14.0.0",
55
+ "pydantic>=2.12.5",
56
+ "openpyxl>=3.1.5",
55
57
  ]
56
58
  dynamic = ["version"]
57
59
 
@@ -17,7 +17,7 @@ def find_config_file() -> Path | None:
17
17
  查找配置文件
18
18
  """
19
19
  # 环境变量
20
- if config_path := os.getenv("QULAB_CONFIG_PATH"):
20
+ if config_path := os.getenv(f"{ENV_PREFIX}CONFIG_PATH"):
21
21
  return Path(config_path)
22
22
 
23
23
  # 先查找当前目录下的配置文件
@@ -29,7 +29,8 @@ def find_config_file() -> Path | None:
29
29
  current_dir = Path.cwd()
30
30
  while not (current_dir / "uv.lock").exists():
31
31
  current_dir = current_dir.parent
32
- if current_dir == Path("/"):
32
+ # 到达文件系统根目录,停止
33
+ if current_dir == current_dir.parent:
33
34
  break
34
35
  config_path = current_dir / "qulab.ini"
35
36
  if config_path.exists():
@@ -0,0 +1,81 @@
1
+ from openpyxl import load_workbook
2
+
3
+
4
+ def read_excel_to_dict(path: str) -> dict[str, list[dict[str, str]]]:
5
+ wb = load_workbook(path, read_only=True, data_only=True)
6
+ result = {}
7
+
8
+ for ws in wb.worksheets:
9
+ sheet_data = []
10
+
11
+ rows = list(ws.iter_rows(values_only=True))
12
+
13
+ if not rows:
14
+ result[ws.title] = []
15
+ continue
16
+
17
+ header_row = rows[0]
18
+
19
+ # 过滤掉空列名
20
+ valid_indices = [
21
+ idx for idx, col in enumerate(header_row)
22
+ if col is not None and str(col).strip() != ""
23
+ ]
24
+
25
+ headers = [str(header_row[i]).strip() for i in valid_indices]
26
+
27
+ # 读取数据行
28
+ for row in rows[1:]:
29
+ row_dict = {}
30
+ for col_idx, header in zip(valid_indices, headers):
31
+ value = row[col_idx] if col_idx < len(row) else None
32
+ row_dict[header] = "" if value is None else str(value)
33
+ sheet_data.append(row_dict)
34
+
35
+ result[ws.title] = sheet_data
36
+
37
+ wb.close()
38
+ return result
39
+
40
+
41
+ def update_cells(path: str, sheet_name: str, updates: dict[str, str]):
42
+ """
43
+ updates 示例:
44
+ {
45
+ "A2": "新内容",
46
+ "C5": "修改值",
47
+ }
48
+ """
49
+
50
+ wb = load_workbook(path, keep_vba=True)
51
+ ws = wb[sheet_name]
52
+
53
+ for cell_addr, new_value in updates.items():
54
+ ws[cell_addr].value = new_value # 只改 value
55
+
56
+ wb.save(path)
57
+ wb.close()
58
+
59
+
60
+ def update_by_key(path, sheet_name, key_col, key_value, target_col, new_value):
61
+ """
62
+ 找到 key_col 的值为 key_value 的行,将该行 target_col 的值改为 new_value
63
+ key_col 和 target_col 都是列名
64
+ """
65
+ wb = load_workbook(path, keep_vba=True)
66
+ ws = wb[sheet_name]
67
+
68
+ # 找列号
69
+ header = [cell.value for cell in ws[1]]
70
+
71
+ key_idx = header.index(key_col) + 1
72
+ target_idx = header.index(target_col) + 1
73
+
74
+ for row in ws.iter_rows(min_row=2):
75
+ # 找到对应的行
76
+ if row[key_idx - 1].value == key_value:
77
+ ws.cell(row=row[0].row, column=target_idx).value = new_value
78
+ break
79
+
80
+ wb.save(path)
81
+ wb.close()
@@ -0,0 +1 @@
1
+ __version__ = "2.12.3"
@@ -1 +0,0 @@
1
- __version__ = "2.12.1"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes