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.
- qulab/__init__.py +33 -0
- qulab/__main__.py +4 -0
- qulab/cli/__init__.py +0 -0
- qulab/cli/commands.py +30 -0
- qulab/cli/config.py +170 -0
- qulab/cli/decorators.py +28 -0
- qulab/dicttree.py +523 -0
- qulab/executor/__init__.py +5 -0
- qulab/executor/analyze.py +188 -0
- qulab/executor/cli.py +434 -0
- qulab/executor/load.py +563 -0
- qulab/executor/registry.py +185 -0
- qulab/executor/schedule.py +543 -0
- qulab/executor/storage.py +615 -0
- qulab/executor/template.py +259 -0
- qulab/executor/utils.py +194 -0
- qulab/expression.py +827 -0
- qulab/fun.cpython-313-darwin.so +0 -0
- qulab/monitor/__init__.py +1 -0
- qulab/monitor/__main__.py +8 -0
- qulab/monitor/config.py +41 -0
- qulab/monitor/dataset.py +77 -0
- qulab/monitor/event_queue.py +54 -0
- qulab/monitor/mainwindow.py +234 -0
- qulab/monitor/monitor.py +115 -0
- qulab/monitor/ploter.py +123 -0
- qulab/monitor/qt_compat.py +16 -0
- qulab/monitor/toolbar.py +265 -0
- qulab/scan/__init__.py +2 -0
- qulab/scan/curd.py +221 -0
- qulab/scan/models.py +554 -0
- qulab/scan/optimize.py +76 -0
- qulab/scan/query.py +387 -0
- qulab/scan/record.py +603 -0
- qulab/scan/scan.py +1166 -0
- qulab/scan/server.py +450 -0
- qulab/scan/space.py +213 -0
- qulab/scan/utils.py +234 -0
- qulab/storage/__init__.py +0 -0
- qulab/storage/__main__.py +51 -0
- qulab/storage/backend/__init__.py +0 -0
- qulab/storage/backend/redis.py +204 -0
- qulab/storage/base_dataset.py +352 -0
- qulab/storage/chunk.py +60 -0
- qulab/storage/dataset.py +127 -0
- qulab/storage/file.py +273 -0
- qulab/storage/models/__init__.py +22 -0
- qulab/storage/models/base.py +4 -0
- qulab/storage/models/config.py +28 -0
- qulab/storage/models/file.py +89 -0
- qulab/storage/models/ipy.py +58 -0
- qulab/storage/models/models.py +88 -0
- qulab/storage/models/record.py +161 -0
- qulab/storage/models/report.py +22 -0
- qulab/storage/models/tag.py +93 -0
- qulab/storage/storage.py +95 -0
- qulab/sys/__init__.py +2 -0
- qulab/sys/chat.py +688 -0
- qulab/sys/device/__init__.py +3 -0
- qulab/sys/device/basedevice.py +255 -0
- qulab/sys/device/loader.py +86 -0
- qulab/sys/device/utils.py +79 -0
- qulab/sys/drivers/FakeInstrument.py +68 -0
- qulab/sys/drivers/__init__.py +0 -0
- qulab/sys/ipy_events.py +125 -0
- qulab/sys/net/__init__.py +0 -0
- qulab/sys/net/bencoder.py +205 -0
- qulab/sys/net/cli.py +169 -0
- qulab/sys/net/dhcp.py +543 -0
- qulab/sys/net/dhcpd.py +176 -0
- qulab/sys/net/kad.py +1142 -0
- qulab/sys/net/kcp.py +192 -0
- qulab/sys/net/nginx.py +194 -0
- qulab/sys/progress.py +190 -0
- qulab/sys/rpc/__init__.py +0 -0
- qulab/sys/rpc/client.py +0 -0
- qulab/sys/rpc/exceptions.py +96 -0
- qulab/sys/rpc/msgpack.py +1052 -0
- qulab/sys/rpc/msgpack.pyi +41 -0
- qulab/sys/rpc/router.py +35 -0
- qulab/sys/rpc/rpc.py +412 -0
- qulab/sys/rpc/serialize.py +139 -0
- qulab/sys/rpc/server.py +29 -0
- qulab/sys/rpc/socket.py +29 -0
- qulab/sys/rpc/utils.py +25 -0
- qulab/sys/rpc/worker.py +0 -0
- qulab/sys/rpc/zmq_socket.py +227 -0
- qulab/tools/__init__.py +0 -0
- qulab/tools/connection_helper.py +39 -0
- qulab/typing.py +2 -0
- qulab/utils.py +95 -0
- qulab/version.py +1 -0
- qulab/visualization/__init__.py +188 -0
- qulab/visualization/__main__.py +71 -0
- qulab/visualization/_autoplot.py +464 -0
- qulab/visualization/plot_circ.py +319 -0
- qulab/visualization/plot_layout.py +408 -0
- qulab/visualization/plot_seq.py +242 -0
- qulab/visualization/qdat.py +152 -0
- qulab/visualization/rot3d.py +23 -0
- qulab/visualization/widgets.py +86 -0
- qulab-2.10.10.dist-info/METADATA +110 -0
- qulab-2.10.10.dist-info/RECORD +107 -0
- qulab-2.10.10.dist-info/WHEEL +5 -0
- qulab-2.10.10.dist-info/entry_points.txt +2 -0
- qulab-2.10.10.dist-info/licenses/LICENSE +21 -0
- qulab-2.10.10.dist-info/top_level.txt +1 -0
qulab/scan/utils.py
ADDED
@@ -0,0 +1,234 @@
|
|
1
|
+
import ast
|
2
|
+
import asyncio
|
3
|
+
import inspect
|
4
|
+
import platform
|
5
|
+
import re
|
6
|
+
import subprocess
|
7
|
+
import sys
|
8
|
+
import uuid
|
9
|
+
import warnings
|
10
|
+
from typing import Any, Callable
|
11
|
+
|
12
|
+
import dill
|
13
|
+
|
14
|
+
from ..expression import Env, Expression
|
15
|
+
|
16
|
+
|
17
|
+
class Unpicklable:
|
18
|
+
|
19
|
+
def __init__(self, obj):
|
20
|
+
self.type = str(type(obj))
|
21
|
+
self.id = id(obj)
|
22
|
+
|
23
|
+
def __repr__(self):
|
24
|
+
return f'<Unpicklable: {self.type} at 0x{id(self):x}>'
|
25
|
+
|
26
|
+
|
27
|
+
class TooLarge:
|
28
|
+
|
29
|
+
def __init__(self, obj):
|
30
|
+
self.type = str(type(obj))
|
31
|
+
self.id = id(obj)
|
32
|
+
|
33
|
+
def __repr__(self):
|
34
|
+
return f'<TooLarge: {self.type} at 0x{id(self):x}>'
|
35
|
+
|
36
|
+
|
37
|
+
def dump_dict(d, keys=[]):
|
38
|
+
ret = {}
|
39
|
+
|
40
|
+
for key, value in d.items():
|
41
|
+
if key in keys:
|
42
|
+
ret[key] = value
|
43
|
+
continue
|
44
|
+
if isinstance(value, dict) and isinstance(key, str):
|
45
|
+
ret[key] = dump_dict(value,
|
46
|
+
keys=[
|
47
|
+
k[len(key) + 1:] for k in keys
|
48
|
+
if k.startswith(f'{key}.')
|
49
|
+
])
|
50
|
+
else:
|
51
|
+
try:
|
52
|
+
ret[key] = dill.dumps(value)
|
53
|
+
except:
|
54
|
+
ret[key] = Unpicklable(value)
|
55
|
+
|
56
|
+
return dill.dumps(ret)
|
57
|
+
|
58
|
+
|
59
|
+
def load_dict(buff):
|
60
|
+
if isinstance(buff, dict):
|
61
|
+
return {key: load_dict(value) for key, value in buff.items()}
|
62
|
+
|
63
|
+
if not isinstance(buff, bytes):
|
64
|
+
return buff
|
65
|
+
|
66
|
+
try:
|
67
|
+
ret = dill.loads(buff)
|
68
|
+
except:
|
69
|
+
return buff
|
70
|
+
|
71
|
+
if isinstance(ret, dict):
|
72
|
+
return load_dict(ret)
|
73
|
+
else:
|
74
|
+
return ret
|
75
|
+
|
76
|
+
|
77
|
+
def dump_globals(ns=None, *, size_limit=10 * 1024 * 1024, warn=False):
|
78
|
+
import __main__
|
79
|
+
|
80
|
+
if ns is None:
|
81
|
+
ns = __main__.__dict__
|
82
|
+
|
83
|
+
namespace = {}
|
84
|
+
|
85
|
+
for name, value in ns.items():
|
86
|
+
try:
|
87
|
+
buf = dill.dumps(value)
|
88
|
+
except:
|
89
|
+
namespace[name] = Unpicklable(value)
|
90
|
+
if warn:
|
91
|
+
warnings.warn(f'Unpicklable: {name} {type(value)}')
|
92
|
+
if len(buf) > size_limit:
|
93
|
+
namespace[name] = TooLarge(value)
|
94
|
+
if warn:
|
95
|
+
warnings.warn(f'TooLarge: {name} {type(value)}')
|
96
|
+
else:
|
97
|
+
namespace[name] = buf
|
98
|
+
|
99
|
+
return namespace
|
100
|
+
|
101
|
+
|
102
|
+
def is_valid_identifier(s: str) -> bool:
|
103
|
+
"""
|
104
|
+
Check if a string is a valid identifier.
|
105
|
+
"""
|
106
|
+
try:
|
107
|
+
ast.parse(f"f({s}=0)")
|
108
|
+
return True
|
109
|
+
except SyntaxError:
|
110
|
+
return False
|
111
|
+
|
112
|
+
|
113
|
+
async def async_next(aiter):
|
114
|
+
try:
|
115
|
+
if hasattr(aiter, '__anext__'):
|
116
|
+
return await aiter.__anext__()
|
117
|
+
else:
|
118
|
+
return next(aiter)
|
119
|
+
except StopIteration:
|
120
|
+
raise StopAsyncIteration from None
|
121
|
+
|
122
|
+
|
123
|
+
async def async_zip(*aiters):
|
124
|
+
aiters = [
|
125
|
+
ait.__aiter__() if hasattr(ait, '__aiter__') else iter(ait)
|
126
|
+
for ait in aiters
|
127
|
+
]
|
128
|
+
try:
|
129
|
+
while True:
|
130
|
+
# 使用 asyncio.gather 等待所有异步生成器返回下一个元素
|
131
|
+
result = await asyncio.gather(*(async_next(ait) for ait in aiters))
|
132
|
+
yield tuple(result)
|
133
|
+
except StopAsyncIteration:
|
134
|
+
# 当任一异步生成器耗尽时停止迭代
|
135
|
+
return
|
136
|
+
|
137
|
+
|
138
|
+
async def call_function(func: Callable | Expression, variables: dict[str,
|
139
|
+
Any]):
|
140
|
+
if isinstance(func, Expression):
|
141
|
+
env = Env()
|
142
|
+
for name in func.symbols():
|
143
|
+
if name in variables:
|
144
|
+
if inspect.isawaitable(variables[name]):
|
145
|
+
variables[name] = await variables[name]
|
146
|
+
env.variables[name] = variables[name]
|
147
|
+
else:
|
148
|
+
raise ValueError(f'{name} is not provided.')
|
149
|
+
return func.eval(env)
|
150
|
+
|
151
|
+
try:
|
152
|
+
sig = inspect.signature(func)
|
153
|
+
except:
|
154
|
+
return func()
|
155
|
+
args = []
|
156
|
+
for name, param in sig.parameters.items():
|
157
|
+
if param.kind == param.POSITIONAL_OR_KEYWORD:
|
158
|
+
if name in variables:
|
159
|
+
if inspect.isawaitable(variables[name]):
|
160
|
+
variables[name] = await variables[name]
|
161
|
+
args.append(variables[name])
|
162
|
+
elif param.default is not param.empty:
|
163
|
+
args.append(param.default)
|
164
|
+
else:
|
165
|
+
raise ValueError(f'parameter {name} is not provided.')
|
166
|
+
elif param.kind == param.VAR_POSITIONAL:
|
167
|
+
raise ValueError('not support VAR_POSITIONAL')
|
168
|
+
elif param.kind == param.VAR_KEYWORD:
|
169
|
+
ret = func(**variables)
|
170
|
+
if inspect.isawaitable(ret):
|
171
|
+
ret = await ret
|
172
|
+
return ret
|
173
|
+
ret = func(*args)
|
174
|
+
if inspect.isawaitable(ret):
|
175
|
+
ret = await ret
|
176
|
+
return ret
|
177
|
+
|
178
|
+
|
179
|
+
def yapf_reformat(cell_text):
|
180
|
+
try:
|
181
|
+
import isort
|
182
|
+
import yapf.yapflib.yapf_api
|
183
|
+
|
184
|
+
fname = f"f{uuid.uuid1().hex}"
|
185
|
+
|
186
|
+
def wrap(source):
|
187
|
+
lines = [f"async def {fname}():"]
|
188
|
+
for line in source.split('\n'):
|
189
|
+
lines.append(" " + line)
|
190
|
+
return '\n'.join(lines)
|
191
|
+
|
192
|
+
def unwrap(source):
|
193
|
+
lines = []
|
194
|
+
for line in source.split('\n'):
|
195
|
+
if line.startswith(f"async def {fname}():"):
|
196
|
+
continue
|
197
|
+
lines.append(line[4:])
|
198
|
+
return '\n'.join(lines)
|
199
|
+
|
200
|
+
cell_text = re.sub('^%', '#%#', cell_text, flags=re.M)
|
201
|
+
try:
|
202
|
+
reformated_text = yapf.yapflib.yapf_api.FormatCode(
|
203
|
+
isort.code(cell_text))[0]
|
204
|
+
except:
|
205
|
+
reformated_text = unwrap(
|
206
|
+
yapf.yapflib.yapf_api.FormatCode(wrap(
|
207
|
+
isort.code(cell_text)))[0])
|
208
|
+
return re.sub('^#%#', '%', reformated_text, flags=re.M)
|
209
|
+
except:
|
210
|
+
return cell_text
|
211
|
+
|
212
|
+
|
213
|
+
def get_installed_packages():
|
214
|
+
result = subprocess.run([sys.executable, '-m', 'pip', 'freeze'],
|
215
|
+
stdout=subprocess.PIPE,
|
216
|
+
text=True)
|
217
|
+
|
218
|
+
lines = result.stdout.split('\n')
|
219
|
+
packages = []
|
220
|
+
for line in lines:
|
221
|
+
if line:
|
222
|
+
packages.append(line)
|
223
|
+
return packages
|
224
|
+
|
225
|
+
|
226
|
+
def get_system_info():
|
227
|
+
info = {
|
228
|
+
'OS': platform.uname()._asdict(),
|
229
|
+
'Python': sys.version,
|
230
|
+
'PythonExecutable': sys.executable,
|
231
|
+
'PythonPath': sys.path,
|
232
|
+
'packages': get_installed_packages()
|
233
|
+
}
|
234
|
+
return info
|
File without changes
|
@@ -0,0 +1,51 @@
|
|
1
|
+
import click
|
2
|
+
|
3
|
+
|
4
|
+
@click.command()
|
5
|
+
@click.option('--executor', default='', help='Executor address to use.')
|
6
|
+
@click.option('--port', default=8080, help='Port to run the server on.')
|
7
|
+
@click.option('--host', default='127.0.0.1', help='Host to run the server on.')
|
8
|
+
@click.option('--db-url', default=None, help='Database URL to use.')
|
9
|
+
@click.option('--data-path',
|
10
|
+
default='waveforms/data',
|
11
|
+
help='Path to the data directory.')
|
12
|
+
@click.option('--debug', is_flag=True, help='Run in debug mode.')
|
13
|
+
@click.option('--workers',
|
14
|
+
default=1,
|
15
|
+
help='Number of workers to run the server with.')
|
16
|
+
@click.option('--timeout', default=60, help='Timeout for requests.')
|
17
|
+
@click.option('--log-level',
|
18
|
+
default='INFO',
|
19
|
+
help='Log level to run the server with.')
|
20
|
+
@click.option('--log-file',
|
21
|
+
default='/var/log/waveforms/server.log',
|
22
|
+
help='Log file to run the server with.')
|
23
|
+
@click.option('--log-format',
|
24
|
+
default='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
25
|
+
help='Log format to run the server with.')
|
26
|
+
def main(executor, port, host, db_url, data_path, debug, workers, timeout,
|
27
|
+
log_level, log_file, log_format):
|
28
|
+
"""
|
29
|
+
Main entry point for the server.
|
30
|
+
"""
|
31
|
+
from waveforms.server import create_app
|
32
|
+
|
33
|
+
app = create_app(
|
34
|
+
executor=executor,
|
35
|
+
port=port,
|
36
|
+
host=host,
|
37
|
+
db_url=db_url,
|
38
|
+
data_path=data_path,
|
39
|
+
debug=debug,
|
40
|
+
workers=workers,
|
41
|
+
timeout=timeout,
|
42
|
+
log_level=log_level,
|
43
|
+
log_file=log_file,
|
44
|
+
log_format=log_format,
|
45
|
+
)
|
46
|
+
app.run()
|
47
|
+
|
48
|
+
|
49
|
+
if __name__ == '__main__':
|
50
|
+
main()
|
51
|
+
|
File without changes
|
@@ -0,0 +1,204 @@
|
|
1
|
+
import dill
|
2
|
+
import numpy as np
|
3
|
+
import redis
|
4
|
+
|
5
|
+
|
6
|
+
def try_dumps(value):
|
7
|
+
try:
|
8
|
+
value_b = dill.dumps(value)
|
9
|
+
except:
|
10
|
+
value_b = dill.dumps(str(value))
|
11
|
+
finally:
|
12
|
+
return value_b
|
13
|
+
|
14
|
+
|
15
|
+
class redisClient(object):
|
16
|
+
|
17
|
+
def __init__(self,
|
18
|
+
name,
|
19
|
+
server=None,
|
20
|
+
addr='redis://localhost:6379/0',
|
21
|
+
expire_time=172800):
|
22
|
+
self._r = redis.Redis.from_url(addr) if server is None else server
|
23
|
+
self.name = name
|
24
|
+
self.expire_time = int(expire_time) # 默认数据两天过期,单位秒
|
25
|
+
|
26
|
+
def delete(self):
|
27
|
+
self._r.delete(self.name)
|
28
|
+
|
29
|
+
|
30
|
+
class redisString(redisClient):
|
31
|
+
'''Redis String client'''
|
32
|
+
|
33
|
+
def set(self, value):
|
34
|
+
if value is not None:
|
35
|
+
value_b = try_dumps(value)
|
36
|
+
self._r.set(self.name, value_b, ex=self.expire_time)
|
37
|
+
|
38
|
+
def get(self):
|
39
|
+
v_b = self._r.get(self.name)
|
40
|
+
value = dill.loads(v_b) if v_b is not None else None
|
41
|
+
return value
|
42
|
+
|
43
|
+
@property
|
44
|
+
def data(self):
|
45
|
+
return self.get()
|
46
|
+
|
47
|
+
|
48
|
+
class redisList(redisClient):
|
49
|
+
'''Redis List client'''
|
50
|
+
|
51
|
+
def add(self, *arg):
|
52
|
+
arg_b = [dill.dumps(i) for i in arg]
|
53
|
+
self._r.rpush(self.name, *arg_b)
|
54
|
+
self._r.expire(self.name, self.expire_time)
|
55
|
+
|
56
|
+
def read(self, start=0, end=-1):
|
57
|
+
data_b = self._r.lrange(self.name, start, end)
|
58
|
+
data = [dill.loads(i) for i in data_b]
|
59
|
+
return data
|
60
|
+
|
61
|
+
@property
|
62
|
+
def size(self):
|
63
|
+
return self._r.llen(self.name)
|
64
|
+
|
65
|
+
@property
|
66
|
+
def data(self):
|
67
|
+
return self.read()
|
68
|
+
|
69
|
+
|
70
|
+
class redisSet(redisClient):
|
71
|
+
'''Redis Set client'''
|
72
|
+
|
73
|
+
def add(self, *arg):
|
74
|
+
arg_b = {dill.dumps(i) for i in arg}
|
75
|
+
self._r.sadd(self.name, *arg_b)
|
76
|
+
self._r.expire(self.name, self.expire_time)
|
77
|
+
|
78
|
+
def read(self):
|
79
|
+
data_b = self._r.smembers(self.name)
|
80
|
+
data = {dill.loads(i) for i in data_b}
|
81
|
+
return data
|
82
|
+
|
83
|
+
@property
|
84
|
+
def size(self):
|
85
|
+
return self._r.scard(self.name)
|
86
|
+
|
87
|
+
@property
|
88
|
+
def data(self):
|
89
|
+
return self.read()
|
90
|
+
|
91
|
+
|
92
|
+
class redisZSet(redisClient):
|
93
|
+
'''有序集合'''
|
94
|
+
|
95
|
+
def __init__(self,
|
96
|
+
name,
|
97
|
+
server=None,
|
98
|
+
addr='redis://localhost:6379/0',
|
99
|
+
expire_time=172800):
|
100
|
+
super().__init__(name, server, addr, expire_time)
|
101
|
+
self.__score = 0
|
102
|
+
|
103
|
+
def delete(self):
|
104
|
+
super().delete()
|
105
|
+
self.__score = 0
|
106
|
+
|
107
|
+
def add(self, *elements):
|
108
|
+
mapping = {}
|
109
|
+
for ele in elements:
|
110
|
+
ele_b = dill.dumps(ele)
|
111
|
+
self.__score += 1
|
112
|
+
mapping.update({ele_b: self.__score})
|
113
|
+
self._r.zadd(self.name, mapping, nx=True) # 只添加新元素
|
114
|
+
self._r.expire(self.name, self.expire_time)
|
115
|
+
|
116
|
+
def read(self, start=0, end=-1):
|
117
|
+
data_b = self._r.zrange(self.name, start, end, withscores=False)
|
118
|
+
data = [dill.loads(i) for i in data_b]
|
119
|
+
return data
|
120
|
+
|
121
|
+
@property
|
122
|
+
def size(self):
|
123
|
+
return self._r.zcard(self.name)
|
124
|
+
|
125
|
+
@property
|
126
|
+
def data(self):
|
127
|
+
return self.read()
|
128
|
+
|
129
|
+
|
130
|
+
class redisHash(redisClient):
|
131
|
+
'''Redis Hash client'''
|
132
|
+
|
133
|
+
def add(self, **kw):
|
134
|
+
kw_b = {k: try_dumps(v) for k, v in kw.items()}
|
135
|
+
self._r.hmset(self.name, kw_b)
|
136
|
+
self._r.expire(self.name, self.expire_time)
|
137
|
+
|
138
|
+
def read(self):
|
139
|
+
data_b = self._r.hgetall(self.name)
|
140
|
+
data = {k_b.decode(): dill.loads(v_b) for k_b, v_b in data_b.items()}
|
141
|
+
return data
|
142
|
+
|
143
|
+
def get(self, key):
|
144
|
+
'''读取Hash中的一个key'''
|
145
|
+
v_b = self._r.hget(self.name, key)
|
146
|
+
value = dill.loads(v_b) if v_b is not None else None
|
147
|
+
return value
|
148
|
+
|
149
|
+
@property
|
150
|
+
def size(self):
|
151
|
+
return self._r.hlen(self.name)
|
152
|
+
|
153
|
+
@property
|
154
|
+
def data(self):
|
155
|
+
return self.read()
|
156
|
+
|
157
|
+
|
158
|
+
class redisArray(redisClient):
|
159
|
+
'''Redis np.array client'''
|
160
|
+
|
161
|
+
def __init__(self,
|
162
|
+
name,
|
163
|
+
server=None,
|
164
|
+
addr='redis://localhost:6379/0',
|
165
|
+
expire_time=172800,
|
166
|
+
dtype='complex128'):
|
167
|
+
super().__init__(name, server, addr, expire_time)
|
168
|
+
_r_dtype = self._r.get(f'{name}.dtype')
|
169
|
+
if _r_dtype is None:
|
170
|
+
self._r.set(f'{name}.dtype', dtype, ex=self.expire_time)
|
171
|
+
self.dtype = dtype
|
172
|
+
else:
|
173
|
+
self.dtype = _r_dtype
|
174
|
+
|
175
|
+
def delete(self):
|
176
|
+
self._r.delete(self.name)
|
177
|
+
self._r.delete(f'{self.name}.dtype')
|
178
|
+
|
179
|
+
def add(self, *args):
|
180
|
+
for arg in args:
|
181
|
+
buf = np.asarray(arg).astype(self.dtype).tobytes()
|
182
|
+
# self._r.append(self.name, buf)
|
183
|
+
self._r.rpush(self.name, buf)
|
184
|
+
self._r.expire(self.name, self.expire_time)
|
185
|
+
|
186
|
+
def read(self):
|
187
|
+
# buf = self._r.get(self.name)
|
188
|
+
buf_list = self._r.lrange(self.name, 0, -1)
|
189
|
+
buf = b''.join(buf_list)
|
190
|
+
data = np.frombuffer(buf,
|
191
|
+
dtype=self.dtype) if buf is not None else None
|
192
|
+
return data
|
193
|
+
|
194
|
+
@property
|
195
|
+
def size(self):
|
196
|
+
array = self.data
|
197
|
+
if array is None:
|
198
|
+
return 0
|
199
|
+
else:
|
200
|
+
return array.size
|
201
|
+
|
202
|
+
@property
|
203
|
+
def data(self):
|
204
|
+
return self.read()
|