cloudpss 4.1.1b8__py3-none-any.whl → 4.5.0__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 -3
- cloudpss/asyncio/__init__.py +8 -0
- cloudpss/asyncio/job/__init__.py +5 -0
- cloudpss/asyncio/job/job.py +116 -0
- cloudpss/asyncio/job/messageStreamReceiver.py +121 -0
- cloudpss/asyncio/job/messageStreamSender.py +45 -0
- cloudpss/asyncio/model/__init__.py +5 -0
- cloudpss/asyncio/model/model.py +257 -0
- cloudpss/asyncio/model/revision.py +41 -0
- cloudpss/asyncio/model/topology.py +34 -0
- cloudpss/asyncio/utils/__init__.py +6 -0
- cloudpss/{utils → asyncio/utils}/httpAsyncRequest.py +2 -2
- cloudpss/function/functionExecution.py +36 -3
- cloudpss/ieslab/DataManageModel.py +131 -9
- cloudpss/ieslab/EvaluationModel.py +80 -9
- cloudpss/ieslab/IESLabOpt.py +235 -0
- cloudpss/ieslab/IESLabPlan.py +82 -4
- cloudpss/ieslab/IESLabSimulation.py +59 -32
- cloudpss/ieslab/PlanModel.py +276 -33
- cloudpss/ieslab/__init__.py +2 -1
- cloudpss/job/job.py +136 -141
- cloudpss/job/jobReceiver.py +8 -2
- cloudpss/job/messageStreamReceiver.py +42 -99
- cloudpss/job/messageStreamSender.py +5 -42
- cloudpss/job/{view/EMTView.py → result/EMTResult.py} +11 -13
- cloudpss/job/result/IESLabSimulationResult.py +5 -0
- cloudpss/job/result/IESLabTypicalDayResult.py +136 -0
- cloudpss/job/{view/IESView.py → result/IESResult.py} +2 -2
- cloudpss/job/{view/PowerFlowView.py → result/PowerFlowResult.py} +2 -2
- cloudpss/job/result/__init__.py +39 -0
- cloudpss/job/{view/view.py → result/result.py} +37 -8
- cloudpss/model/implements/diagram.py +113 -0
- cloudpss/model/jobDefinitions.py +6 -6
- cloudpss/model/model.py +232 -209
- cloudpss/model/revision.py +30 -35
- cloudpss/model/topology.py +13 -15
- cloudpss/runner/IESLabEvaluationResult.py +14 -6
- cloudpss/runner/IESLabPlanResult.py +91 -35
- cloudpss/runner/IESLabTypicalDayResult.py +62 -50
- cloudpss/runner/MessageStreamReceiver.py +5 -100
- cloudpss/runner/result.py +6 -1
- cloudpss/runner/runner.py +77 -48
- cloudpss/utils/IO.py +1 -1
- cloudpss/utils/graphqlUtil.py +3 -2
- cloudpss/utils/httprequests.py +16 -8
- cloudpss/version.py +1 -1
- {cloudpss-4.1.1b8.dist-info → cloudpss-4.5.0.dist-info}/METADATA +2 -2
- cloudpss-4.5.0.dist-info/RECORD +70 -0
- cloudpss/dslab/__init__.py +0 -2
- cloudpss/dslab/dataManageModel.py +0 -275
- cloudpss/dslab/dslab.py +0 -210
- cloudpss/dslab/files/__init__.py +0 -2
- cloudpss/dslab/files/curveData.py +0 -140229
- cloudpss/dslab/files/files.py +0 -27
- cloudpss/dslab/financialAnalysisModel.py +0 -137
- cloudpss/job/jobMachine.py +0 -11
- cloudpss/job/jobPolicy.py +0 -129
- cloudpss/job/jobQueue.py +0 -14
- cloudpss/job/jobTres.py +0 -6
- cloudpss/job/view/IESLabSimulationView.py +0 -5
- cloudpss/job/view/IESLabTypicalDayView.py +0 -27
- cloudpss/job/view/__init__.py +0 -42
- cloudpss/runner/DSLabResult.py +0 -92
- cloudpss-4.1.1b8.dist-info/RECORD +0 -71
- /cloudpss/{utils → asyncio/utils}/AsyncIterable.py +0 -0
- {cloudpss-4.1.1b8.dist-info → cloudpss-4.5.0.dist-info}/WHEEL +0 -0
- {cloudpss-4.1.1b8.dist-info → cloudpss-4.5.0.dist-info}/top_level.txt +0 -0
    
        cloudpss/job/job.py
    CHANGED
    
    | @@ -2,23 +2,53 @@ import asyncio | |
| 2 2 | 
             
            import random
         | 
| 3 3 | 
             
            import re
         | 
| 4 4 | 
             
            import time
         | 
| 5 | 
            -
            from cloudpss.utils.AsyncIterable import CustomAsyncIterable
         | 
| 6 5 |  | 
| 7 | 
            -
            from cloudpss. | 
| 8 | 
            -
            from . | 
| 6 | 
            +
            from cloudpss.job.result.result import Result
         | 
| 7 | 
            +
            from .result import getResultClass
         | 
| 9 8 |  | 
| 10 9 | 
             
            from cloudpss.utils.IO import IO
         | 
| 11 10 | 
             
            from .messageStreamReceiver import MessageStreamReceiver
         | 
| 12 11 |  | 
| 13 12 | 
             
            from cloudpss.utils.graphqlUtil import graphql_request
         | 
| 14 | 
            -
            from .jobPolicy import JobPolicy
         | 
| 15 | 
            -
            from .jobMachine import JobMachine
         | 
| 16 13 | 
             
            from .messageStreamSender import MessageStreamSender
         | 
| 17 | 
            -
            from typing import Any, Callable, TypeVar
         | 
| 14 | 
            +
            from typing import Any, Callable, Generic, TypeVar
         | 
| 18 15 | 
             
            F = TypeVar('F', bound=Callable[..., Any])
         | 
| 19 | 
            -
             | 
| 16 | 
            +
            T = TypeVar('T', bound=Callable[..., Result])
         | 
| 17 | 
            +
            class Job(Generic[T]):
         | 
| 20 18 | 
             
                """docstring for Job"""
         | 
| 21 | 
            -
             | 
| 19 | 
            +
                __jobQuery = """query($_a:JobInput!){
         | 
| 20 | 
            +
                        job(input:$_a){
         | 
| 21 | 
            +
                            id
         | 
| 22 | 
            +
                            args
         | 
| 23 | 
            +
                            createTime
         | 
| 24 | 
            +
                            startTime
         | 
| 25 | 
            +
                            endTime
         | 
| 26 | 
            +
                            status
         | 
| 27 | 
            +
                            context
         | 
| 28 | 
            +
                            user
         | 
| 29 | 
            +
                            priority
         | 
| 30 | 
            +
                            policy  { 
         | 
| 31 | 
            +
                                name
         | 
| 32 | 
            +
                                queue
         | 
| 33 | 
            +
                                tres {
         | 
| 34 | 
            +
                                    cpu
         | 
| 35 | 
            +
                                    ecpu
         | 
| 36 | 
            +
                                    mem
         | 
| 37 | 
            +
                                } 
         | 
| 38 | 
            +
                                priority 
         | 
| 39 | 
            +
                                maxDuration 
         | 
| 40 | 
            +
                            }
         | 
| 41 | 
            +
                            machine {
         | 
| 42 | 
            +
                                id
         | 
| 43 | 
            +
                                name
         | 
| 44 | 
            +
                            }
         | 
| 45 | 
            +
                            input
         | 
| 46 | 
            +
                            output
         | 
| 47 | 
            +
                            position
         | 
| 48 | 
            +
                        }
         | 
| 49 | 
            +
                    }"""
         | 
| 50 | 
            +
                
         | 
| 51 | 
            +
                __createJobQuery = """mutation($input:CreateJobInput!){job:createJob(input:$input){id input output status position}}"""
         | 
| 22 52 | 
             
                def __init__(
         | 
| 23 53 | 
             
                    self,
         | 
| 24 54 | 
             
                    id,
         | 
| @@ -47,7 +77,7 @@ class Job(object): | |
| 47 77 | 
             
                    self.user = user
         | 
| 48 78 | 
             
                    self.priority = priority
         | 
| 49 79 | 
             
                    self.policy = policy  # type: ignore
         | 
| 50 | 
            -
                    self.machine =  | 
| 80 | 
            +
                    self.machine = machine # type: ignore
         | 
| 51 81 | 
             
                    self.input = input
         | 
| 52 82 | 
             
                    self.output = output
         | 
| 53 83 | 
             
                    self.position = position
         | 
| @@ -57,82 +87,32 @@ class Job(object): | |
| 57 87 |  | 
| 58 88 | 
             
                @staticmethod
         | 
| 59 89 | 
             
                def fetch(id):
         | 
| 60 | 
            -
                    return  asyncio.run(Job.fetchAsync(id))
         | 
| 61 | 
            -
                @staticmethod
         | 
| 62 | 
            -
                async def fetchAsync(id):
         | 
| 63 90 | 
             
                    """
         | 
| 64 91 | 
             
                    获取job信息
         | 
| 65 92 | 
             
                    """
         | 
| 66 93 | 
             
                    if id is None:
         | 
| 67 94 | 
             
                        raise Exception("id is None")
         | 
| 68 | 
            -
             | 
| 69 | 
            -
                        job(input:$_a){
         | 
| 70 | 
            -
                            id
         | 
| 71 | 
            -
                            args
         | 
| 72 | 
            -
                            createTime
         | 
| 73 | 
            -
                            startTime
         | 
| 74 | 
            -
                            endTime
         | 
| 75 | 
            -
                            status
         | 
| 76 | 
            -
                            context
         | 
| 77 | 
            -
                            user
         | 
| 78 | 
            -
                            priority
         | 
| 79 | 
            -
                            policy  { 
         | 
| 80 | 
            -
                                name
         | 
| 81 | 
            -
                                queue
         | 
| 82 | 
            -
                                tres {
         | 
| 83 | 
            -
                                    cpu
         | 
| 84 | 
            -
                                    ecpu
         | 
| 85 | 
            -
                                    mem
         | 
| 86 | 
            -
                                } 
         | 
| 87 | 
            -
                                priority 
         | 
| 88 | 
            -
                                maxDuration 
         | 
| 89 | 
            -
                            }
         | 
| 90 | 
            -
                            machine {
         | 
| 91 | 
            -
                                id
         | 
| 92 | 
            -
                                name
         | 
| 93 | 
            -
                                tres {
         | 
| 94 | 
            -
                                    cpu
         | 
| 95 | 
            -
                                    ecpu
         | 
| 96 | 
            -
                                    mem
         | 
| 97 | 
            -
                                }
         | 
| 98 | 
            -
                            }
         | 
| 99 | 
            -
                            input
         | 
| 100 | 
            -
                            output
         | 
| 101 | 
            -
                            position
         | 
| 102 | 
            -
                        }
         | 
| 103 | 
            -
                    }"""
         | 
| 95 | 
            +
                   
         | 
| 104 96 | 
             
                    variables = {"_a": {"id": id}}
         | 
| 105 97 |  | 
| 106 | 
            -
                    r = | 
| 98 | 
            +
                    r =  graphql_request(Job.__jobQuery, variables)
         | 
| 107 99 | 
             
                    if "errors" in r:
         | 
| 108 100 | 
             
                        raise Exception(r["errors"])
         | 
| 109 101 | 
             
                    return Job(**r["data"]["job"])
         | 
| 110 | 
            -
             | 
| 111 | 
            -
                 | 
| 112 | 
            -
                 | 
| 113 | 
            -
             | 
| 114 | 
            -
             | 
| 115 | 
            -
             | 
| 116 | 
            -
             | 
| 117 | 
            -
             | 
| 102 | 
            +
                    
         | 
| 103 | 
            +
                
         | 
| 104 | 
            +
                # @staticmethod
         | 
| 105 | 
            +
                # def fetchMany(*args):
         | 
| 106 | 
            +
                #     """
         | 
| 107 | 
            +
                #     批量获取任务信息
         | 
| 108 | 
            +
                #     """
         | 
| 109 | 
            +
                #     # jobs = CustomAsyncIterable(Job.fetch,*args)
         | 
| 110 | 
            +
                #     # return jobs 
         | 
| 118 111 |  | 
| 119 112 |  | 
| 113 | 
            +
                
         | 
| 120 114 | 
             
                @staticmethod
         | 
| 121 | 
            -
                 | 
| 122 | 
            -
                    """
         | 
| 123 | 
            -
                    创建一个运行任务
         | 
| 124 | 
            -
             | 
| 125 | 
            -
                    :params: revision 项目版本号
         | 
| 126 | 
            -
                    :params: job 调用仿真时使用的计算方案,为空时使用项目的第一个计算方案
         | 
| 127 | 
            -
                    :params: config 调用仿真时使用的参数方案,为空时使用项目的第一个参数方案
         | 
| 128 | 
            -
                    :params: name 任务名称,为空时使用项目的参数方案名称和计算方案名称
         | 
| 129 | 
            -
                    :params: rid 项目rid,可为空
         | 
| 130 | 
            -
             | 
| 131 | 
            -
                    :return: 返回一个运行实例
         | 
| 132 | 
            -
             | 
| 133 | 
            -
                    >>> runner = Runner.runRevision(revision,job,config,'')
         | 
| 134 | 
            -
                    """
         | 
| 135 | 
            -
             | 
| 115 | 
            +
                def __createJobVariables(job, config, revisionHash, rid=None, policy=None, **kwargs):
         | 
| 136 116 | 
             
                    # 处理policy字段
         | 
| 137 117 | 
             
                    if policy is None:
         | 
| 138 118 | 
             
                        policy = {}
         | 
| @@ -148,45 +128,62 @@ class Job(object): | |
| 148 128 | 
             
                            k, v = t.split("=")
         | 
| 149 129 | 
             
                            tres[k] = float(v)  # type: ignore
         | 
| 150 130 | 
             
                        policy["tres"] = tres
         | 
| 151 | 
            -
             | 
| 152 | 
            -
                    query = """mutation($input:CreateJobInput!){job:createJob(input:$input){id input output status position}}"""
         | 
| 153 131 | 
             
                    function = job["rid"].replace("job-definition/cloudpss/", "function/CloudPSS/")
         | 
| 132 | 
            +
                    implement = kwargs.get("implement", None)
         | 
| 133 | 
            +
                    debug = job["args"].get("@debug", None )
         | 
| 134 | 
            +
                    debugargs={}
         | 
| 135 | 
            +
                    if debug is not None:
         | 
| 136 | 
            +
                        t= [ i.split('=') for i in re.split(r'\s+',debug) if i.find('=')>0]
         | 
| 137 | 
            +
                        for i in t:
         | 
| 138 | 
            +
                            debugargs[i[0]]=i[1]
         | 
| 139 | 
            +
                    context=[
         | 
| 140 | 
            +
                        function,
         | 
| 141 | 
            +
                        f"model/@sdk/{str(int(time.time() * random.random()))}",
         | 
| 142 | 
            +
                    ]
         | 
| 143 | 
            +
                    if rid is not None and rid != "":
         | 
| 144 | 
            +
                        context.append(rid)
         | 
| 145 | 
            +
                        
         | 
| 146 | 
            +
                    PARENT_JOB_ID =kwargs.get("PARENT_JOB_ID",None)
         | 
| 147 | 
            +
                    if PARENT_JOB_ID is not None:
         | 
| 148 | 
            +
                        context.append(f"job/parent/{PARENT_JOB_ID}")
         | 
| 149 | 
            +
                        
         | 
| 154 150 | 
             
                    variables = {
         | 
| 155 151 | 
             
                        "input": {
         | 
| 156 152 | 
             
                            "args": {
         | 
| 157 153 | 
             
                                **job["args"],
         | 
| 158 154 | 
             
                                "_ModelRevision": revisionHash,
         | 
| 159 155 | 
             
                                "_ModelArgs": config["args"],
         | 
| 156 | 
            +
                                "implement":implement
         | 
| 160 157 | 
             
                            },
         | 
| 161 | 
            -
                            "context":  | 
| 162 | 
            -
                                function,
         | 
| 163 | 
            -
                                rid,
         | 
| 164 | 
            -
                                f"model/@sdk/{str(int(time.time() * random.random()))}",
         | 
| 165 | 
            -
                            ],
         | 
| 158 | 
            +
                            "context": context,
         | 
| 166 159 | 
             
                            "policy": policy,
         | 
| 160 | 
            +
                            "debug":debugargs
         | 
| 167 161 | 
             
                        }
         | 
| 168 162 | 
             
                    }
         | 
| 169 | 
            -
                     | 
| 170 | 
            -
                    if "errors" in r:
         | 
| 171 | 
            -
                        raise Exception(r["errors"])
         | 
| 172 | 
            -
                    id = r["data"]["job"]["id"]
         | 
| 173 | 
            -
                    return await Job.fetchAsync(id)
         | 
| 174 | 
            -
             | 
| 163 | 
            +
                    return variables
         | 
| 175 164 | 
             
                @staticmethod
         | 
| 176 | 
            -
                 | 
| 165 | 
            +
                def create(revisionHash, job, config, name=None, rid=None, policy=None, **kwargs):
         | 
| 177 166 | 
             
                    """
         | 
| 178 | 
            -
                     | 
| 167 | 
            +
                    创建一个运行任务
         | 
| 179 168 |  | 
| 169 | 
            +
                    :params: revision 项目版本号
         | 
| 170 | 
            +
                    :params: job 调用仿真时使用的计算方案,为空时使用项目的第一个计算方案
         | 
| 171 | 
            +
                    :params: config 调用仿真时使用的参数方案,为空时使用项目的第一个参数方案
         | 
| 172 | 
            +
                    :params: name 任务名称,为空时使用项目的参数方案名称和计算方案名称
         | 
| 173 | 
            +
                    :params: rid 项目rid,可为空
         | 
| 174 | 
            +
             | 
| 175 | 
            +
                    :return: 返回一个运行实例
         | 
| 176 | 
            +
             | 
| 177 | 
            +
                    >>> runner = Runner.runRevision(revision,job,config,'')
         | 
| 180 178 | 
             
                    """
         | 
| 181 | 
            -
                     | 
| 182 | 
            -
             | 
| 183 | 
            -
             | 
| 184 | 
            -
             | 
| 185 | 
            -
             | 
| 186 | 
            -
                     | 
| 187 | 
            -
                     | 
| 188 | 
            -
             | 
| 189 | 
            -
                    await graphql_fetch(query, variables)
         | 
| 179 | 
            +
                    variables=Job.__createJobVariables(job, config, revisionHash, rid=rid, policy=policy, **kwargs)
         | 
| 180 | 
            +
                    r =  graphql_request(Job.__createJobQuery, variables)
         | 
| 181 | 
            +
                    if "errors" in r:
         | 
| 182 | 
            +
                        raise Exception(r["errors"])
         | 
| 183 | 
            +
                    id = r["data"]["job"]["id"]
         | 
| 184 | 
            +
                    return  Job.fetch(id)
         | 
| 185 | 
            +
                    
         | 
| 186 | 
            +
                
         | 
| 190 187 |  | 
| 191 188 | 
             
                @staticmethod
         | 
| 192 189 | 
             
                def load(file, format="yaml"):
         | 
| @@ -196,49 +193,30 @@ class Job(object): | |
| 196 193 | 
             
                def dump(job, file, format="yaml", compress="gzip"):
         | 
| 197 194 | 
             
                    return IO.dump(job, file, format, compress)
         | 
| 198 195 |  | 
| 199 | 
            -
                 | 
| 200 | 
            -
                    """
         | 
| 201 | 
            -
                    使用接收器获取当前运行实例的输出
         | 
| 202 | 
            -
                    """
         | 
| 203 | 
            -
                    if receiver is not None:
         | 
| 204 | 
            -
                        self.__receiver = receiver
         | 
| 205 | 
            -
                    if self.__receiver is None:
         | 
| 206 | 
            -
                        self.__receiver = MessageStreamReceiver(self, dev)
         | 
| 207 | 
            -
                    await self.__receiver.connect(**kwargs)
         | 
| 208 | 
            -
                    return self.__receiver
         | 
| 196 | 
            +
                
         | 
| 209 197 |  | 
| 210 | 
            -
                def  | 
| 198 | 
            +
                def read(self, receiver=None, **kwargs):
         | 
| 211 199 | 
             
                    """
         | 
| 212 200 | 
             
                    使用接收器获取当前运行实例的输出
         | 
| 213 201 | 
             
                    """
         | 
| 214 202 | 
             
                    if receiver is not None:
         | 
| 215 203 | 
             
                        self.__receiver = receiver
         | 
| 216 204 | 
             
                    if self.__receiver is None:
         | 
| 217 | 
            -
                        self.__receiver = MessageStreamReceiver(self | 
| 218 | 
            -
                        self.__receiver. | 
| 205 | 
            +
                        self.__receiver = MessageStreamReceiver(self)
         | 
| 206 | 
            +
                        self.__receiver.connect(**kwargs)
         | 
| 219 207 | 
             
                    return self.__receiver
         | 
| 220 208 |  | 
| 221 | 
            -
                async def write(self, sender=None, dev=False, **kwargs) -> MessageStreamSender:
         | 
| 222 | 
            -
                    """
         | 
| 223 | 
            -
                    使用发送器为当前运行实例输入
         | 
| 224 | 
            -
                    """
         | 
| 225 | 
            -
             | 
| 226 | 
            -
                    if sender is not None:
         | 
| 227 | 
            -
                        self.__sender = sender
         | 
| 228 | 
            -
                    if self.__sender is None:
         | 
| 229 | 
            -
                        self.__sender = MessageStreamSender(self, dev)
         | 
| 230 | 
            -
                    await self.__sender.connect(**kwargs)
         | 
| 231 | 
            -
                    return self.__sender
         | 
| 232 209 |  | 
| 233 | 
            -
                 | 
| 210 | 
            +
                
         | 
| 211 | 
            +
                def write(self, sender=None,  **kwargs) -> MessageStreamSender:
         | 
| 234 212 | 
             
                    """
         | 
| 235 | 
            -
                     | 
| 213 | 
            +
                    使用发送器为当前运行实例输入
         | 
| 236 214 | 
             
                    """
         | 
| 237 215 |  | 
| 238 216 | 
             
                    if sender is not None:
         | 
| 239 217 | 
             
                        self.__sender = sender
         | 
| 240 218 | 
             
                    if self.__sender is None:
         | 
| 241 | 
            -
                        self.__sender = MessageStreamSender(self | 
| 219 | 
            +
                        self.__sender = MessageStreamSender(self)
         | 
| 242 220 | 
             
                    self.__sender.connect_legacy(**kwargs)
         | 
| 243 221 | 
             
                    return self.__sender
         | 
| 244 222 |  | 
| @@ -246,43 +224,60 @@ class Job(object): | |
| 246 224 | 
             
                    """
         | 
| 247 225 | 
             
                    return: 0: 运行中 1: 运行完成 2: 运行失败
         | 
| 248 226 | 
             
                    """
         | 
| 249 | 
            -
                    
         | 
| 227 | 
            +
                    time.sleep(0)
         | 
| 250 228 | 
             
                    if self.__receiver is not None:
         | 
| 251 229 | 
             
                        return self.__receiver.status
         | 
| 252 230 | 
             
                    if self.__receiver is None:
         | 
| 253 | 
            -
                        self. | 
| 231 | 
            +
                        self.__connect()
         | 
| 232 | 
            +
                    
         | 
| 254 233 | 
             
                    return 0
         | 
| 255 234 |  | 
| 256 | 
            -
                def  | 
| 235 | 
            +
                def __connect(self):
         | 
| 257 236 | 
             
                    """
         | 
| 258 237 | 
             
                    连接接收器和发送器
         | 
| 259 238 | 
             
                    """
         | 
| 260 | 
            -
                     | 
| 261 | 
            -
                     | 
| 239 | 
            +
                    resultType = getResultClass(self.context[0])
         | 
| 240 | 
            +
                    
         | 
| 241 | 
            +
                    self._result = self._resultView(resultType)
         | 
| 262 242 |  | 
| 263 243 | 
             
                @property
         | 
| 264 | 
            -
                def result(self):
         | 
| 244 | 
            +
                def result(self)->T:
         | 
| 265 245 | 
             
                    """
         | 
| 266 246 | 
             
                    获取当前运行实例的输出
         | 
| 267 247 | 
             
                    """
         | 
| 268 248 | 
             
                    if self._result is None:
         | 
| 269 | 
            -
                        self. | 
| 249 | 
            +
                        self.__connect()
         | 
| 270 250 | 
             
                    return self._result
         | 
| 271 251 |  | 
| 272 | 
            -
             | 
| 273 | 
            -
             | 
| 252 | 
            +
                    
         | 
| 253 | 
            +
                    
         | 
| 254 | 
            +
                def _resultView(self, resultType=None):
         | 
| 274 255 | 
             
                    """
         | 
| 275 256 | 
             
                    获取当前运行实例的输出
         | 
| 276 257 | 
             
                    """
         | 
| 277 | 
            -
                    receiver =  self. | 
| 278 | 
            -
                    sender =  self. | 
| 279 | 
            -
                     | 
| 258 | 
            +
                    receiver =  self.read()
         | 
| 259 | 
            +
                    sender =  self.write()
         | 
| 260 | 
            +
                    if resultType is None:
         | 
| 261 | 
            +
                        resultType = getResultClass(self.context[0])
         | 
| 262 | 
            +
                    return resultType(receiver, sender)
         | 
| 263 | 
            +
             | 
| 264 | 
            +
                
         | 
| 280 265 |  | 
| 281 | 
            -
                 | 
| 266 | 
            +
                def abort(self,timeout=3):
         | 
| 282 267 | 
             
                    """
         | 
| 283 | 
            -
                     | 
| 268 | 
            +
                    中断当前运行实例
         | 
| 284 269 | 
             
                    """
         | 
| 285 | 
            -
                     | 
| 286 | 
            -
             | 
| 287 | 
            -
             | 
| 288 | 
            -
             | 
| 270 | 
            +
                    query = '''mutation ($input: AbortJobInput!) {
         | 
| 271 | 
            +
                        job: abortJob(input: $input) {
         | 
| 272 | 
            +
                            id
         | 
| 273 | 
            +
                            status
         | 
| 274 | 
            +
                        }
         | 
| 275 | 
            +
                    }
         | 
| 276 | 
            +
                    '''
         | 
| 277 | 
            +
                    variables = {
         | 
| 278 | 
            +
                        'input': {
         | 
| 279 | 
            +
                            'id': self.taskId,
         | 
| 280 | 
            +
                            'timeout': timeout
         | 
| 281 | 
            +
                        }
         | 
| 282 | 
            +
                    }
         | 
| 283 | 
            +
                    graphql_request(query, variables)
         | 
    
        cloudpss/job/jobReceiver.py
    CHANGED
    
    | @@ -1,3 +1,4 @@ | |
| 1 | 
            +
            from deprecated import deprecated
         | 
| 1 2 | 
             
            class JobReceiver(object):
         | 
| 2 3 | 
             
                messages = []
         | 
| 3 4 | 
             
                index = 0
         | 
| @@ -20,7 +21,7 @@ class JobReceiver(object): | |
| 20 21 | 
             
                        return message
         | 
| 21 22 | 
             
                    raise StopIteration()
         | 
| 22 23 |  | 
| 23 | 
            -
                def  | 
| 24 | 
            +
                def result(self, resultType):
         | 
| 24 25 | 
             
                    """
         | 
| 25 26 | 
             
                        获取指定类型的视图数据
         | 
| 26 27 |  | 
| @@ -30,4 +31,9 @@ class JobReceiver(object): | |
| 30 31 |  | 
| 31 32 | 
             
                        >>> view= receiver.view(EMTView)
         | 
| 32 33 | 
             
                    """
         | 
| 33 | 
            -
                    return  | 
| 34 | 
            +
                    return resultType(self)
         | 
| 35 | 
            +
                
         | 
| 36 | 
            +
                @property
         | 
| 37 | 
            +
                @deprecated(version='3.0', reason="该方法将在 5.0 版本移除")
         | 
| 38 | 
            +
                def message(self):
         | 
| 39 | 
            +
                    return self.messages
         | 
| @@ -1,9 +1,5 @@ | |
| 1 1 | 
             
            import logging
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            import aiohttp
         | 
| 4 | 
            -
            from aiohttp import WSMsgType
         | 
| 5 | 
            -
             | 
| 6 | 
            -
            from cloudpss.utils.httpAsyncRequest import websocket_connect
         | 
| 2 | 
            +
            import sys
         | 
| 7 3 | 
             
            from .jobReceiver import JobReceiver
         | 
| 8 4 | 
             
            import os
         | 
| 9 5 | 
             
            from urllib.parse import urlparse
         | 
| @@ -24,91 +20,36 @@ class Message(object): | |
| 24 20 |  | 
| 25 21 |  | 
| 26 22 | 
             
            class MessageStreamReceiver(JobReceiver):
         | 
| 27 | 
            -
                def __init__(self, job | 
| 23 | 
            +
                def __init__(self, job):
         | 
| 28 24 | 
             
                    super().__init__()
         | 
| 29 25 | 
             
                    self.job = job
         | 
| 30 | 
            -
                    self. | 
| 26 | 
            +
                    self.id =self.job.output
         | 
| 31 27 | 
             
                    self.origin = os.environ.get("CLOUDPSS_API_URL", "https://cloudpss.net/")
         | 
| 32 28 | 
             
                    self.__hasOpen = False
         | 
| 33 29 |  | 
| 34 | 
            -
                def  | 
| 35 | 
            -
                     | 
| 36 | 
            -
                    同步方法读取消息流中的数据
         | 
| 37 | 
            -
                    id: 消息流id
         | 
| 38 | 
            -
                    fr0m: 从哪个位置开始读取,如果为0则从头开始读取
         | 
| 39 | 
            -
                    on_open: 连接建立时的回调函数
         | 
| 40 | 
            -
                    on_message: 收到消息时的回调函数
         | 
| 41 | 
            -
                    on_error: 发生错误时的回调函数
         | 
| 42 | 
            -
                    on_close: 连接关闭时的回调函数
         | 
| 43 | 
            -
                    """
         | 
| 44 | 
            -
                    if id is None:
         | 
| 45 | 
            -
                        raise Exception("id is None")
         | 
| 46 | 
            -
                    u = list(urlparse(self.origin))
         | 
| 47 | 
            -
                    head = "wss" if u[0] == "https" else "ws"
         | 
| 48 | 
            -
             | 
| 49 | 
            -
                    path = head + "://" + str(u[1]) + "/api/streams/id/" + id
         | 
| 50 | 
            -
                    if fr0m is not None:
         | 
| 51 | 
            -
                        path = path + "&from=" + str(fr0m)
         | 
| 52 | 
            -
                    logging.info(f"receive data from websocket: {path}")
         | 
| 53 | 
            -
                    ws = websocket.WebSocketApp(
         | 
| 54 | 
            -
                        path,
         | 
| 55 | 
            -
                        on_open=self.__on_open,
         | 
| 56 | 
            -
                        on_message=self.__on_message_legacy,
         | 
| 57 | 
            -
                        on_error=self.__on_error,
         | 
| 58 | 
            -
                        on_close=self.__on_close,
         | 
| 59 | 
            -
                    )
         | 
| 60 | 
            -
             | 
| 61 | 
            -
                    return ws
         | 
| 62 | 
            -
             | 
| 63 | 
            -
                async def __receive(self, id, fr0m):
         | 
| 64 | 
            -
                    """
         | 
| 65 | 
            -
                    读取消息流中的数据
         | 
| 66 | 
            -
                    id: 消息流id
         | 
| 67 | 
            -
                    fr0m: 从哪个位置开始读取,如果为0则从头开始读取
         | 
| 68 | 
            -
                    on_open: 连接建立时的回调函数
         | 
| 69 | 
            -
                    on_message: 收到消息时的回调函数
         | 
| 70 | 
            -
                    on_error: 发生错误时的回调函数
         | 
| 71 | 
            -
                    on_close: 连接关闭时的回调函数
         | 
| 72 | 
            -
                    """
         | 
| 73 | 
            -
                    if id is None:
         | 
| 30 | 
            +
                def __path(self, from_=None):
         | 
| 31 | 
            +
                    if self.id is None:
         | 
| 74 32 | 
             
                        raise Exception("id is None")
         | 
| 75 33 | 
             
                    u = list(urlparse(self.origin))
         | 
| 76 34 | 
             
                    head = "wss" if u[0] == "https" else "ws"
         | 
| 77 | 
            -
             | 
| 78 | 
            -
                     | 
| 79 | 
            -
             | 
| 80 | 
            -
             | 
| 81 | 
            -
             | 
| 82 | 
            -
                    async for msg in websocket_connect(
         | 
| 83 | 
            -
                        path,
         | 
| 84 | 
            -
                        open_func=self.__on_open,
         | 
| 85 | 
            -
                    ):
         | 
| 86 | 
            -
                        if msg.type == WSMsgType.BINARY:
         | 
| 87 | 
            -
                            decode = self.__on_message(msg.data)
         | 
| 88 | 
            -
                            yield decode
         | 
| 89 | 
            -
                        elif msg.type == WSMsgType.TEXT:
         | 
| 90 | 
            -
                            decode = self.__on_message(msg.data)
         | 
| 91 | 
            -
                            yield decode
         | 
| 92 | 
            -
                        elif msg.type == WSMsgType.CLOSED:
         | 
| 93 | 
            -
                            logging.debug("WebSocket连接已关闭")
         | 
| 94 | 
            -
                            self.__on_close()
         | 
| 95 | 
            -
                            
         | 
| 96 | 
            -
                            break
         | 
| 97 | 
            -
                        elif msg.type == WSMsgType.ERROR:
         | 
| 98 | 
            -
                            logging.debug(f"WebSocket连接发生错误:{msg.data}")
         | 
| 99 | 
            -
                            self.__on_error(msg.data)
         | 
| 100 | 
            -
                            break
         | 
| 101 | 
            -
                    self._status=1
         | 
| 35 | 
            +
                    path = head + "://" + str(u[1]) + "/api/streams/id/" + self.id
         | 
| 36 | 
            +
                    if from_ is not None:
         | 
| 37 | 
            +
                        path = path + "?from=" + str(from_)
         | 
| 38 | 
            +
                    return path
         | 
| 39 | 
            +
              
         | 
| 102 40 | 
             
                ###下面是兼容Receiver部分功能实现
         | 
| 103 41 | 
             
                def __on_message_legacy(self,  *args, **kwargs):
         | 
| 104 | 
            -
                     | 
| 42 | 
            +
                    
         | 
| 43 | 
            +
                    if type(args[0]) != websocket.WebSocketApp:
         | 
| 105 44 | 
             
                        message = args[0]
         | 
| 106 45 | 
             
                    else:
         | 
| 107 46 | 
             
                        message = args[1]
         | 
| 108 47 | 
             
                    return self.__on_message(message)
         | 
| 109 48 |  | 
| 110 49 | 
             
                def __on_message(self, message):
         | 
| 50 | 
            +
                    
         | 
| 111 51 | 
             
                    data = IO.deserialize(message, "ubjson")
         | 
| 52 | 
            +
                    self.ws.url = self.__path(data["id"])
         | 
| 112 53 | 
             
                    msg = IO.deserialize(data["data"], "ubjson")
         | 
| 113 54 | 
             
                    self.messages.append(msg)
         | 
| 114 55 | 
             
                    if(msg['type']=='terminate'):
         | 
| @@ -130,9 +71,10 @@ class MessageStreamReceiver(JobReceiver): | |
| 130 71 | 
             
                    self.messages.append(msg)
         | 
| 131 72 |  | 
| 132 73 | 
             
                def __on_close(self, *args, **kwargs):
         | 
| 133 | 
            -
                    if len(args)> | 
| 74 | 
            +
                    if len(args)>1:
         | 
| 134 75 | 
             
                        msg =args[2]
         | 
| 135 | 
            -
                         | 
| 76 | 
            +
                        
         | 
| 77 | 
            +
                        if msg is not None and msg.startswith("CMS_NO_STREAM_ID:"):
         | 
| 136 78 | 
             
                            self._status = 1
         | 
| 137 79 | 
             
                            msg = {
         | 
| 138 80 | 
             
                                "type": "log",
         | 
| @@ -145,7 +87,6 @@ class MessageStreamReceiver(JobReceiver): | |
| 145 87 | 
             
                            self.messages.append(msg)
         | 
| 146 88 | 
             
                            return
         | 
| 147 89 | 
             
                    logging.debug("MessageStreamReceiver close")
         | 
| 148 | 
            -
                    self._status = 1
         | 
| 149 90 | 
             
                    msg = {
         | 
| 150 91 | 
             
                        "type": "log",
         | 
| 151 92 | 
             
                        "verb": "create",
         | 
| @@ -156,7 +97,7 @@ class MessageStreamReceiver(JobReceiver): | |
| 156 97 | 
             
                        },
         | 
| 157 98 | 
             
                    }
         | 
| 158 99 | 
             
                    self.messages.append(msg)
         | 
| 159 | 
            -
             | 
| 100 | 
            +
                    self._status = 1
         | 
| 160 101 |  | 
| 161 102 | 
             
                def __on_open(self,ws, *args, **kwargs):
         | 
| 162 103 | 
             
                    self.ws = ws
         | 
| @@ -173,31 +114,33 @@ class MessageStreamReceiver(JobReceiver): | |
| 173 114 | 
             
                def status(self):
         | 
| 174 115 | 
             
                    return self._status
         | 
| 175 116 |  | 
| 176 | 
            -
                 | 
| 177 | 
            -
             | 
| 178 | 
            -
             | 
| 117 | 
            +
                def waitFor(self,timeOut=sys.maxsize):
         | 
| 118 | 
            +
                    """
         | 
| 119 | 
            +
                        阻塞方法,直到任务完成
         | 
| 179 120 |  | 
| 180 | 
            -
             | 
| 121 | 
            +
                        :params timeOut: 超时时间
         | 
| 122 | 
            +
                    """
         | 
| 123 | 
            +
                    start = time.time()
         | 
| 124 | 
            +
                    while self.status == 0:
         | 
| 125 | 
            +
                        time.sleep(0)
         | 
| 126 | 
            +
                        if time.time()-start>timeOut:
         | 
| 127 | 
            +
                            raise Exception("time out")
         | 
| 128 | 
            +
                   
         | 
| 129 | 
            +
             | 
| 130 | 
            +
                def connect(self):
         | 
| 181 131 | 
             
                    self._status = 1
         | 
| 182 | 
            -
                     | 
| 183 | 
            -
             | 
| 184 | 
            -
             | 
| 132 | 
            +
                    path = self.__path()
         | 
| 133 | 
            +
                    logging.info(f"receive data from websocket: {path}")
         | 
| 134 | 
            +
                    self.ws = websocket.WebSocketApp(
         | 
| 135 | 
            +
                        path,
         | 
| 136 | 
            +
                        on_open=self.__on_open,
         | 
| 137 | 
            +
                        on_message=self.__on_message_legacy,
         | 
| 138 | 
            +
                        on_error=self.__on_error,
         | 
| 139 | 
            +
                        on_close=self.__on_close,
         | 
| 185 140 | 
             
                    )
         | 
| 186 | 
            -
                    thread = threading.Thread(target=self.ws.run_forever,  | 
| 141 | 
            +
                    thread = threading.Thread(target=self.ws.run_forever, kwargs={'ping_interval':60,'ping_timeout':5,'reconnect':True})
         | 
| 187 142 | 
             
                    thread.setDaemon(True)
         | 
| 188 143 | 
             
                    thread.start()
         | 
| 189 144 | 
             
                    while not self.__hasOpen:
         | 
| 190 | 
            -
                        time.sleep(0 | 
| 191 | 
            -
             | 
| 192 | 
            -
                async def connect(self):
         | 
| 193 | 
            -
                    self._status = 0
         | 
| 194 | 
            -
                    self.receiver= self.__receive(
         | 
| 195 | 
            -
                        self.job.output,
         | 
| 196 | 
            -
                        None,
         | 
| 197 | 
            -
                    )
         | 
| 198 | 
            -
                    # asyncio.create_task(
         | 
| 199 | 
            -
                    #     self.__receive(
         | 
| 200 | 
            -
                    #         self.job.output,
         | 
| 201 | 
            -
                    #         None
         | 
| 202 | 
            -
                    #     )
         | 
| 203 | 
            -
                    # )
         | 
| 145 | 
            +
                        time.sleep(0)
         | 
| 146 | 
            +
                    
         | 
| @@ -2,10 +2,6 @@ import asyncio | |
| 2 2 | 
             
            import sys, os
         | 
| 3 3 | 
             
            import threading
         | 
| 4 4 | 
             
            from urllib.parse import urlparse
         | 
| 5 | 
            -
             | 
| 6 | 
            -
            import aiohttp
         | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 9 5 | 
             
            sys.path.append(os.path.join(os.path.dirname(__file__), "../"))
         | 
| 10 6 |  | 
| 11 7 | 
             
            import websocket
         | 
| @@ -16,10 +12,9 @@ import logging | |
| 16 12 |  | 
| 17 13 |  | 
| 18 14 | 
             
            class MessageStreamSender:
         | 
| 19 | 
            -
                def __init__(self, job | 
| 15 | 
            +
                def __init__(self, job):
         | 
| 20 16 | 
             
                    super().__init__()
         | 
| 21 17 | 
             
                    self.job = job
         | 
| 22 | 
            -
                    self.dev = dev
         | 
| 23 18 | 
             
                    self.origin = os.environ.get("CLOUDPSS_API_URL", "https://cloudpss.net/")
         | 
| 24 19 | 
             
                    self.__hasOpen = False
         | 
| 25 20 |  | 
| @@ -56,19 +51,9 @@ class MessageStreamSender: | |
| 56 51 | 
             
                def status(self):
         | 
| 57 52 | 
             
                    return self._status
         | 
| 58 53 |  | 
| 59 | 
            -
                async def write_async(self, message):
         | 
| 60 | 
            -
                    if self.websocket:
         | 
| 61 | 
            -
                        data = IO.serialize(message, "ubjson", None)
         | 
| 62 | 
            -
                        await self.websocket.send_bytes(data)
         | 
| 63 | 
            -
                    else:
         | 
| 64 | 
            -
                        logging.info("websocket is None")
         | 
| 65 | 
            -
             | 
| 66 54 | 
             
                def write(self, message):
         | 
| 67 | 
            -
                     | 
| 68 | 
            -
             | 
| 69 | 
            -
                        self.ws.send(data,websocket.ABNF.OPCODE_BINARY)
         | 
| 70 | 
            -
                    else:
         | 
| 71 | 
            -
                        asyncio.run(self.write_async(message))
         | 
| 55 | 
            +
                    data = IO.serialize(message, "ubjson", None)
         | 
| 56 | 
            +
                    self.ws.send(data,websocket.ABNF.OPCODE_BINARY)
         | 
| 72 57 |  | 
| 73 58 | 
             
                def connect_legacy(self):
         | 
| 74 59 | 
             
                    """
         | 
| @@ -99,28 +84,6 @@ class MessageStreamSender: | |
| 99 84 | 
             
                        time.sleep(0.2)
         | 
| 100 85 | 
             
                    return self.ws
         | 
| 101 86 |  | 
| 102 | 
            -
                 | 
| 103 | 
            -
                    if self.websocket:
         | 
| 104 | 
            -
                        data = await self.websocket.receive()
         | 
| 105 | 
            -
                        if data.type == aiohttp.WSMsgType.TEXT:
         | 
| 106 | 
            -
                            self.__on_message(data.data)
         | 
| 107 | 
            -
                        elif data.type == aiohttp.WSMsgType.CLOSED:
         | 
| 108 | 
            -
                            self.__on_close()
         | 
| 109 | 
            -
                        elif data.type == aiohttp.WSMsgType.ERROR:
         | 
| 110 | 
            -
                            self.__on_error(data.data)
         | 
| 111 | 
            -
                    else:
         | 
| 112 | 
            -
                        logging.info("WebSocket connection not established")
         | 
| 113 | 
            -
             | 
| 114 | 
            -
                async def connect(self):
         | 
| 115 | 
            -
                    self._status = 0
         | 
| 116 | 
            -
                    if self.job.input is None:
         | 
| 117 | 
            -
                        raise Exception("id is None")
         | 
| 118 | 
            -
                    if self.job.input == "00000000-0000-0000-0000-000000000000":
         | 
| 119 | 
            -
                        return
         | 
| 120 | 
            -
                    u = list(urlparse(self.origin))
         | 
| 121 | 
            -
                    head = "wss" if u[0] == "https" else "ws"
         | 
| 87 | 
            +
                
         | 
| 122 88 |  | 
| 123 | 
            -
             | 
| 124 | 
            -
                    logging.info(f"MessageStreamSender data from websocket: {path}")
         | 
| 125 | 
            -
                    async with aiohttp.ClientSession() as session:
         | 
| 126 | 
            -
                        self.websocket = await session.ws_connect(path)
         | 
| 89 | 
            +
                
         |