QuLab 2.10.10__cp313-cp313-macosx_10_13_universal2.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 (107) hide show
  1. qulab/__init__.py +33 -0
  2. qulab/__main__.py +4 -0
  3. qulab/cli/__init__.py +0 -0
  4. qulab/cli/commands.py +30 -0
  5. qulab/cli/config.py +170 -0
  6. qulab/cli/decorators.py +28 -0
  7. qulab/dicttree.py +523 -0
  8. qulab/executor/__init__.py +5 -0
  9. qulab/executor/analyze.py +188 -0
  10. qulab/executor/cli.py +434 -0
  11. qulab/executor/load.py +563 -0
  12. qulab/executor/registry.py +185 -0
  13. qulab/executor/schedule.py +543 -0
  14. qulab/executor/storage.py +615 -0
  15. qulab/executor/template.py +259 -0
  16. qulab/executor/utils.py +194 -0
  17. qulab/expression.py +827 -0
  18. qulab/fun.cpython-313-darwin.so +0 -0
  19. qulab/monitor/__init__.py +1 -0
  20. qulab/monitor/__main__.py +8 -0
  21. qulab/monitor/config.py +41 -0
  22. qulab/monitor/dataset.py +77 -0
  23. qulab/monitor/event_queue.py +54 -0
  24. qulab/monitor/mainwindow.py +234 -0
  25. qulab/monitor/monitor.py +115 -0
  26. qulab/monitor/ploter.py +123 -0
  27. qulab/monitor/qt_compat.py +16 -0
  28. qulab/monitor/toolbar.py +265 -0
  29. qulab/scan/__init__.py +2 -0
  30. qulab/scan/curd.py +221 -0
  31. qulab/scan/models.py +554 -0
  32. qulab/scan/optimize.py +76 -0
  33. qulab/scan/query.py +387 -0
  34. qulab/scan/record.py +603 -0
  35. qulab/scan/scan.py +1166 -0
  36. qulab/scan/server.py +450 -0
  37. qulab/scan/space.py +213 -0
  38. qulab/scan/utils.py +234 -0
  39. qulab/storage/__init__.py +0 -0
  40. qulab/storage/__main__.py +51 -0
  41. qulab/storage/backend/__init__.py +0 -0
  42. qulab/storage/backend/redis.py +204 -0
  43. qulab/storage/base_dataset.py +352 -0
  44. qulab/storage/chunk.py +60 -0
  45. qulab/storage/dataset.py +127 -0
  46. qulab/storage/file.py +273 -0
  47. qulab/storage/models/__init__.py +22 -0
  48. qulab/storage/models/base.py +4 -0
  49. qulab/storage/models/config.py +28 -0
  50. qulab/storage/models/file.py +89 -0
  51. qulab/storage/models/ipy.py +58 -0
  52. qulab/storage/models/models.py +88 -0
  53. qulab/storage/models/record.py +161 -0
  54. qulab/storage/models/report.py +22 -0
  55. qulab/storage/models/tag.py +93 -0
  56. qulab/storage/storage.py +95 -0
  57. qulab/sys/__init__.py +2 -0
  58. qulab/sys/chat.py +688 -0
  59. qulab/sys/device/__init__.py +3 -0
  60. qulab/sys/device/basedevice.py +255 -0
  61. qulab/sys/device/loader.py +86 -0
  62. qulab/sys/device/utils.py +79 -0
  63. qulab/sys/drivers/FakeInstrument.py +68 -0
  64. qulab/sys/drivers/__init__.py +0 -0
  65. qulab/sys/ipy_events.py +125 -0
  66. qulab/sys/net/__init__.py +0 -0
  67. qulab/sys/net/bencoder.py +205 -0
  68. qulab/sys/net/cli.py +169 -0
  69. qulab/sys/net/dhcp.py +543 -0
  70. qulab/sys/net/dhcpd.py +176 -0
  71. qulab/sys/net/kad.py +1142 -0
  72. qulab/sys/net/kcp.py +192 -0
  73. qulab/sys/net/nginx.py +194 -0
  74. qulab/sys/progress.py +190 -0
  75. qulab/sys/rpc/__init__.py +0 -0
  76. qulab/sys/rpc/client.py +0 -0
  77. qulab/sys/rpc/exceptions.py +96 -0
  78. qulab/sys/rpc/msgpack.py +1052 -0
  79. qulab/sys/rpc/msgpack.pyi +41 -0
  80. qulab/sys/rpc/router.py +35 -0
  81. qulab/sys/rpc/rpc.py +412 -0
  82. qulab/sys/rpc/serialize.py +139 -0
  83. qulab/sys/rpc/server.py +29 -0
  84. qulab/sys/rpc/socket.py +29 -0
  85. qulab/sys/rpc/utils.py +25 -0
  86. qulab/sys/rpc/worker.py +0 -0
  87. qulab/sys/rpc/zmq_socket.py +227 -0
  88. qulab/tools/__init__.py +0 -0
  89. qulab/tools/connection_helper.py +39 -0
  90. qulab/typing.py +2 -0
  91. qulab/utils.py +95 -0
  92. qulab/version.py +1 -0
  93. qulab/visualization/__init__.py +188 -0
  94. qulab/visualization/__main__.py +71 -0
  95. qulab/visualization/_autoplot.py +464 -0
  96. qulab/visualization/plot_circ.py +319 -0
  97. qulab/visualization/plot_layout.py +408 -0
  98. qulab/visualization/plot_seq.py +242 -0
  99. qulab/visualization/qdat.py +152 -0
  100. qulab/visualization/rot3d.py +23 -0
  101. qulab/visualization/widgets.py +86 -0
  102. qulab-2.10.10.dist-info/METADATA +110 -0
  103. qulab-2.10.10.dist-info/RECORD +107 -0
  104. qulab-2.10.10.dist-info/WHEEL +5 -0
  105. qulab-2.10.10.dist-info/entry_points.txt +2 -0
  106. qulab-2.10.10.dist-info/licenses/LICENSE +21 -0
  107. qulab-2.10.10.dist-info/top_level.txt +1 -0
@@ -0,0 +1,205 @@
1
+ """
2
+ This module provides a simple bencoding implementation in pure Python.
3
+ Bencoding is a way to specify and organize data in a terse format. It supports
4
+ the following types: byte strings, integers, lists, and dictionaries.
5
+
6
+ Classes:
7
+ Bencached: A class that holds bencoded data.
8
+
9
+ Functions:
10
+ encode_bencached(x, fp): Encodes a Bencached object.
11
+ encode_int(x, fp): Encodes an integer.
12
+ encode_bool(x, fp): Encodes a boolean.
13
+ encode_string(x, fp): Encodes a string.
14
+ encode_list(x, fp): Encodes a list.
15
+ encode_dict(x, fp): Encodes a dictionary.
16
+ decode_int(x, ptr): Decodes a bencoded integer.
17
+ decode_string(x, ptr): Decodes a bencoded string.
18
+ decode_list(x, ptr): Decodes a bencoded list.
19
+ decode_dict(x, ptr): Decodes a bencoded dictionary.
20
+ encode(obj, fp): Encodes an object.
21
+ encodes(obj): Encodes an object and returns the bencoded bytes.
22
+ decode(fp): Decodes a file-like object.
23
+ decodes(s): Decodes a bencoded bytes object.
24
+ dump = encode: Alias for encode function.
25
+ load = decodes: Alias for decode function.
26
+ dumps = encodes: Alias for encodes function.
27
+ loads = decodes: Alias for decodes function.
28
+
29
+ Examples:
30
+ >>> encode(42) == b'i42e'
31
+ True
32
+ >>> decode(b'i42e')
33
+ 42
34
+ """
35
+ import io
36
+
37
+
38
+ class Bencached():
39
+
40
+ __slots__ = ['bencoded']
41
+
42
+ def __init__(self, s):
43
+ self.bencoded = s
44
+
45
+
46
+ def encode_bencached(x, fp):
47
+ fp.write(x.bencoded)
48
+
49
+
50
+ def encode_int(x, fp):
51
+ fp.write(f"i{x}e".encode())
52
+
53
+
54
+ def encode_bool(x, fp):
55
+ if x:
56
+ encode_int(1, fp)
57
+ else:
58
+ encode_int(0, fp)
59
+
60
+
61
+ def encode_string(x, fp):
62
+ if isinstance(x, str):
63
+ x = x.encode()
64
+ fp.write(f"{len(x):d}:".encode())
65
+ fp.write(x)
66
+
67
+
68
+ def encode_list(x, fp):
69
+ fp.write(b'l')
70
+ for i in x:
71
+ encode_func[type(i)](i, fp)
72
+ fp.write(b'e')
73
+
74
+
75
+ def encode_dict(x, fp):
76
+ fp.write(b'd')
77
+ for k, v in sorted(x.items()):
78
+ if isinstance(k, str):
79
+ k = k.encode()
80
+ fp.write(f"{len(k):d}:".encode())
81
+ fp.write(k)
82
+ encode_func[type(v)](v, fp)
83
+ fp.write(b'e')
84
+
85
+
86
+ encode_func = {
87
+ Bencached: encode_bencached,
88
+ int: encode_int,
89
+ str: encode_string,
90
+ bytes: encode_string,
91
+ list: encode_list,
92
+ tuple: encode_list,
93
+ dict: encode_dict,
94
+ bool: encode_bool
95
+ }
96
+
97
+
98
+ def decode_int(x, ptr):
99
+ ptr += 1
100
+ end = x.index(b'e', ptr)
101
+ if x[ptr] == b'-'[0]:
102
+ if x[ptr + 1] == b'0'[0]:
103
+ raise ValueError
104
+ elif x[ptr] == b'0'[0] and end != ptr + 1:
105
+ raise ValueError
106
+ n = int(x[ptr:end])
107
+ return n, end + 1
108
+
109
+
110
+ def decode_string(x, ptr):
111
+ colon = x.index(b':', ptr)
112
+ n = int(x[ptr:colon])
113
+ if x[ptr] == b'0'[0] and colon != ptr + 1:
114
+ raise ValueError
115
+ colon += 1
116
+ return x[colon:colon + n], colon + n
117
+
118
+
119
+ def decode_list(x, ptr):
120
+ r, ptr = [], ptr + 1
121
+ while x[ptr] != b'e'[0]:
122
+ v, ptr = decode_func[x[ptr]](x, ptr)
123
+ r.append(v)
124
+ return r, ptr + 1
125
+
126
+
127
+ def decode_dict(x, ptr):
128
+ r, ptr = {}, ptr + 1
129
+ while x[ptr] != b'e'[0]:
130
+ k, ptr = decode_string(x, ptr)
131
+ if isinstance(k, bytes):
132
+ k = k.decode()
133
+ r[k], ptr = decode_func[x[ptr]](x, ptr)
134
+ return r, ptr + 1
135
+
136
+
137
+ decode_func = {b'l'[0]: decode_list, b'd'[0]: decode_dict, b'i'[0]: decode_int}
138
+
139
+ for i in range(10):
140
+ decode_func[f"{i}".encode()[0]] = decode_string
141
+
142
+
143
+ def encode(obj, fp):
144
+ try:
145
+ encode_func[type(obj)](obj, fp)
146
+ except KeyError:
147
+ raise ValueError("Allowed types: int, bytes, list, dict; not %s",
148
+ type(obj))
149
+
150
+
151
+ def encodes(obj):
152
+ """
153
+ bencodes given object. Given object should be a int,
154
+ bytes, list or dict. If a str is given, it'll be
155
+ encoded as ASCII.
156
+ >>> [encode(i) for i in (-2, 42, b"answer", b"")] \
157
+ == [b'i-2e', b'i42e', b'6:answer', b'0:']
158
+ True
159
+ >>> encode([b'a', 42, [13, 14]]) == b'l1:ai42eli13ei14eee'
160
+ True
161
+ >>> encode({'bar': b'spam', 'foo': 42, 'mess': [1, b'c']}) \
162
+ == b'd3:bar4:spam3:fooi42e4:messli1e1:cee'
163
+ True
164
+ """
165
+ buff = io.BytesIO()
166
+ encode(obj, buff)
167
+ return buff.getvalue()
168
+
169
+
170
+ def decodes(s):
171
+ """
172
+ Decodes given bencoded bytes object.
173
+ >>> decode(b'i-42e')
174
+ -42
175
+ >>> decode(b'4:utku') == b'utku'
176
+ True
177
+ >>> decode(b'li1eli2eli3eeee')
178
+ [1, [2, [3]]]
179
+ >>> decode(b'd3:bar4:spam3:fooi42ee') == {'bar': b'spam', 'foo': 42}
180
+ True
181
+ """
182
+ if isinstance(s, str):
183
+ s = s.encode()
184
+ try:
185
+ r, l = decode_func[s[0]](s, 0)
186
+ except (IndexError, KeyError, ValueError):
187
+ raise ValueError("not a valid bencoded string")
188
+ if l != len(s):
189
+ raise ValueError("invalid bencoded value (data after valid prefix)")
190
+ return r
191
+
192
+
193
+ def decode(fp):
194
+ """
195
+ Decodes given file-like object.
196
+ """
197
+ return decodes(fp.read())
198
+
199
+
200
+ dump = encode
201
+ load = decodes
202
+ dumps = encodes
203
+ loads = decodes
204
+
205
+ __all__ = ['decodes', 'encodes', 'dump', 'load', 'dumps', 'loads']
qulab/sys/net/cli.py ADDED
@@ -0,0 +1,169 @@
1
+ import asyncio
2
+ import pathlib
3
+ import pickle
4
+
5
+ import click
6
+
7
+ from .kad import Server
8
+
9
+
10
+ async def client_get(key, server, port, timeout=5):
11
+ reader, writer = await asyncio.wait_for(asyncio.open_connection(
12
+ server, port),
13
+ timeout=timeout)
14
+ writer.write(pickle.dumps(('get', key)))
15
+ await asyncio.wait_for(writer.drain(), timeout=timeout)
16
+ data = await asyncio.wait_for(reader.read(1600), timeout=timeout)
17
+ value = pickle.loads(data)
18
+ writer.close()
19
+ await writer.wait_closed()
20
+ return value
21
+
22
+
23
+ async def client_set(key, value, server, port, timeout=5):
24
+ reader, writer = await asyncio.wait_for(asyncio.open_connection(
25
+ server, port),
26
+ timeout=timeout)
27
+ writer.write(pickle.dumps(('set', key, value)))
28
+ await asyncio.wait_for(writer.drain(), timeout=timeout)
29
+ writer.close()
30
+ await writer.wait_closed()
31
+
32
+
33
+ async def client_bootstrap(address, server, port, timeout=5):
34
+ reader, writer = await asyncio.wait_for(asyncio.open_connection(
35
+ server, port),
36
+ timeout=timeout)
37
+ addr, p = address.split(':')
38
+ writer.write(pickle.dumps(('bootstrap', (addr, int(p)))))
39
+ await asyncio.wait_for(writer.drain(), timeout=timeout)
40
+ writer.close()
41
+ await writer.wait_closed()
42
+
43
+
44
+ @click.group()
45
+ def dht():
46
+ pass
47
+
48
+
49
+ @dht.command()
50
+ @click.option('--interface',
51
+ default='127.0.0.1',
52
+ help='Interface to listen on')
53
+ @click.option('--port', default=8467, help='Port to listen on')
54
+ @click.option('--dht-only', default=False, is_flag=True, help='DHT only')
55
+ @click.option('--dht-interface',
56
+ default='0.0.0.0',
57
+ help='DHT interface to listen on')
58
+ @click.option('--dht-port', default=8468, help='DHT port to listen on')
59
+ @click.option('--bootstrap', default=None, help='Address of bootstrap node')
60
+ @click.option('--interval', default=300, help='Refresh interval')
61
+ @click.option('--state-file', default=None, help='State file')
62
+ def server(interface, port, dht_only, dht_interface, dht_port, bootstrap,
63
+ interval, state_file):
64
+
65
+ async def main(interface, port, dht_only, dht_interface, dht_port,
66
+ bootstrap, state_file):
67
+
68
+ if state_file is None:
69
+ state_file = pathlib.Path.home() / '.waveforms' / 'dht.pickle'
70
+ else:
71
+ state_file = pathlib.Path(state_file)
72
+
73
+ if state_file.exists():
74
+ node = await Server.load_state(state_file, dht_port, dht_interface,
75
+ interval)
76
+ else:
77
+ node = Server()
78
+ state_file.parent.mkdir(parents=True, exist_ok=True)
79
+ await node.listen(dht_port, dht_interface, interval)
80
+ if bootstrap:
81
+ addr, p = bootstrap.split(':')
82
+ await node.bootstrap([(addr, int(p))])
83
+
84
+ loop = asyncio.get_running_loop()
85
+ loop.call_later(min(interval / 2, 30), node.save_state_regularly,
86
+ state_file, interval)
87
+
88
+ async def handle_cmds(reader, writer):
89
+ data = await reader.read(1600)
90
+ cmd, *args = pickle.loads(data)
91
+ match cmd:
92
+ case 'get':
93
+ value = await node.get(*args)
94
+ data = pickle.dumps(value)
95
+ case 'set':
96
+ value = await node.set(*args)
97
+ data = pickle.dumps(value)
98
+ case 'ping':
99
+ data = pickle.dumps(node.node.id)
100
+ case 'bootstrap':
101
+ await node.bootstrap(args)
102
+ data = pickle.dumps(None)
103
+ case _:
104
+ data = pickle.dumps(None)
105
+
106
+ writer.write(data)
107
+ await writer.drain()
108
+ writer.close()
109
+ await writer.wait_closed()
110
+
111
+ if dht_only:
112
+ try:
113
+ while True:
114
+ await asyncio.sleep(1)
115
+ except asyncio.CancelledError:
116
+ pass
117
+ else:
118
+ server = await asyncio.start_server(handle_cmds, interface, port)
119
+
120
+ async with server:
121
+ try:
122
+ await server.serve_forever()
123
+ except asyncio.CancelledError:
124
+ pass
125
+
126
+ asyncio.run(
127
+ main(interface, port, dht_only, dht_interface, dht_port, bootstrap,
128
+ state_file))
129
+
130
+
131
+ @dht.command('get')
132
+ @click.argument('key')
133
+ @click.option('--server', default='127.0.0.1', help='Server to connect to')
134
+ @click.option('--port', default=8467, help='Port to connect to')
135
+ @click.option('--timeout', default=5, help='Timeout')
136
+ def get(key, server, port, timeout):
137
+
138
+ async def client():
139
+ value = await client_get(key, server, port, timeout)
140
+ print(value)
141
+
142
+ asyncio.run(client())
143
+
144
+
145
+ @dht.command('set')
146
+ @click.argument('key')
147
+ @click.argument('value')
148
+ @click.option('--server', default='127.0.0.1', help='Server to connect to')
149
+ @click.option('--port', default=8467, help='Port to connect to')
150
+ @click.option('--timeout', default=5, help='Timeout')
151
+ def set_(key, value, server, port, timeout):
152
+
153
+ async def client():
154
+ await client_set(key, value, server, port, timeout)
155
+
156
+ asyncio.run(client())
157
+
158
+
159
+ @dht.command('bootstrap')
160
+ @click.argument('address')
161
+ @click.option('--server', default='127.0.0.1', help='Server to connect to')
162
+ @click.option('--port', default=8467, help='Port to connect to')
163
+ @click.option('--timeout', default=5, help='Timeout')
164
+ def bootstrap(address, server, port, timeout):
165
+
166
+ async def client():
167
+ await client_bootstrap(address, server, port, timeout)
168
+
169
+ asyncio.run(client())