unisi 0.1.7__py3-none-any.whl → 0.1.8__py3-none-any.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.
unisi/__init__.py CHANGED
@@ -4,4 +4,3 @@ from .users import User, handle
4
4
  from .server import start
5
5
  from .tables import *
6
6
  from .containers import *
7
- from .proxy import *
unisi/users.py CHANGED
@@ -194,7 +194,7 @@ class User:
194
194
  if elem:
195
195
  return self.process_element(elem, message)
196
196
 
197
- error = f'Element {message.block}>>{message.element} does not exists!'
197
+ error = f'Element {message.block}>>{message.element} does not exist!'
198
198
  self.log(error)
199
199
  return Error(error)
200
200
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: unisi
3
- Version: 0.1.7
3
+ Version: 0.1.8
4
4
  Summary: UNified System Interface, GUI and proxy
5
5
  Author-Email: UNISI Tech <g.dernovoy@gmail.com>
6
6
  License: Apache-2.0
@@ -30,8 +30,6 @@ UNISI technology provides a unified system interface and advanced program functi
30
30
  - Integral autotesting
31
31
  - Protocol schema auto validation
32
32
  - Shared sessions
33
- - Voice interaction (not released yet)
34
- - Remote GUI interaction and pipelining (not released yet)
35
33
 
36
34
  ### Installing ###
37
35
  ```
@@ -39,7 +37,7 @@ pip install unisi
39
37
  ```
40
38
 
41
39
  ### Programming ###
42
- This repo explains how to work with Unisi using Python and the tiny but optimal framework for that. Unisi web version is included in this library. Supports Python 3.8 and up.
40
+ This repo explains how to work with Unisi using Python and the tiny but optimal framework for that. Unisi web version is included in this library. Supports Python 3.10 and up.
43
41
 
44
42
 
45
43
  ### High level - Screen ###
@@ -336,12 +334,12 @@ Graph supports an interactive graph.
336
334
  ```
337
335
  graph = Graph('X graph', graph_value, graph_selection,
338
336
  nodes = [
339
- { 'id' : 'node1', 'label': "Node 1" },
340
- { 'id' : 'node2', 'label': "Node 2" },
341
- { 'id' : 'node3', 'label': "Node 3" }
337
+ { 'id' : 'node1', 'name': "Node 1" },
338
+ { 'id' : 'node2', 'name': "Node 2" },
339
+ { 'id' : 'node3', 'name': "Node 3" }
342
340
  ], edges = [
343
- { 'id' : 'edge1', 'source': "node1", 'target': "node2", 'label' : 'extending' },
344
- { 'id' :'edge2' , 'source': "node2", 'target': "node3" , 'label' : 'extending'}
341
+ { 'id' : 'edge1', 'source': "node1", 'target': "node2", 'name' : 'extending' },
342
+ { 'id' :'edge2' , 'source': "node2", 'target': "node3" , 'name' : 'extending'}
345
343
  ])
346
344
  ```
347
345
  where graph_value is a dictionary like {'nodes' : ["node1"], 'edges' : ['edge3']}, where enumerations are selected nodes and edges.
@@ -1,7 +1,7 @@
1
- unisi-0.1.7.dist-info/METADATA,sha256=Daai6No7h9RdMN_B8Kp0hcFvpdJTpZfBbze_f2bnxVE,17788
2
- unisi-0.1.7.dist-info/WHEEL,sha256=N2J68yzZqJh3mI_Wg92rwhw0rtJDFpZj9bwQIMJgaVg,90
3
- unisi-0.1.7.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
4
- unisi/__init__.py,sha256=bQ7yTDcgybkbIGTjxkajTbBJXtgyryrCvt3nXg8QxlQ,175
1
+ unisi-0.1.8.dist-info/METADATA,sha256=rBUW89zbtC9urbRQ1mzUAcdU786z5oJyYT1QCHMx860,17684
2
+ unisi-0.1.8.dist-info/WHEEL,sha256=N2J68yzZqJh3mI_Wg92rwhw0rtJDFpZj9bwQIMJgaVg,90
3
+ unisi-0.1.8.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
4
+ unisi/__init__.py,sha256=z7fP6b-R1l4VZmc0tFXz4-Uay5y1kSzMm3xbWl5Zh-g,154
5
5
  unisi/autotest.py,sha256=mkvfUuxO7co9QcninjBSS9u-zJSva9H_51k3m6sd3rw,9485
6
6
  unisi/common.py,sha256=jsZpOkZIQdfPZjrTIoO1OLiZfQ_spEpMCX3td269RR0,635
7
7
  unisi/containers.py,sha256=Me28aZkhchWJA5OExtXoFzl2u5bc6p0m2Cww7CfKIbA,4200
@@ -11,11 +11,10 @@ unisi/jsoncomparison/compare.py,sha256=qPDaxd9n0GgiNd2SgrcRWvRDoXGg7NStViP9PHk2t
11
11
  unisi/jsoncomparison/config.py,sha256=LbdLJE1KIebFq_tX7zcERhPvopKhnzcTqMCnS3jN124,381
12
12
  unisi/jsoncomparison/errors.py,sha256=wqphE1Xn7K6n16uvUhDC45m2BxbsMUhIF2olPbhqf4o,1192
13
13
  unisi/jsoncomparison/ignore.py,sha256=xfF0a_BBEyGdZBoq-ovpCpawgcX8SRwwp7IrGnu1c2w,2634
14
- unisi/proxy.py,sha256=sMnGEs480wiic91AGH9hrDAisc0gDUEKKHX_nC3v3_E,7559
15
14
  unisi/reloader.py,sha256=B0f9GU452epFvdih8sH7_NiIJrXnC5i27uw2imGQxMg,6585
16
15
  unisi/server.py,sha256=5oax_OGWGPNm1smQM_8EpCb1jKia2s7IBnIfjIr1Z2w,4583
17
16
  unisi/tables.py,sha256=v7Fio5iIN7u1t7cE4Yvl4ewn7jTmmNPyWigoKW1Mj8U,4239
18
- unisi/users.py,sha256=B3Ouj-Ygx9BYU64JtE_HM4yApIZ7ikVeH2v86Lr1rSA,9819
17
+ unisi/users.py,sha256=JD4AD0WyuJQK31juWURqHwbeHF-016nifGQBZutHSPI,9818
19
18
  unisi/utils.py,sha256=6iDXECQE_44v8m6fvte_PXM0Ku6ZV-8LkAqMcNSMYdk,2975
20
19
  unisi/web/css/847.64dbc68c.css,sha256=ckeNz4l2QkIp60LdV_-cEXf9orp0ZVklEbrQfjkAG5M,2691
21
20
  unisi/web/css/app.31d6cfe0.css,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -39,4 +38,4 @@ unisi/web/js/430.591e9a73.js,sha256=7S1CJTwGdE2EKXzeFRcaYuTrn0QteoVI03Hykz8qh3s,
39
38
  unisi/web/js/847.c4ea8fe3.js,sha256=el_JqiK9zS97V_UDUjlkbwIM8NQ4Y0Yt2WMMRoNm3UM,56531
40
39
  unisi/web/js/app.8224dd96.js,sha256=aKvusY5mySDAmto_L53gUEV2njTSU6JZKWGe_TXtlK8,5923
41
40
  unisi/web/js/vendor.d6797c01.js,sha256=2aKM3Lfxc0pHSirrcUReL1LcvDYWnfeBj2c67XsSELk,1279477
42
- unisi-0.1.7.dist-info/RECORD,,
41
+ unisi-0.1.8.dist-info/RECORD,,
unisi/proxy.py DELETED
@@ -1,202 +0,0 @@
1
- from websocket import create_connection
2
- from enum import IntFlag
3
- import json, requests, os
4
- from .common import *
5
-
6
- class Event(IntFlag):
7
- none = 0
8
- update = 1
9
- invalid = 2
10
- message = 4
11
- update_message = 6
12
- progress = 12
13
- update_progress = 13
14
- unknown = 16
15
- unknown_update = 17
16
- dialog = 32
17
- screen = 65
18
- complete = 128
19
- append = 256
20
-
21
- ws_header = 'ws://'
22
- wss_header = 'wss://'
23
- ws_path = 'ws'
24
-
25
- message_types = ['error','warning','info']
26
-
27
- class Proxy:
28
- """UNISI proxy"""
29
- def __init__(self, host_port, timeout = 7, ssl = False):
30
- addr_port = f'{wss_header if ssl else ws_header}{host_port}'
31
- addr_port = f'{addr_port}{"" if addr_port.endswith("/") else "/"}{ws_path}'
32
- self.host_port = f'{"https" if ssl else "http"}://{host_port}'
33
- self.conn = create_connection(addr_port, timeout = timeout)
34
- self.screen = None
35
- self.screens = {}
36
- self.dialog = None
37
- self.event = None
38
- self.request(None)
39
-
40
- def close(self):
41
- self.conn.close()
42
-
43
- @property
44
- def screen_menu(self):
45
- return [name_icon[0] for name_icon in self.screen['menu']] if self.screen else []
46
-
47
- @property
48
- def commands(self):
49
- """return command objects"""
50
- return self.elements(types=['command'])
51
-
52
- def element(self, name, block_name = None):
53
- """return the element only if 1 element has such name"""
54
- result = None
55
- name2block = self.screen['name2block']
56
- for block in [name2block[block_name]] if block_name else name2block.values():
57
- for el in flatten(block['value']):
58
- if el['name'] == name:
59
- if not result:
60
- result = el
61
- else:
62
- return None
63
- return result
64
-
65
- def elements(self, block = None, types = None):
66
- """get elements with filtering types and blocks"""
67
- if block:
68
- return [el for el in flatten(block['value']) if not types or el['type'] in types]
69
- answer = []
70
- for block in self.screen['name2block'].values():
71
- answer.extend([el for el in flatten(block['value']) if not types or el['type'] in types])
72
- return answer
73
-
74
- def block_name(self, element):
75
- is_name = isinstance(element, str)
76
- for block in self.screen['name2block'].values():
77
- for el in flatten(block['value']):
78
- if el['name'] == element if is_name else el == element:
79
- return block['name']
80
-
81
- def upload(self, fpath):
82
- """upload file to the server and get its server path"""
83
- file = open(fpath, "rb")
84
- response = requests.post(self.host_port, files = {os.path.basename(fpath): file})
85
- return getattr(response, 'text', '')
86
-
87
- def command(self, command, value = None):
88
- return self.interact(self.make_message(command, value))
89
-
90
- def command_upload(self, command, fpath):
91
- """upload file to the server and call command"""
92
- spath = self.upload(fpath)
93
- return self.command(command, spath) if spath else Event.invalid
94
-
95
- def make_message(self, element, value = None, event = 'changed'):
96
- if isinstance(element, str):
97
- element = self.element(element)
98
- if event != 'changed' and event not in element:
99
- return None
100
- return ArgObject(block = self.block_name(element), element = element['name'],
101
- event = event, value = value)
102
-
103
- def interact(self, message, progress_callback = None):
104
- """progress_callback is def (proxy:Proxy)"""
105
- while self.request(message) & Event.progress:
106
- if progress_callback:
107
- progress_callback(self)
108
- message = None
109
- return self.event
110
-
111
- def request(self, message):
112
- """send message or message list, get responce, return the responce type"""
113
- if message:
114
- self.conn.send(toJson(message))
115
- responce = self.conn.recv()
116
- message = json.loads(responce)
117
- return self.process(message)
118
-
119
- def set_value(self, element, new_value):
120
- if isinstance(element, str):
121
- element = self.element(element)
122
- element['value'] = new_value
123
- ms = self.make_message(element, new_value)
124
- return self.interact(ms) if ms else Event.invalid
125
-
126
- def set_screen(self, name):
127
- screen = self.screens.get(name)
128
- if not screen:
129
- if name in self.screen_menu:
130
- mtype = self.request(ArgObject(block = 'root', element = None, value = name))
131
- return mtype == Event.screen
132
- else:
133
- return False
134
- return True
135
-
136
- @property
137
- def dialog_commands(self):
138
- return self.dialog['commands'] if self.dialog else []
139
-
140
- def dialog_responce(self, command: str | None):
141
- if not self.dialog:
142
- self.event = Event.invalid
143
- return self.event
144
- return self.interact(ArgObject(block = self.dialog['name'], value = command))
145
-
146
- def process(self, message):
147
- self.message = message
148
- if not message:
149
- self.event = Event.none
150
- self.mtype = None
151
- else:
152
- mtype = message.get('type')
153
- self.mtype = mtype
154
- if mtype == 'screen':
155
- self.screen = message
156
- self.screens[self.screen['name']] = message
157
- name2block = {block['name']: block for block in flatten(message['blocks'])}
158
- name2block['toolbar'] = {'name': 'toolbar', 'value': message['toolbar']}
159
- message['name2block'] = name2block
160
- self.event = Event.screen
161
- elif mtype == 'dialog':
162
- self.dialog = message
163
- self.event = Event.dialog
164
- elif mtype == 'complete':
165
- return Event.complete
166
- elif mtype == 'append':
167
- self.event = Event.append
168
- elif mtype == 'update':
169
- self.update(message)
170
- self.event = Event.update
171
- else:
172
- updates = message.get('updates')
173
- if updates:
174
- self.update(message)
175
- if type in message_types:
176
- self.event = Event.update_message if updates else Event.message
177
- if type == 'progress':
178
- self.event = Event.update_progress if updates else Event.progress
179
- else:
180
- self.event = Event.unknown_update if updates else Event.unknown
181
- return self.event
182
-
183
- def update(self, message):
184
- """update screen from the message"""
185
- result = Event.update
186
- updates = message.updates
187
- for update in updates:
188
- path = update['path']
189
- name2block = self.screen['name2block']
190
- if len(path) == 1: #block
191
- name2block[block] = update['data']
192
- else:
193
- block, element = path
194
- for el in flatten(name2block[block]['value']):
195
- if el['name'] == element:
196
- el.__dict__ = update['data'].__dict__
197
- break
198
- else:
199
- result = Event.unknown_update
200
- return result
201
-
202
-
File without changes