cloudpss 4.0.2a1__py3-none-any.whl → 4.1.1a2__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.
- cloudpss/__init__.py +2 -2
- cloudpss/function/functionExecution.py +1 -1
- cloudpss/ieslab/IESLabPlan.py +0 -87
- cloudpss/ieslab/IESLabSimulation.py +2 -62
- cloudpss/job/job.py +98 -135
- cloudpss/job/messageStreamReceiver.py +59 -53
- cloudpss/job/messageStreamSender.py +38 -33
- cloudpss/model/implements/diagram.py +0 -113
- cloudpss/model/model.py +365 -364
- cloudpss/model/revision.py +9 -9
- cloudpss/model/topology.py +9 -2
- cloudpss/runner/__init__.py +5 -3
- cloudpss/runner/receiver.py +2 -0
- cloudpss/runner/runner.py +91 -18
- cloudpss/utils/AsyncIterable.py +27 -0
- cloudpss/utils/__init__.py +5 -1
- cloudpss/utils/httpAsyncRequest.py +89 -0
- cloudpss/utils/httprequests.py +6 -1
- cloudpss/utils/yamlLoader.py +40 -41
- cloudpss/version.py +1 -1
- {cloudpss-4.0.2a1.dist-info → cloudpss-4.1.1a2.dist-info}/METADATA +4 -1
- {cloudpss-4.0.2a1.dist-info → cloudpss-4.1.1a2.dist-info}/RECORD +24 -22
- {cloudpss-4.0.2a1.dist-info → cloudpss-4.1.1a2.dist-info}/WHEEL +0 -0
- {cloudpss-4.0.2a1.dist-info → cloudpss-4.1.1a2.dist-info}/top_level.txt +0 -0
@@ -1,35 +1,30 @@
|
|
1
1
|
import logging
|
2
|
+
|
3
|
+
from cloudpss.utils.httpAsyncRequest import websocket_connect
|
2
4
|
from .jobReceiver import JobReceiver
|
3
5
|
import os
|
4
6
|
from urllib.parse import urlparse
|
5
|
-
import websocket
|
6
7
|
import pytz
|
7
|
-
|
8
|
-
|
9
|
-
utc_tz = pytz.timezone('UTC')
|
8
|
+
|
9
|
+
utc_tz = pytz.timezone("UTC")
|
10
10
|
|
11
11
|
from ..utils.IO import IO
|
12
12
|
|
13
13
|
|
14
14
|
class Message(object):
|
15
|
-
|
16
15
|
def __init__(self, id, token):
|
17
16
|
self.id = id
|
18
17
|
self.token = token
|
19
|
-
|
20
18
|
|
21
19
|
|
22
20
|
class MessageStreamReceiver(JobReceiver):
|
23
|
-
|
24
21
|
def __init__(self, job, dev=False):
|
25
22
|
super().__init__()
|
26
23
|
self.job = job
|
27
24
|
self.dev = dev
|
28
|
-
self.origin = os.environ.get(
|
29
|
-
'https://cloudpss.net/')
|
30
|
-
self.__hasOpen=False
|
25
|
+
self.origin = os.environ.get("CLOUDPSS_API_URL", "https://cloudpss.net/")
|
31
26
|
|
32
|
-
def receive(self, id, fr0m, on_open, on_message, on_error, on_close):
|
27
|
+
async def receive(self, id, fr0m, on_open, on_message, on_error, on_close):
|
33
28
|
"""
|
34
29
|
读取消息流中的数据
|
35
30
|
id: 消息流id
|
@@ -40,29 +35,30 @@ class MessageStreamReceiver(JobReceiver):
|
|
40
35
|
on_close: 连接关闭时的回调函数
|
41
36
|
"""
|
42
37
|
if id is None:
|
43
|
-
raise Exception(
|
38
|
+
raise Exception("id is None")
|
44
39
|
u = list(urlparse(self.origin))
|
45
|
-
head =
|
40
|
+
head = "wss" if u[0] == "https" else "ws"
|
46
41
|
|
47
|
-
path = head +
|
42
|
+
path = head + "://" + str(u[1]) + "/api/streams/id/" + id
|
48
43
|
if fr0m is not None:
|
49
|
-
path = path +
|
50
|
-
logging.info(f"
|
51
|
-
ws =
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
44
|
+
path = path + "&from=" + str(fr0m)
|
45
|
+
logging.info(f"MessageStreamReceiver data from websocket: {path}")
|
46
|
+
ws =await websocket_connect(
|
47
|
+
path,
|
48
|
+
open_func=on_open,
|
49
|
+
receive_func=on_message,
|
50
|
+
error_func=on_error,
|
51
|
+
closed_func=on_close,
|
52
|
+
)
|
53
|
+
|
57
54
|
return ws
|
58
|
-
|
55
|
+
|
59
56
|
###下面是兼容Receiver部分功能实现
|
60
57
|
|
61
|
-
def on_message(self,
|
62
|
-
data = IO.deserialize(message,
|
63
|
-
msg = IO.deserialize(data[
|
64
|
-
|
65
|
-
print(msg)
|
58
|
+
def on_message(self, message):
|
59
|
+
data = IO.deserialize(message, "ubjson")
|
60
|
+
msg = IO.deserialize(data["data"], "ubjson")
|
61
|
+
print(msg)
|
66
62
|
self.messages.append(msg)
|
67
63
|
# if msg and type(msg) is dict and msg.get('type', None) == 'terminate':
|
68
64
|
# self.close(ws)
|
@@ -70,12 +66,12 @@ class MessageStreamReceiver(JobReceiver):
|
|
70
66
|
def on_error(self, ws, error):
|
71
67
|
logging.info("MessageStreamReceiver error")
|
72
68
|
msg = {
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
69
|
+
"type": "log",
|
70
|
+
"verb": "create",
|
71
|
+
"version": 1,
|
72
|
+
"data": {
|
73
|
+
"level": "error",
|
74
|
+
"content": "websocket error",
|
79
75
|
},
|
80
76
|
}
|
81
77
|
self.messages.append(msg)
|
@@ -84,37 +80,47 @@ class MessageStreamReceiver(JobReceiver):
|
|
84
80
|
logging.info("MessageStreamReceiver close")
|
85
81
|
self._status = 0
|
86
82
|
msg = {
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
83
|
+
"type": "log",
|
84
|
+
"verb": "create",
|
85
|
+
"version": 1,
|
86
|
+
"data": {
|
87
|
+
"level": "error",
|
88
|
+
"content": "websocket closed",
|
93
89
|
},
|
94
90
|
}
|
95
91
|
self.messages.append(msg)
|
96
92
|
|
97
|
-
def on_open(self
|
93
|
+
def on_open(self):
|
94
|
+
logging.info(f"MessageStreamReceiver on_open")
|
98
95
|
self._status = 1
|
99
|
-
self.__hasOpen=True
|
96
|
+
self.__hasOpen = True
|
100
97
|
pass
|
101
98
|
|
102
99
|
def close(self, ws):
|
103
100
|
self._status = 0
|
104
101
|
ws.close()
|
105
102
|
|
103
|
+
@property
|
104
|
+
def status(self):
|
105
|
+
return self._status
|
106
|
+
|
106
107
|
@property
|
107
108
|
def end(self):
|
108
|
-
return
|
109
|
+
return not self._status
|
109
110
|
|
110
|
-
def connect(self):
|
111
|
+
async def connect(self):
|
111
112
|
self._status = 0
|
112
|
-
self.ws = self.receive(
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
113
|
+
self.ws = await self.receive(
|
114
|
+
self.job.output,
|
115
|
+
None,
|
116
|
+
self.on_open,
|
117
|
+
self.on_message,
|
118
|
+
self.on_error,
|
119
|
+
self.on_close,
|
120
|
+
)
|
121
|
+
|
122
|
+
# thread = threading.Thread(target=self.ws.run_forever, args=(None, None, 6, 3))
|
123
|
+
# thread.setDaemon(True)
|
124
|
+
# thread.start()
|
125
|
+
# while not self.__hasOpen:
|
126
|
+
# time.sleep(0.2)
|
@@ -1,7 +1,10 @@
|
|
1
|
-
import sys,os
|
1
|
+
import sys, os
|
2
2
|
import threading
|
3
3
|
from urllib.parse import urlparse
|
4
|
-
|
4
|
+
|
5
|
+
from cloudpss.utils.httpAsyncRequest import websocket_connect
|
6
|
+
|
7
|
+
sys.path.append(os.path.join(os.path.dirname(__file__), "../"))
|
5
8
|
|
6
9
|
import websocket
|
7
10
|
|
@@ -9,36 +12,34 @@ from cloudpss.utils.IO import IO
|
|
9
12
|
import time
|
10
13
|
import logging
|
11
14
|
|
12
|
-
class MessageStreamSender():
|
13
15
|
|
16
|
+
class MessageStreamSender:
|
14
17
|
def __init__(self, job, dev=False):
|
15
18
|
super().__init__()
|
16
19
|
self.job = job
|
17
20
|
self.dev = dev
|
18
|
-
self.origin = os.environ.get(
|
19
|
-
'https://cloudpss.net/')
|
21
|
+
self.origin = os.environ.get("CLOUDPSS_API_URL", "https://cloudpss.net/")
|
20
22
|
|
21
23
|
###下面是兼容Receiver部分功能实现
|
22
24
|
|
23
25
|
def on_message(self, ws, message):
|
24
|
-
logging.info(
|
26
|
+
logging.info("on_message", message)
|
25
27
|
|
26
28
|
def on_error(self, ws, error):
|
27
|
-
logging.info(
|
29
|
+
logging.info("on_error")
|
28
30
|
|
29
31
|
def on_close(self, *args, **kwargs):
|
30
32
|
time.sleep(0.5)
|
31
33
|
self._status = 0
|
32
|
-
|
33
|
-
logging.info('on_close')
|
34
34
|
|
35
|
-
|
35
|
+
logging.info("on_close")
|
36
|
+
|
37
|
+
def on_open(self):
|
36
38
|
self._status = 1
|
37
|
-
logging.info(
|
39
|
+
logging.info("on_open")
|
38
40
|
pass
|
39
41
|
|
40
42
|
def close(self):
|
41
|
-
|
42
43
|
self._status = 0
|
43
44
|
self.ws.close()
|
44
45
|
|
@@ -47,28 +48,32 @@ class MessageStreamSender():
|
|
47
48
|
return self._status
|
48
49
|
|
49
50
|
def write(self, message):
|
50
|
-
data = IO.serialize(message,
|
51
|
-
self.ws.
|
52
|
-
|
53
|
-
def connect(self):
|
54
|
-
logging.info('connect')
|
51
|
+
data = IO.serialize(message, "ubjson", None)
|
52
|
+
self.ws.send_bytes(data)
|
53
|
+
|
54
|
+
async def connect(self):
|
55
55
|
self._status = 0
|
56
56
|
if self.job.input is None:
|
57
|
-
raise Exception(
|
57
|
+
raise Exception("id is None")
|
58
|
+
if self.job.input=='00000000-0000-0000-0000-000000000000':
|
59
|
+
return
|
58
60
|
u = list(urlparse(self.origin))
|
59
|
-
head =
|
60
|
-
|
61
|
-
path = head + '://' + str(u[1]) + '/api/streams/token/' + self.job.input
|
62
|
-
logging.info(f"receive data from websocket: {path}")
|
63
|
-
|
64
|
-
self.ws = websocket.WebSocketApp(path,
|
65
|
-
on_open=self.on_open,
|
66
|
-
on_message=self.on_message,
|
67
|
-
on_error=self.on_error,
|
68
|
-
on_close=self.on_close)
|
61
|
+
head = "wss" if u[0] == "https" else "ws"
|
69
62
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
63
|
+
|
64
|
+
path = head + "://" + str(u[1]) + "/api/streams/token/" + self.job.input
|
65
|
+
logging.info(f"MessageStreamSender data from websocket: {path}")
|
66
|
+
|
67
|
+
self.ws = await websocket_connect(
|
68
|
+
path,
|
69
|
+
open_func=self.on_open,
|
70
|
+
receive_func=self.on_message,
|
71
|
+
error_func=self.on_error,
|
72
|
+
closed_func=self.on_close,
|
73
|
+
)
|
74
|
+
|
75
|
+
# thread = threading.Thread(target=self.ws.run_forever, args=(None, None, 6, 3))
|
76
|
+
# thread.setDaemon(True)
|
77
|
+
# thread.start()
|
78
|
+
# while self.status != 1:
|
79
|
+
# time.sleep(0.2)
|
@@ -1,6 +1,4 @@
|
|
1
1
|
from .component import Component
|
2
|
-
from typing import Optional
|
3
|
-
import uuid
|
4
2
|
|
5
3
|
|
6
4
|
class DiagramImplement(object):
|
@@ -46,114 +44,3 @@ class DiagramImplement(object):
|
|
46
44
|
"""
|
47
45
|
|
48
46
|
return self.cells
|
49
|
-
|
50
|
-
def addComponent(
|
51
|
-
self,
|
52
|
-
definition: str,
|
53
|
-
label: str,
|
54
|
-
args: dict = {},
|
55
|
-
pins: dict = {},
|
56
|
-
canvas: Optional[str] = None,
|
57
|
-
position: Optional[dict] = None,
|
58
|
-
size: Optional[dict] = None,
|
59
|
-
) -> Component:
|
60
|
-
"""
|
61
|
-
添加元件
|
62
|
-
|
63
|
-
:param definition 元件定义, 连接线没有definition
|
64
|
-
:param label 元件标签
|
65
|
-
:param args 元件参数数据,连接线没有参数数据
|
66
|
-
:param pins 元件引脚数据,连接线没有引脚数据
|
67
|
-
:param canvas 元件所在图纸数据
|
68
|
-
:param position 元件位置数据, 连接线没有位置数据
|
69
|
-
:param size 元件大小数据,连接线没有大小数据
|
70
|
-
|
71
|
-
:return: Component
|
72
|
-
|
73
|
-
>>>> diagram.addComponent(args)
|
74
|
-
"""
|
75
|
-
id = "comp_" + str(uuid.uuid4())
|
76
|
-
shape = "diagram-component"
|
77
|
-
definition = definition
|
78
|
-
label = label or definition
|
79
|
-
args = args.copy()
|
80
|
-
pins = pins.copy()
|
81
|
-
props = {"enabled": True}
|
82
|
-
context = {}
|
83
|
-
canvas or self.canvas[0].get("key", "canvas_0")
|
84
|
-
position = position.copy() if position else {"x": 0, "y": 0}
|
85
|
-
size = size.copy() if size else None
|
86
|
-
zIndex = 0
|
87
|
-
style = {
|
88
|
-
"--fill": "var(--spectrum-global-color-gray-100)",
|
89
|
-
"--fill-opacity": 1,
|
90
|
-
"--font-family": "var(--spectrum-global-font-family-base, Arial, Helvetica, sans-serif)",
|
91
|
-
"--stroke": "var(--spectrum-global-color-gray-900)",
|
92
|
-
"--stroke-opacity": 1,
|
93
|
-
"--stroke-width": 2,
|
94
|
-
"--text": "var(--spectrum-global-color-gray-900)",
|
95
|
-
"--text-opacity": 1,
|
96
|
-
}
|
97
|
-
diagram = {
|
98
|
-
"id": id,
|
99
|
-
"shape": shape,
|
100
|
-
"definition": definition,
|
101
|
-
"label": label,
|
102
|
-
"args": args,
|
103
|
-
"pins": pins,
|
104
|
-
"props": props,
|
105
|
-
"context": context,
|
106
|
-
"canvas": canvas,
|
107
|
-
"position": position,
|
108
|
-
"size": size,
|
109
|
-
"zIndex": zIndex,
|
110
|
-
"style": style,
|
111
|
-
}
|
112
|
-
component = Component(diagram)
|
113
|
-
self.cells[id] = component
|
114
|
-
return component
|
115
|
-
|
116
|
-
def removeComponent(self, key: str) -> bool:
|
117
|
-
"""
|
118
|
-
删除元件
|
119
|
-
|
120
|
-
:param key: str
|
121
|
-
:return: bool
|
122
|
-
|
123
|
-
>>>> diagram.removeComponent(key)
|
124
|
-
"""
|
125
|
-
component = self.cells.get(key)
|
126
|
-
if not component:
|
127
|
-
return False
|
128
|
-
position = component.position.copy()
|
129
|
-
del self.cells[key]
|
130
|
-
for edge in self.cells.values():
|
131
|
-
if edge.shape == "diagram-edge":
|
132
|
-
if edge.source.get("cell") == key:
|
133
|
-
edge.source = position.copy()
|
134
|
-
position["x"] += 5
|
135
|
-
position["y"] += 5
|
136
|
-
|
137
|
-
if edge.target.get("cell") == key:
|
138
|
-
edge.target = position.copy()
|
139
|
-
position["x"] += 5
|
140
|
-
position["y"] += 5
|
141
|
-
return True
|
142
|
-
|
143
|
-
def updateComponent(self, key: str, args: dict) -> bool:
|
144
|
-
"""
|
145
|
-
更新元件
|
146
|
-
|
147
|
-
:param key: str
|
148
|
-
:param args: dict
|
149
|
-
:return: bool
|
150
|
-
|
151
|
-
>>>> diagram.updateComponent(key)
|
152
|
-
"""
|
153
|
-
component = self.cells.get(key)
|
154
|
-
if not component:
|
155
|
-
return False
|
156
|
-
for k, v in self.cells.items():
|
157
|
-
if k == key:
|
158
|
-
v.__dict__.update(args)
|
159
|
-
return True
|