pyjuiz 0.0.2__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.
- pyjuiz-0.0.2/PKG-INFO +21 -0
- pyjuiz-0.0.2/README.md +0 -0
- pyjuiz-0.0.2/juiz/__init__.py +5 -0
- pyjuiz-0.0.2/juiz/__main__.py +131 -0
- pyjuiz-0.0.2/juiz/decorators.py +248 -0
- pyjuiz-0.0.2/juiz/juiz.py +178 -0
- pyjuiz-0.0.2/juiz/proxy/__init__.py +403 -0
- pyjuiz-0.0.2/pyjuiz.egg-info/PKG-INFO +21 -0
- pyjuiz-0.0.2/pyjuiz.egg-info/SOURCES.txt +12 -0
- pyjuiz-0.0.2/pyjuiz.egg-info/dependency_links.txt +1 -0
- pyjuiz-0.0.2/pyjuiz.egg-info/requires.txt +3 -0
- pyjuiz-0.0.2/pyjuiz.egg-info/top_level.txt +1 -0
- pyjuiz-0.0.2/setup.cfg +4 -0
- pyjuiz-0.0.2/setup.py +20 -0
pyjuiz-0.0.2/PKG-INFO
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyjuiz
|
|
3
|
+
Version: 0.0.2
|
|
4
|
+
Summary: Python binding interface for JUIZ robot middleware components
|
|
5
|
+
Home-page: https://github.com/juiz
|
|
6
|
+
Author: ysuga
|
|
7
|
+
Author-email: ysuga@ysuga.net
|
|
8
|
+
License: MIT
|
|
9
|
+
Keywords: robot,middleware
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
11
|
+
Requires-Dist: yaml
|
|
12
|
+
Requires-Dist: httpx
|
|
13
|
+
Requires-Dist: pillow
|
|
14
|
+
Dynamic: author
|
|
15
|
+
Dynamic: author-email
|
|
16
|
+
Dynamic: classifier
|
|
17
|
+
Dynamic: home-page
|
|
18
|
+
Dynamic: keywords
|
|
19
|
+
Dynamic: license
|
|
20
|
+
Dynamic: requires-dist
|
|
21
|
+
Dynamic: summary
|
pyjuiz-0.0.2/README.md
ADDED
|
File without changes
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
|
|
2
|
+
import argparse
|
|
3
|
+
import juiz
|
|
4
|
+
import json
|
|
5
|
+
|
|
6
|
+
def _get_system(option):
|
|
7
|
+
return juiz.proxy.SystemProxy(juiz.proxy.HttpProxy(option.host, option.port))
|
|
8
|
+
|
|
9
|
+
def sys_handler(args):
|
|
10
|
+
print('system:', args)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def proc_list_handler(option):
|
|
15
|
+
s = _get_system(option)
|
|
16
|
+
ps = s.processes()
|
|
17
|
+
print([p.identifier() for p in ps])
|
|
18
|
+
|
|
19
|
+
def proc_call_handler(option):
|
|
20
|
+
s = _get_system(option)
|
|
21
|
+
p = s.process(option.identifier)
|
|
22
|
+
body = json.loads(option.body)
|
|
23
|
+
print(p.call(body))
|
|
24
|
+
|
|
25
|
+
def proc_exec_handler(option):
|
|
26
|
+
s = _get_system(option)
|
|
27
|
+
p = s.process(option.identifier)
|
|
28
|
+
print(p.execute())
|
|
29
|
+
|
|
30
|
+
def proc_prof_handler(option):
|
|
31
|
+
s = _get_system(option)
|
|
32
|
+
p = s.process(option.identifier)
|
|
33
|
+
print(p.profile_full())
|
|
34
|
+
|
|
35
|
+
def setup_process_parser(proc_parser):
|
|
36
|
+
proc_subparsers = proc_parser.add_subparsers()
|
|
37
|
+
p_l_parser = proc_subparsers.add_parser('list')
|
|
38
|
+
p_l_parser.set_defaults(handler=proc_list_handler)
|
|
39
|
+
|
|
40
|
+
p_p_parser = proc_subparsers.add_parser('profile')
|
|
41
|
+
p_p_parser.add_argument('identifier', help='process ID')
|
|
42
|
+
p_p_parser.set_defaults(handler=proc_prof_handler)
|
|
43
|
+
|
|
44
|
+
p_c_parser = proc_subparsers.add_parser('call')
|
|
45
|
+
p_c_parser.add_argument('identifier', help='process ID')
|
|
46
|
+
p_c_parser.add_argument('body', help='body json')
|
|
47
|
+
p_c_parser.set_defaults(handler=proc_call_handler)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def cont_list_handler(option):
|
|
51
|
+
s = _get_system(option)
|
|
52
|
+
cs = s.containers()
|
|
53
|
+
print([c.identifier() for c in cs])
|
|
54
|
+
|
|
55
|
+
def cont_prof_handler(option):
|
|
56
|
+
s = _get_system(option)
|
|
57
|
+
c = s.container(option.identifier)
|
|
58
|
+
print(c.profile_full())
|
|
59
|
+
|
|
60
|
+
def setup_container_parser(cont_parser):
|
|
61
|
+
cont_subparsers = cont_parser.add_subparsers()
|
|
62
|
+
c_l_parser = cont_subparsers.add_parser('list')
|
|
63
|
+
c_l_parser.set_defaults(handler=cont_list_handler)
|
|
64
|
+
|
|
65
|
+
c_p_parser = cont_subparsers.add_parser('profile')
|
|
66
|
+
c_p_parser.add_argument('identifier', help='container ID')
|
|
67
|
+
c_p_parser.set_defaults(handler=cont_prof_handler)
|
|
68
|
+
|
|
69
|
+
setup_container_process_parser(cont_subparsers.add_parser('process'))
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def c_p_l_handler(option):
|
|
74
|
+
s = _get_system(option)
|
|
75
|
+
c = s.container(option.identifier)
|
|
76
|
+
ps = c.processes()
|
|
77
|
+
print([p.identifier() for p in ps])
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def c_p_c_handler(option):
|
|
81
|
+
s = _get_system(option)
|
|
82
|
+
c = s.container(option.identifier)
|
|
83
|
+
p = c.process(option.process_identifier)
|
|
84
|
+
body = json.loads(option.body)
|
|
85
|
+
print(p.call(body))
|
|
86
|
+
|
|
87
|
+
def c_p_e_handler(option):
|
|
88
|
+
s = _get_system(option)
|
|
89
|
+
c = s.container(option.identifier)
|
|
90
|
+
p = c.process(option.process_identifier)
|
|
91
|
+
print(p.execute())
|
|
92
|
+
|
|
93
|
+
def setup_container_process_parser(c_ps_parser):
|
|
94
|
+
c_ps_parser.add_argument('identifier', help='container ID')
|
|
95
|
+
c_ps_subparsers = c_ps_parser.add_subparsers()
|
|
96
|
+
|
|
97
|
+
c_ps_list_parser = c_ps_subparsers.add_parser('list')
|
|
98
|
+
c_ps_list_parser.set_defaults(handler=c_p_l_handler)
|
|
99
|
+
|
|
100
|
+
c_ps_call_parser = c_ps_subparsers.add_parser('call')
|
|
101
|
+
c_ps_call_parser.add_argument('process_identifier', help='container process id')
|
|
102
|
+
c_ps_call_parser.add_argument('body', help='data')
|
|
103
|
+
c_ps_call_parser.set_defaults(handler=c_p_c_handler)
|
|
104
|
+
|
|
105
|
+
c_ps_e_parser = c_ps_subparsers.add_parser('execute')
|
|
106
|
+
c_ps_e_parser.add_argument('process_identifier', help='container process id')
|
|
107
|
+
c_ps_e_parser.set_defaults(handler=c_p_e_handler)
|
|
108
|
+
|
|
109
|
+
def main():
|
|
110
|
+
parser = argparse.ArgumentParser(
|
|
111
|
+
prog='juiz',
|
|
112
|
+
description='juiz test program',
|
|
113
|
+
)
|
|
114
|
+
parser.add_argument('--host', default='localhost')
|
|
115
|
+
parser.add_argument('--port', default=8000)
|
|
116
|
+
subparsers = parser.add_subparsers()
|
|
117
|
+
sysparser = subparsers.add_parser('system', help='system command')
|
|
118
|
+
sysparser.add_argument('profile', help='system profile')
|
|
119
|
+
sysparser.set_defaults(handler=sys_handler)
|
|
120
|
+
|
|
121
|
+
setup_process_parser(subparsers.add_parser('process', help='process command'))
|
|
122
|
+
setup_container_parser(subparsers.add_parser('container', help='container command'))
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
option = parser.parse_args()
|
|
126
|
+
|
|
127
|
+
if hasattr(option, 'handler'):
|
|
128
|
+
option.handler(option)
|
|
129
|
+
|
|
130
|
+
if __name__ == '__main__':
|
|
131
|
+
main()
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import datetime
|
|
2
|
+
import inspect
|
|
3
|
+
import functools
|
|
4
|
+
import io
|
|
5
|
+
|
|
6
|
+
from .juiz import *
|
|
7
|
+
from PIL.Image import Image
|
|
8
|
+
class PyJuizProcessArgumentUnknownTypeError(Exception): pass
|
|
9
|
+
class PyJuizContainerArgumentUnknownTypeError(Exception): pass
|
|
10
|
+
|
|
11
|
+
def allow_no_arg_decorator(decorator_function):
|
|
12
|
+
def wrapper(*args, **kwargs):
|
|
13
|
+
|
|
14
|
+
if len(args) != 0 and callable(args[0]):
|
|
15
|
+
decorated_function= args[0]
|
|
16
|
+
return functools.wraps(decorated_function)(decorator_function(decorated_function))
|
|
17
|
+
else:
|
|
18
|
+
def _wrapper(decorated_function):
|
|
19
|
+
return functools.wraps(decorated_function)(decorator_function(decorated_function, *args, **kwargs))
|
|
20
|
+
return _wrapper
|
|
21
|
+
return wrapper
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class JuizProcess(object):
|
|
25
|
+
def __init__(self, proc):
|
|
26
|
+
self.__proc = proc
|
|
27
|
+
self.name = proc.__name__
|
|
28
|
+
self.signature = inspect.signature(proc)
|
|
29
|
+
self._manifest = ProcessManifest.new(self.name).set_description(proc.__doc__)
|
|
30
|
+
for p in self.signature.parameters:
|
|
31
|
+
param = self.signature.parameters[p]
|
|
32
|
+
param_type = param.annotation
|
|
33
|
+
param_default = param.default
|
|
34
|
+
if param_type is inspect._empty:
|
|
35
|
+
if isinstance(param_default, int):
|
|
36
|
+
param_type = int
|
|
37
|
+
elif isinstance(param_default, bool):
|
|
38
|
+
param_type = bool
|
|
39
|
+
elif isinstance(param_default, float):
|
|
40
|
+
param_type = float
|
|
41
|
+
elif isinstance(param_default, list):
|
|
42
|
+
param_type = list
|
|
43
|
+
elif isinstance(param_default, str):
|
|
44
|
+
param_type = str
|
|
45
|
+
elif isinstance(param_default, dict):
|
|
46
|
+
param_type = dict
|
|
47
|
+
else:
|
|
48
|
+
raise PyJuizProcessArgumentUnknownTypeError()
|
|
49
|
+
if param_default is inspect._empty:
|
|
50
|
+
if param_type == int:
|
|
51
|
+
param_default = 0
|
|
52
|
+
elif param_type == float:
|
|
53
|
+
param_default = 0.0
|
|
54
|
+
elif param_type == dict:
|
|
55
|
+
param_default = {}
|
|
56
|
+
elif param_type == list:
|
|
57
|
+
param_default = []
|
|
58
|
+
elif param_type == bool:
|
|
59
|
+
param_default = False
|
|
60
|
+
elif param_type == str:
|
|
61
|
+
param_default = ""
|
|
62
|
+
elif param_type == Image:
|
|
63
|
+
param_default = None
|
|
64
|
+
else:
|
|
65
|
+
raise PyJuizProcessArgumentUnknownTypeError()
|
|
66
|
+
|
|
67
|
+
# print('p:', param.name, param.default, param.kind, param.annotation, param)
|
|
68
|
+
if param_type == int:
|
|
69
|
+
self._manifest.add_int_arg(param.name, "", param_default)
|
|
70
|
+
elif param_type == float:
|
|
71
|
+
self._manifest.add_float_arg(param.name, "", param_default)
|
|
72
|
+
elif param_type == bool:
|
|
73
|
+
self._manifest.add_bool_arg(param.name, "", param_default)
|
|
74
|
+
elif param_type == str:
|
|
75
|
+
self._manifest.add_string_arg(param.name, "", param_default)
|
|
76
|
+
elif param_type == dict:
|
|
77
|
+
self._manifest.add_object_arg(param.name, "", param_default)
|
|
78
|
+
elif param_type == list:
|
|
79
|
+
self._manifest.add_array_arg(param.name, "", param_default)
|
|
80
|
+
elif param_type == Image:
|
|
81
|
+
self._manifest.add_image_arg(param.name, "", param_default)
|
|
82
|
+
def manifest(self):
|
|
83
|
+
return self._manifest.into_value()
|
|
84
|
+
|
|
85
|
+
def __call__(self, *args, **kwargs):
|
|
86
|
+
return convert_process_result(self.__proc(*args, **kwargs))
|
|
87
|
+
|
|
88
|
+
@allow_no_arg_decorator
|
|
89
|
+
def juiz_process(process_function, description="Default Description"):
|
|
90
|
+
return JuizProcess(process_function)
|
|
91
|
+
|
|
92
|
+
class JuizContainer(object):
|
|
93
|
+
def __init__(self, proc):
|
|
94
|
+
self.__proc = proc
|
|
95
|
+
self.name = proc.__name__
|
|
96
|
+
self.signature = inspect.signature(proc)
|
|
97
|
+
self._manifest = ContainerManifest.new(self.name).set_description(proc.__doc__)
|
|
98
|
+
for p in self.signature.parameters:
|
|
99
|
+
param = self.signature.parameters[p]
|
|
100
|
+
param_type = param.annotation
|
|
101
|
+
param_default = param.default
|
|
102
|
+
if param_type is inspect._empty:
|
|
103
|
+
if isinstance(param_default, int):
|
|
104
|
+
param_type = int
|
|
105
|
+
elif isinstance(param_default, bool):
|
|
106
|
+
param_type = bool
|
|
107
|
+
elif isinstance(param_default, float):
|
|
108
|
+
param_type = float
|
|
109
|
+
elif isinstance(param_default, list):
|
|
110
|
+
param_type = list
|
|
111
|
+
elif isinstance(param_default, str):
|
|
112
|
+
param_type = str
|
|
113
|
+
elif isinstance(param_default, dict):
|
|
114
|
+
param_type = dict
|
|
115
|
+
elif isinstance(param_default, Image):
|
|
116
|
+
param_type = Image
|
|
117
|
+
else:
|
|
118
|
+
raise PyJuizProcessArgumentUnknownTypeError()
|
|
119
|
+
if param_default is inspect._empty:
|
|
120
|
+
if param_type == int:
|
|
121
|
+
param_default = 0
|
|
122
|
+
elif param_type == float:
|
|
123
|
+
param_default = 0.0
|
|
124
|
+
elif param_type == dict:
|
|
125
|
+
param_default = {}
|
|
126
|
+
elif param_type == list:
|
|
127
|
+
param_default = []
|
|
128
|
+
elif param_type == bool:
|
|
129
|
+
param_default = False
|
|
130
|
+
elif param_type == str:
|
|
131
|
+
param_default = ""
|
|
132
|
+
elif param_type == Image:
|
|
133
|
+
param_default = None
|
|
134
|
+
else:
|
|
135
|
+
raise PyJuizProcessArgumentUnknownTypeError()
|
|
136
|
+
|
|
137
|
+
# print('p:', param.name, param.default, param.kind, param.annotation, param)
|
|
138
|
+
if param_type == int:
|
|
139
|
+
self._manifest.add_int_arg(param.name, "", param_default)
|
|
140
|
+
elif param_type == float:
|
|
141
|
+
self._manifest.add_float_arg(param.name, "", param_default)
|
|
142
|
+
elif param_type == bool:
|
|
143
|
+
self._manifest.add_bool_arg(param.name, "", param_default)
|
|
144
|
+
elif param_type == str:
|
|
145
|
+
self._manifest.add_string_arg(param.name, "", param_default)
|
|
146
|
+
elif param_type == dict:
|
|
147
|
+
self._manifest.add_object_arg(param.name, "", param_default)
|
|
148
|
+
elif param_type == list:
|
|
149
|
+
self._manifest.add_array_arg(param.name, "", param_default)
|
|
150
|
+
elif param_type == Image:
|
|
151
|
+
self._manifest.add_image_arg(param.name, "", param_default)
|
|
152
|
+
def manifest(self):
|
|
153
|
+
return self._manifest.into_value()
|
|
154
|
+
|
|
155
|
+
def __call__(self, *args, **kwargs):
|
|
156
|
+
return self.__proc(*args, **kwargs)
|
|
157
|
+
|
|
158
|
+
@allow_no_arg_decorator
|
|
159
|
+
def juiz_container(constructor_function, description="Default Description"):
|
|
160
|
+
return JuizContainer(constructor_function)
|
|
161
|
+
|
|
162
|
+
@allow_no_arg_decorator
|
|
163
|
+
def juiz_component_container(constructor_function, description="Default Description"):
|
|
164
|
+
return JuizContainer(constructor_function)
|
|
165
|
+
|
|
166
|
+
class JuizContainerProcess(object):
|
|
167
|
+
def __init__(self, proc, container_type):
|
|
168
|
+
self.__proc = proc
|
|
169
|
+
self.name = proc.__name__
|
|
170
|
+
self.signature = inspect.signature(proc)
|
|
171
|
+
self._manifest = ProcessManifest.new(self.name).set_description(proc.__doc__).set_container_type(container_type)
|
|
172
|
+
for i, p in enumerate(self.signature.parameters):
|
|
173
|
+
if i == 0:
|
|
174
|
+
continue
|
|
175
|
+
param = self.signature.parameters[p]
|
|
176
|
+
param_type = param.annotation
|
|
177
|
+
param_default = param.default
|
|
178
|
+
if param_type is inspect._empty:
|
|
179
|
+
if isinstance(param_default, int):
|
|
180
|
+
param_type = int
|
|
181
|
+
elif isinstance(param_default, bool):
|
|
182
|
+
param_type = bool
|
|
183
|
+
elif isinstance(param_default, float):
|
|
184
|
+
param_type = float
|
|
185
|
+
elif isinstance(param_default, list):
|
|
186
|
+
param_type = list
|
|
187
|
+
elif isinstance(param_default, str):
|
|
188
|
+
param_type = str
|
|
189
|
+
elif isinstance(param_default, dict):
|
|
190
|
+
param_type = dict
|
|
191
|
+
elif isinstance(param_default, Image):
|
|
192
|
+
param_type = Image
|
|
193
|
+
else:
|
|
194
|
+
raise PyJuizProcessArgumentUnknownTypeError()
|
|
195
|
+
if param_default is inspect._empty:
|
|
196
|
+
if param_type == int:
|
|
197
|
+
param_default = 0
|
|
198
|
+
elif param_type == float:
|
|
199
|
+
param_default = 0.0
|
|
200
|
+
elif param_type == dict:
|
|
201
|
+
param_default = {}
|
|
202
|
+
elif param_type == list:
|
|
203
|
+
param_default = []
|
|
204
|
+
elif param_type == bool:
|
|
205
|
+
param_default = False
|
|
206
|
+
elif param_type == str:
|
|
207
|
+
param_default = ""
|
|
208
|
+
elif param_type == Image:
|
|
209
|
+
param_default = None
|
|
210
|
+
else:
|
|
211
|
+
print('Param Type Unknown:', param_type)
|
|
212
|
+
raise PyJuizProcessArgumentUnknownTypeError()
|
|
213
|
+
|
|
214
|
+
# print('p:', param.name, param.default, param.kind, param.annotation, param)
|
|
215
|
+
if param_type == int:
|
|
216
|
+
self._manifest.add_int_arg(param.name, "", param_default)
|
|
217
|
+
elif param_type == float:
|
|
218
|
+
self._manifest.add_float_arg(param.name, "", param_default)
|
|
219
|
+
elif param_type == bool:
|
|
220
|
+
self._manifest.add_bool_arg(param.name, "", param_default)
|
|
221
|
+
elif param_type == str:
|
|
222
|
+
self._manifest.add_string_arg(param.name, "", param_default)
|
|
223
|
+
elif param_type == dict:
|
|
224
|
+
self._manifest.add_object_arg(param.name, "", param_default)
|
|
225
|
+
elif param_type == list:
|
|
226
|
+
self._manifest.add_array_arg(param.name, "", param_default)
|
|
227
|
+
elif param_type == Image:
|
|
228
|
+
self._manifest.add_image_arg(param.name, "", param_default)
|
|
229
|
+
def manifest(self):
|
|
230
|
+
return self._manifest.into_value()
|
|
231
|
+
|
|
232
|
+
def __call__(self, *args, **kwargs):
|
|
233
|
+
return convert_process_result(self.__proc(*args, **kwargs))
|
|
234
|
+
|
|
235
|
+
def convert_process_result(retval):
|
|
236
|
+
# if isinstance(retval, Image):
|
|
237
|
+
# output = io.BytesIO()
|
|
238
|
+
# retval.save(output, format='PNG')
|
|
239
|
+
# return output.getvalue() # Hex Data
|
|
240
|
+
return retval
|
|
241
|
+
|
|
242
|
+
@allow_no_arg_decorator
|
|
243
|
+
def juiz_container_process(constructor_function, container_type:str, description="Default Description"):
|
|
244
|
+
return JuizContainerProcess(constructor_function, container_type)
|
|
245
|
+
|
|
246
|
+
@allow_no_arg_decorator
|
|
247
|
+
def juiz_component_container_process(constructor_function, container_type:str, description="Default Description"):
|
|
248
|
+
return JuizContainerProcess(constructor_function, container_type)
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
from dataclasses import dataclass, asdict
|
|
2
|
+
from typing import List, Any, Optional
|
|
3
|
+
from PIL.Image import Image
|
|
4
|
+
|
|
5
|
+
@dataclass
|
|
6
|
+
class ArgumentManifest:
|
|
7
|
+
type_name: str
|
|
8
|
+
name: str
|
|
9
|
+
default: Any
|
|
10
|
+
description: str = ""
|
|
11
|
+
|
|
12
|
+
@classmethod
|
|
13
|
+
def new(cls, type_name, name, description, default_value):
|
|
14
|
+
return ArgumentManifest(type_name=type_name, name=name, default=default_value, description=description )
|
|
15
|
+
|
|
16
|
+
@dataclass
|
|
17
|
+
class ProcessManifest:
|
|
18
|
+
|
|
19
|
+
type_name: str
|
|
20
|
+
arguments: List[ArgumentManifest]
|
|
21
|
+
description: str = ""
|
|
22
|
+
factory: str = "process_factory"
|
|
23
|
+
use_demo: bool = False
|
|
24
|
+
language: str = "python"
|
|
25
|
+
name: Optional[str] = None
|
|
26
|
+
container_name: Optional[str] = None
|
|
27
|
+
container_type: Optional[str] = None
|
|
28
|
+
|
|
29
|
+
@classmethod
|
|
30
|
+
def new(cls, type_name):
|
|
31
|
+
return ProcessManifest(type_name=type_name, arguments=[])
|
|
32
|
+
|
|
33
|
+
def set_name(self, n):
|
|
34
|
+
self.name = n
|
|
35
|
+
return self
|
|
36
|
+
|
|
37
|
+
def set_description(self, desc):
|
|
38
|
+
self.description = desc
|
|
39
|
+
return self
|
|
40
|
+
|
|
41
|
+
def set_language(self, language:str):
|
|
42
|
+
self.language = language
|
|
43
|
+
return self
|
|
44
|
+
|
|
45
|
+
def set_factory(self, factory:str):
|
|
46
|
+
self.factory = factory
|
|
47
|
+
return self
|
|
48
|
+
|
|
49
|
+
def set_container_type(self, container_type:str):
|
|
50
|
+
self.container_type = container_type
|
|
51
|
+
return self
|
|
52
|
+
|
|
53
|
+
def set_container_name(self, container_name:Optional[str]):
|
|
54
|
+
self.container_name = container_name
|
|
55
|
+
return self
|
|
56
|
+
|
|
57
|
+
def add_argument(self, argument_manifest):
|
|
58
|
+
self.arguments.append(argument_manifest)
|
|
59
|
+
return self
|
|
60
|
+
|
|
61
|
+
def add_bool_arg(self, name, description, default_value:bool):
|
|
62
|
+
self.add_argument(ArgumentManifest.new("Bool", name, description, default_value))
|
|
63
|
+
return self
|
|
64
|
+
|
|
65
|
+
def add_int_arg(self, name, description, default_value:int):
|
|
66
|
+
self.add_argument(ArgumentManifest.new("Int", name, description, default_value))
|
|
67
|
+
return self
|
|
68
|
+
|
|
69
|
+
def add_float_arg(self, name, description, default_value:float):
|
|
70
|
+
self.add_argument(ArgumentManifest.new("Float", name, description, default_value))
|
|
71
|
+
return self
|
|
72
|
+
|
|
73
|
+
def add_string_arg(self, name, description, default_value:str):
|
|
74
|
+
self.add_argument(ArgumentManifest.new("String", name, description, default_value))
|
|
75
|
+
return self
|
|
76
|
+
|
|
77
|
+
def add_object_arg(self, name, description, default_value: dict):
|
|
78
|
+
self.add_argument(ArgumentManifest.new("Object", name, description, default_value))
|
|
79
|
+
return self
|
|
80
|
+
|
|
81
|
+
def add_array_arg(self, name, description, default_value: list):
|
|
82
|
+
self.add_argument(ArgumentManifest.new("Array", name, description, default_value))
|
|
83
|
+
return self
|
|
84
|
+
|
|
85
|
+
def add_image_arg(self, name, description, default_value: object):
|
|
86
|
+
self.add_argument(ArgumentManifest.new("Image", name, description, default_value))
|
|
87
|
+
|
|
88
|
+
def into_value(self):
|
|
89
|
+
return asdict(self, dict_factory=lambda x: {k: v for (k, v) in x if v is not None})
|
|
90
|
+
|
|
91
|
+
@dataclass
|
|
92
|
+
class ContainerManifest:
|
|
93
|
+
type_name: str
|
|
94
|
+
args: dict
|
|
95
|
+
processes: List[ProcessManifest]
|
|
96
|
+
arguments: List[ArgumentManifest]
|
|
97
|
+
language: str = "python"
|
|
98
|
+
factory: str = "container_factory"
|
|
99
|
+
description: str = ""
|
|
100
|
+
parent_type_name: Optional[str] = None
|
|
101
|
+
parent_name: Optional[str] = None
|
|
102
|
+
name: Optional[str] = None
|
|
103
|
+
|
|
104
|
+
@classmethod
|
|
105
|
+
def new(cls, type_name):
|
|
106
|
+
return ContainerManifest(type_name=type_name, args={}, processes=[], arguments=[])
|
|
107
|
+
|
|
108
|
+
def add_process(self, process_manifest: ProcessManifest):
|
|
109
|
+
self.processes.append(process_manifest\
|
|
110
|
+
.set_container_type(self.type_name)\
|
|
111
|
+
.set_container_name(self.name))
|
|
112
|
+
return self
|
|
113
|
+
|
|
114
|
+
def set_description(self, desc):
|
|
115
|
+
self.description = desc
|
|
116
|
+
return self
|
|
117
|
+
|
|
118
|
+
def into_value(self):
|
|
119
|
+
return asdict(self, dict_factory=lambda x: {k: v for (k, v) in x if v is not None})
|
|
120
|
+
|
|
121
|
+
def add_argument(self, argument_manifest):
|
|
122
|
+
self.arguments.append(argument_manifest)
|
|
123
|
+
return self
|
|
124
|
+
|
|
125
|
+
def add_bool_arg(self, name, description, default_value:bool):
|
|
126
|
+
self.add_argument(ArgumentManifest.new("bool", name, description, default_value))
|
|
127
|
+
return self
|
|
128
|
+
|
|
129
|
+
def add_int_arg(self, name, description, default_value:int):
|
|
130
|
+
self.add_argument(ArgumentManifest.new("int", name, description, default_value))
|
|
131
|
+
return self
|
|
132
|
+
|
|
133
|
+
def add_float_arg(self, name, description, default_value:float):
|
|
134
|
+
self.add_argument(ArgumentManifest.new("float", name, description, default_value))
|
|
135
|
+
return self
|
|
136
|
+
|
|
137
|
+
def add_string_arg(self, name, description, default_value:str):
|
|
138
|
+
self.add_argument(ArgumentManifest.new("string", name, description, default_value))
|
|
139
|
+
return self
|
|
140
|
+
|
|
141
|
+
def add_object_arg(self, name, description, default_value: dict):
|
|
142
|
+
self.add_argument(ArgumentManifest.new("object", name, description, default_value))
|
|
143
|
+
return self
|
|
144
|
+
|
|
145
|
+
def add_array_arg(self, name, description, default_value: list):
|
|
146
|
+
self.add_argument(ArgumentManifest.new("array", name, description, default_value))
|
|
147
|
+
return self
|
|
148
|
+
|
|
149
|
+
def add_image_arg(self, name, description, default_value: object):
|
|
150
|
+
self.add_argument(ArgumentManifest.new("image", name, description, default_value))
|
|
151
|
+
|
|
152
|
+
@dataclass
|
|
153
|
+
class ComponentManifest:
|
|
154
|
+
type_name: str
|
|
155
|
+
containers: List[ContainerManifest]
|
|
156
|
+
processes: List[ProcessManifest]
|
|
157
|
+
description: str = ""
|
|
158
|
+
language: str = "python"
|
|
159
|
+
|
|
160
|
+
@classmethod
|
|
161
|
+
def new(cls, type_name):
|
|
162
|
+
return ComponentManifest(type_name=type_name, containers=[], processes=[])
|
|
163
|
+
|
|
164
|
+
def set_description(self, desc):
|
|
165
|
+
self.description = desc
|
|
166
|
+
return self
|
|
167
|
+
|
|
168
|
+
def set_language(self, lang):
|
|
169
|
+
self.language = lang
|
|
170
|
+
return self
|
|
171
|
+
|
|
172
|
+
def add_container(self, c):
|
|
173
|
+
self.containers.append(c)
|
|
174
|
+
return self
|
|
175
|
+
|
|
176
|
+
def add_process(self, p: ProcessManifest):
|
|
177
|
+
self.processes.append(p)
|
|
178
|
+
return self
|
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
import httpx
|
|
2
|
+
import json, io
|
|
3
|
+
from PIL import Image
|
|
4
|
+
from io import BytesIO
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class UnsupportedMediaTypeError(Exception): pass
|
|
8
|
+
class BadRequestError(Exception): pass
|
|
9
|
+
class ForbiddenError(Exception): pass
|
|
10
|
+
class NotFoundError(Exception): pass
|
|
11
|
+
class RequestTimeoutError(Exception): pass
|
|
12
|
+
class InternalServerError(Exception): pass
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
error_code_and_ex={
|
|
16
|
+
415: UnsupportedMediaTypeError,
|
|
17
|
+
400: BadRequestError,
|
|
18
|
+
403: ForbiddenError,
|
|
19
|
+
404: NotFoundError,
|
|
20
|
+
408: RequestTimeoutError,
|
|
21
|
+
500: InternalServerError,
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
class CRUDProxy():
|
|
25
|
+
|
|
26
|
+
def __init__(self):
|
|
27
|
+
pass
|
|
28
|
+
|
|
29
|
+
def _url(self, class_name, function_name, param_dict: dict=None):
|
|
30
|
+
if param_dict is None:
|
|
31
|
+
return f'/api/{class_name}/{function_name}'
|
|
32
|
+
else:
|
|
33
|
+
return f'/api/{class_name}/{function_name}?' + '&'.join([f'{k}={v}' for k, v in param_dict.items()])
|
|
34
|
+
|
|
35
|
+
def read(self, class_name, function_name, param_dict={}):
|
|
36
|
+
pass
|
|
37
|
+
|
|
38
|
+
def delete(self, class_name, function_name, param_dict={}):
|
|
39
|
+
pass
|
|
40
|
+
|
|
41
|
+
def create(self, class_name, function_name, body, param_dict={}):
|
|
42
|
+
pass
|
|
43
|
+
|
|
44
|
+
def update(self, class_name, function_name, body, param_dict={}):
|
|
45
|
+
pass
|
|
46
|
+
|
|
47
|
+
class HttpProxy(CRUDProxy):
|
|
48
|
+
|
|
49
|
+
def __init__(self, host, port):
|
|
50
|
+
self._host = host
|
|
51
|
+
self._port = port
|
|
52
|
+
self._base_url = 'http://' + self._host + ':' + str(self._port)
|
|
53
|
+
pass
|
|
54
|
+
|
|
55
|
+
def _do_response(self, response):
|
|
56
|
+
if response.status_code == 200:
|
|
57
|
+
ct = response.headers.get('content-type', None)
|
|
58
|
+
if ct and ct == 'application/json':
|
|
59
|
+
return response.json()
|
|
60
|
+
elif ct and ct == 'image/png':
|
|
61
|
+
return Image.open(BytesIO(response.content)).convert('RGB')
|
|
62
|
+
else:
|
|
63
|
+
raise error_code_and_ex[response.status_code]()
|
|
64
|
+
|
|
65
|
+
def read(self, class_name, function_name, param_dict={}):
|
|
66
|
+
url = self._url(class_name, function_name, param_dict)
|
|
67
|
+
return self._get(url)
|
|
68
|
+
|
|
69
|
+
def delete(self, class_name, function_name, param_dict={}):
|
|
70
|
+
url = self._url(class_name, function_name, param_dict)
|
|
71
|
+
return self._delete(url)
|
|
72
|
+
|
|
73
|
+
def create(self, class_name, function_name, body: dict, param_dict: dict={}):
|
|
74
|
+
url = self._url(class_name, function_name, param_dict)
|
|
75
|
+
return self._post(url, body)
|
|
76
|
+
|
|
77
|
+
def update(self, class_name, function_name, body, param_dict={}, profile=None):
|
|
78
|
+
url = self._url(class_name, function_name, param_dict)
|
|
79
|
+
return self._patch(url, body, profile=profile)
|
|
80
|
+
|
|
81
|
+
def _get(self, url):
|
|
82
|
+
with httpx.Client() as client:
|
|
83
|
+
return self._do_response(client.get(self._base_url + url))
|
|
84
|
+
return None
|
|
85
|
+
|
|
86
|
+
def _delete(self, url):
|
|
87
|
+
with httpx.Client() as client:
|
|
88
|
+
return self._do_response(client.delete(self._base_url + url))
|
|
89
|
+
return None
|
|
90
|
+
|
|
91
|
+
def create(self, url, data):
|
|
92
|
+
with httpx.Client() as client:
|
|
93
|
+
return self._do_response(client.create(self._base_url + url,
|
|
94
|
+
data=json.dumps(data),
|
|
95
|
+
headers={"Content-Type": "application/json"}
|
|
96
|
+
))
|
|
97
|
+
return None
|
|
98
|
+
|
|
99
|
+
def _post(self, url, data):
|
|
100
|
+
with httpx.Client() as client:
|
|
101
|
+
return self._do_response(client.post(self._base_url + url,
|
|
102
|
+
data=json.dumps(data),
|
|
103
|
+
headers={"Content-Type": "application/json"}
|
|
104
|
+
))
|
|
105
|
+
return None
|
|
106
|
+
|
|
107
|
+
def _patch(self, url, data, profile=None):
|
|
108
|
+
with httpx.Client() as client:
|
|
109
|
+
img_key_value = None
|
|
110
|
+
serializable_data = {}
|
|
111
|
+
if isinstance(data, Image.Image):
|
|
112
|
+
#print('prof:', profile)
|
|
113
|
+
pass
|
|
114
|
+
else:
|
|
115
|
+
for k, v in data.items():
|
|
116
|
+
if isinstance(v, Image.Image):
|
|
117
|
+
img_key_value = (k, v)
|
|
118
|
+
else:
|
|
119
|
+
serializable_data[k] = v
|
|
120
|
+
if img_key_value is not None:
|
|
121
|
+
output = io.BytesIO()
|
|
122
|
+
img_key_value[1].save(output, 'PNG')
|
|
123
|
+
files = {}
|
|
124
|
+
for k, v in serializable_data.items():
|
|
125
|
+
files[k] = (None, v, "application/json")
|
|
126
|
+
files[img_key_value[0]] = (None, output.getvalue(), "image/png")
|
|
127
|
+
return self._do_response(client.put(self._base_url + url,
|
|
128
|
+
# data=json.dumps(serializable_data),
|
|
129
|
+
headers={"Content-Type": "multipart/form-data; boundary=+++"},
|
|
130
|
+
#files={img_key_value[0]: (None, output.getvalue(), "image/png")}))
|
|
131
|
+
files=files))
|
|
132
|
+
else:
|
|
133
|
+
return self._do_response(client.patch(self._base_url + url,
|
|
134
|
+
data=json.dumps(data),
|
|
135
|
+
headers={"Content-Type": "application/json"}
|
|
136
|
+
))
|
|
137
|
+
return None
|
|
138
|
+
|
|
139
|
+
class SystemProxy():
|
|
140
|
+
|
|
141
|
+
def __init__(self, base_proxy: CRUDProxy):
|
|
142
|
+
self.crud = base_proxy
|
|
143
|
+
self._processes = None
|
|
144
|
+
self._containers = None
|
|
145
|
+
self._container_processes = None
|
|
146
|
+
pass
|
|
147
|
+
|
|
148
|
+
def profile_full(self, update=False):
|
|
149
|
+
return self.crud.read('system', 'profile_full')
|
|
150
|
+
|
|
151
|
+
def create_process(self, type_name, name, use_memo=True):
|
|
152
|
+
return self.crud.create('/api/process/', {
|
|
153
|
+
"type_name": type_name,
|
|
154
|
+
"name": name,
|
|
155
|
+
"use_memo": use_memo})
|
|
156
|
+
|
|
157
|
+
def processes(self):
|
|
158
|
+
ps = self.crud.read('process', 'list')
|
|
159
|
+
self._processes = [ProcessProxy.new(self, pid) for pid in ps]
|
|
160
|
+
return self._processes.copy()
|
|
161
|
+
|
|
162
|
+
def process(self, id):
|
|
163
|
+
ps = self.crud.read('process', 'list')
|
|
164
|
+
for pid in ps:
|
|
165
|
+
if pid == id:
|
|
166
|
+
return ProcessProxy.new(self, pid)
|
|
167
|
+
return None
|
|
168
|
+
|
|
169
|
+
def containers(self, update=False):
|
|
170
|
+
ps = self.crud.read('container', 'list')
|
|
171
|
+
self._containers = [ContainerProxy.new(self, pid) for pid in ps]
|
|
172
|
+
return self._containers
|
|
173
|
+
|
|
174
|
+
def container(self, id):
|
|
175
|
+
cs = self.crud.read('container', 'list')
|
|
176
|
+
for pid in cs:
|
|
177
|
+
if pid == id:
|
|
178
|
+
return ContainerProxy.new(self, pid)
|
|
179
|
+
return None
|
|
180
|
+
|
|
181
|
+
def container_processes(self, update=False):
|
|
182
|
+
ps = self.crud.read('container_process','list')
|
|
183
|
+
if self._container_processes is None or update:
|
|
184
|
+
self._container_processes = [ContainerProcessProxy(self, p) for p in ps]
|
|
185
|
+
return self._container_processes
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
class ObjectProxy(object):
|
|
189
|
+
|
|
190
|
+
def __init__(self, system_proxy, class_name, identifier):
|
|
191
|
+
self.system = system_proxy
|
|
192
|
+
self._id = identifier
|
|
193
|
+
self._cn = class_name
|
|
194
|
+
self._profile = None
|
|
195
|
+
self._name = id_to_name(identifier) if identifier is not None else None
|
|
196
|
+
self._type_name = None
|
|
197
|
+
|
|
198
|
+
def profile_full(self, update=False):
|
|
199
|
+
if self._profile is None or update:
|
|
200
|
+
self._profile = self.system.crud.read(self._cn, 'profile_full', {'identifier': self._id})
|
|
201
|
+
return self._profile
|
|
202
|
+
|
|
203
|
+
def identifier(self, update=False):
|
|
204
|
+
return self._id
|
|
205
|
+
|
|
206
|
+
def name(self):
|
|
207
|
+
if self._name is None:
|
|
208
|
+
self._name = id_to_name(self._id)
|
|
209
|
+
return self._name
|
|
210
|
+
|
|
211
|
+
def type_name(self):
|
|
212
|
+
if self._type_name is None:
|
|
213
|
+
self._type_name = id_to_type_name(self._id)
|
|
214
|
+
return self._type_name
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def destroy(self):
|
|
218
|
+
return self._system_proxy.delete('/api/' + self._class_name + '/destroy?identifier=' + self._identifier)
|
|
219
|
+
|
|
220
|
+
class ProcessProxy(ObjectProxy):
|
|
221
|
+
def __init__(self, name, host, port, protocol='http'):
|
|
222
|
+
if protocol is None:
|
|
223
|
+
super().__init__(None, 'process', None)
|
|
224
|
+
self._name = name
|
|
225
|
+
elif protocol == 'http':
|
|
226
|
+
super().__init__(SystemProxy(HttpProxy(host,port)), 'process', None)
|
|
227
|
+
self._name = None
|
|
228
|
+
for p in self.system.processes():
|
|
229
|
+
if p.name() == name:
|
|
230
|
+
self._id = p.identifier()
|
|
231
|
+
return
|
|
232
|
+
|
|
233
|
+
def __repr__(self):
|
|
234
|
+
return f'ProcessProxy("{self.identifier()}")'
|
|
235
|
+
|
|
236
|
+
@classmethod
|
|
237
|
+
def new(cls, system_proxy, identifier):
|
|
238
|
+
p = ProcessProxy(None, None, None, protocol=None)
|
|
239
|
+
p.system = system_proxy
|
|
240
|
+
p._id = identifier
|
|
241
|
+
return p
|
|
242
|
+
|
|
243
|
+
def call(self, *args, **kwargs):
|
|
244
|
+
prof = self.profile_full()
|
|
245
|
+
if len(args) == 1:
|
|
246
|
+
arg_prof = prof['arguments']
|
|
247
|
+
body = {
|
|
248
|
+
arg_prof[0]['name']: args[0]
|
|
249
|
+
}
|
|
250
|
+
elif 'body' in kwargs.keys():
|
|
251
|
+
body = kwargs['body']
|
|
252
|
+
else:
|
|
253
|
+
body = {}
|
|
254
|
+
args_prof = prof['arguments']
|
|
255
|
+
for a, a_prof in zip(args, args_prof):
|
|
256
|
+
if isinstance(a, Image.Image):
|
|
257
|
+
body[a_prof['name']] = a
|
|
258
|
+
else:
|
|
259
|
+
body[a_prof['name']] = json.dumps(a)
|
|
260
|
+
for k, v in kwargs.items():
|
|
261
|
+
body[k] = v
|
|
262
|
+
return self.system.crud.update(self._cn, 'call', body, {'identifier': self._id}, profile=self._profile)
|
|
263
|
+
|
|
264
|
+
def __call__(self, *args, **kwargs):
|
|
265
|
+
return self.call(*args, **kwargs)
|
|
266
|
+
|
|
267
|
+
def execute(self):
|
|
268
|
+
return self.system.crud.update(self._cn, 'execute', {}, {'identifier': self._id})
|
|
269
|
+
|
|
270
|
+
def p_apply(self, arg_name: str, value: dict):
|
|
271
|
+
return self.system.crud.update(self._cn, 'p_apply', {'arg_name': arg_name, 'value': value}, {'identifier': self._id})
|
|
272
|
+
|
|
273
|
+
class ContainerProxy(ObjectProxy):
|
|
274
|
+
|
|
275
|
+
def __init__(self, name, host, port, protocol='http'):
|
|
276
|
+
if protocol is None:
|
|
277
|
+
super().__init__(None, 'container', None)
|
|
278
|
+
self._name = name
|
|
279
|
+
elif protocol == 'http':
|
|
280
|
+
super().__init__(SystemProxy(HttpProxy(host,port)), 'container', None)
|
|
281
|
+
self._name = None
|
|
282
|
+
for c in self.system.containers():
|
|
283
|
+
# print(c.type_name(), name)
|
|
284
|
+
if c.type_name() == name:
|
|
285
|
+
self._id = c.identifier()
|
|
286
|
+
return
|
|
287
|
+
|
|
288
|
+
@classmethod
|
|
289
|
+
def new(cls, system_proxy, identifier):
|
|
290
|
+
p = ContainerProxy(None, None, None, protocol=None)
|
|
291
|
+
p.system = system_proxy
|
|
292
|
+
p._id = identifier
|
|
293
|
+
return p
|
|
294
|
+
|
|
295
|
+
def __repr__(self):
|
|
296
|
+
return f'ContainerProxy("{self.identifier()}")'
|
|
297
|
+
|
|
298
|
+
def processes(self):
|
|
299
|
+
pids = self.profile_full()['processes']
|
|
300
|
+
return [ContainerProcessProxy(self.system, pid) for pid in pids]
|
|
301
|
+
|
|
302
|
+
def process(self, id):
|
|
303
|
+
pids = self.profile_full()['processes']
|
|
304
|
+
for pid in pids:
|
|
305
|
+
if pid == id:
|
|
306
|
+
return ContainerProcessProxy(self.system, pid)
|
|
307
|
+
return None
|
|
308
|
+
|
|
309
|
+
def __getattr__(self, name):
|
|
310
|
+
# search process by name:
|
|
311
|
+
ps = self.processes()
|
|
312
|
+
for p in ps:
|
|
313
|
+
if p.type_name() == name:
|
|
314
|
+
return p
|
|
315
|
+
for p in ps:
|
|
316
|
+
if p.name() == name:
|
|
317
|
+
return p
|
|
318
|
+
raise AttributeError(self, name)
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
class ContainerProcessProxy(ObjectProxy):
|
|
322
|
+
def __init__(self, system_proxy, identifier):
|
|
323
|
+
super().__init__(system_proxy, 'container_process', identifier)
|
|
324
|
+
|
|
325
|
+
def __repr__(self):
|
|
326
|
+
return f'ContainerProcess("{self.identifier()}")'
|
|
327
|
+
|
|
328
|
+
def call(self, *args, **kwargs):
|
|
329
|
+
prof = self.profile_full()
|
|
330
|
+
if len(args) == 1:
|
|
331
|
+
arg_prof = prof['arguments']
|
|
332
|
+
body = {
|
|
333
|
+
arg_prof[0]['name']: args[0]
|
|
334
|
+
}
|
|
335
|
+
#body = args[0]
|
|
336
|
+
elif 'body' in kwargs.keys():
|
|
337
|
+
body = kwargs['body']
|
|
338
|
+
else:
|
|
339
|
+
body = {}
|
|
340
|
+
args_prof = prof['arguments']
|
|
341
|
+
for a, a_prof in zip(args, args_prof):
|
|
342
|
+
if isinstance(a, Image.Image):
|
|
343
|
+
body[a_prof['name']] = a
|
|
344
|
+
else:
|
|
345
|
+
body[a_prof['name']] = json.dumps(a)
|
|
346
|
+
for k, v in kwargs.items():
|
|
347
|
+
body[k] = v
|
|
348
|
+
#body = kwargs
|
|
349
|
+
return self.system.crud.update(self._cn, 'call', body, {'identifier': self._id}, profile=self.profile_full())
|
|
350
|
+
|
|
351
|
+
def __call__(self, *args, **kwargs):
|
|
352
|
+
return self.call(*args, **kwargs)
|
|
353
|
+
|
|
354
|
+
def execute(self):
|
|
355
|
+
return self.system.crud.update(self._cn, 'execute', {}, {'identifier': self._id}, profile=self._profile)
|
|
356
|
+
|
|
357
|
+
def p_apply(self, arg_name: str, value: dict):
|
|
358
|
+
return self.system.crud.update(self._cn, 'p_apply', {'arg_name': arg_name, 'value': value}, {'identifier': self._id})
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
class IdentifierStruct(object):
|
|
362
|
+
|
|
363
|
+
def __init__(self, broker_type, broker_name, class_name, type_name, name):
|
|
364
|
+
self.broker_type = broker_type
|
|
365
|
+
self.broker_name = broker_name
|
|
366
|
+
self.class_name = class_name
|
|
367
|
+
self.type_name = type_name
|
|
368
|
+
self.name = name
|
|
369
|
+
|
|
370
|
+
@classmethod
|
|
371
|
+
def fromIdentifier(self, id):
|
|
372
|
+
s, type_name = id.split('::')
|
|
373
|
+
broker_type, s2 = s.split('://')
|
|
374
|
+
broker_name, class_name, name = s2.split('/')
|
|
375
|
+
return IdentifierStruct(broker_type, broker_name, class_name, type_name, name)
|
|
376
|
+
|
|
377
|
+
def to_id(self):
|
|
378
|
+
return f'{self.broker_type}://{self.broker_name}/{self.class_name}/{self.name}::{self.type_name}'
|
|
379
|
+
|
|
380
|
+
def __repr__(self):
|
|
381
|
+
return f'IdentifierStruct(broker_type="{self.broker_type}",broker_name="{self.broker_name}",class_name="{self.class_name}",type_name="{self.type_name}",name="{self.name}")'
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
def id_to_name(id: str):
|
|
385
|
+
if id.find('://') > 0: # 通常IDフォーマット。プロトコルあり
|
|
386
|
+
# print('id=', id)
|
|
387
|
+
broker_type, id_body = id.split('://')
|
|
388
|
+
broker_name, class_name, name_and_type = id_body.split('/')
|
|
389
|
+
name, type_name = name_and_type.split('::')
|
|
390
|
+
return name
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
def id_to_type_name(id: str):
|
|
394
|
+
if id.find('://') > 0: # 通常IDフォーマット。プロトコルあり
|
|
395
|
+
# print('id=', id)
|
|
396
|
+
broker_type, id_body = id.split('://')
|
|
397
|
+
broker_name, class_name, name_and_type = id_body.split('/')
|
|
398
|
+
name, type_name = name_and_type.split('::')
|
|
399
|
+
return type_name
|
|
400
|
+
|
|
401
|
+
if __name__ == '__main__':
|
|
402
|
+
i = 'core://core/process/hoge_process_name0::hoge_process'
|
|
403
|
+
print(id_to_name(i))
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyjuiz
|
|
3
|
+
Version: 0.0.2
|
|
4
|
+
Summary: Python binding interface for JUIZ robot middleware components
|
|
5
|
+
Home-page: https://github.com/juiz
|
|
6
|
+
Author: ysuga
|
|
7
|
+
Author-email: ysuga@ysuga.net
|
|
8
|
+
License: MIT
|
|
9
|
+
Keywords: robot,middleware
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
11
|
+
Requires-Dist: yaml
|
|
12
|
+
Requires-Dist: httpx
|
|
13
|
+
Requires-Dist: pillow
|
|
14
|
+
Dynamic: author
|
|
15
|
+
Dynamic: author-email
|
|
16
|
+
Dynamic: classifier
|
|
17
|
+
Dynamic: home-page
|
|
18
|
+
Dynamic: keywords
|
|
19
|
+
Dynamic: license
|
|
20
|
+
Dynamic: requires-dist
|
|
21
|
+
Dynamic: summary
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
setup.py
|
|
3
|
+
juiz/__init__.py
|
|
4
|
+
juiz/__main__.py
|
|
5
|
+
juiz/decorators.py
|
|
6
|
+
juiz/juiz.py
|
|
7
|
+
juiz/proxy/__init__.py
|
|
8
|
+
pyjuiz.egg-info/PKG-INFO
|
|
9
|
+
pyjuiz.egg-info/SOURCES.txt
|
|
10
|
+
pyjuiz.egg-info/dependency_links.txt
|
|
11
|
+
pyjuiz.egg-info/requires.txt
|
|
12
|
+
pyjuiz.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
juiz
|
pyjuiz-0.0.2/setup.cfg
ADDED
pyjuiz-0.0.2/setup.py
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
setup(
|
|
4
|
+
name="pyjuiz",
|
|
5
|
+
version="0.0.2",
|
|
6
|
+
description='Python binding interface for JUIZ robot middleware components',
|
|
7
|
+
url='https://github.com/juiz',
|
|
8
|
+
author='ysuga',
|
|
9
|
+
author_email='ysuga@ysuga.net',
|
|
10
|
+
license='MIT',
|
|
11
|
+
keywords='robot,middleware',
|
|
12
|
+
install_requires=["yaml", "httpx", "pillow"],
|
|
13
|
+
extras_require={
|
|
14
|
+
#"develop": ["dev-packageA", "dev-packageB"]
|
|
15
|
+
},
|
|
16
|
+
packages=find_packages(),
|
|
17
|
+
classifiers=[
|
|
18
|
+
'Programming Language :: Python :: 3.10',
|
|
19
|
+
],
|
|
20
|
+
)
|