""" Ray decorated classes and functions defined at top of file, importable with fully qualified name as import_path to test DAG building, artifact generation and structured deployment. """ import asyncio from typing import Dict, Union from ray import serve from ray.actor import ActorHandle from ray.serve.handle import DeploymentHandle NESTED_HANDLE_KEY = "nested_handle" @serve.deployment class ClassHello: def __init__(self): pass def hello(self): return "hello" @serve.deployment class Model: def __init__(self, weight: int, ratio: float = None): self.weight = weight self.ratio = ratio or 1 def forward(self, input: int): return self.ratio * self.weight * input def __call__(self, request): input_data = request return self.ratio * self.weight * input_data @serve.deployment class Combine: def __init__( self, m1: DeploymentHandle, m2: Union[DeploymentHandle, Dict[str, DeploymentHandle]], m2_nested: bool = False, ): self.m1 = m1 self.m2 = m2.get(NESTED_HANDLE_KEY) if m2_nested else m2 async def __call__(self, req): if isinstance(self.m1, ActorHandle) and isinstance(self.m2, ActorHandle): r1_ref = self.m1.forward.remote(req) r2_ref = self.m2.forward.remote(req) else: r1_ref = await self.m1.forward.remote(req)._to_object_ref() r2_ref = await self.m2.forward.remote(req)._to_object_ref() return sum(await asyncio.gather(r1_ref, r2_ref)) @serve.deployment class Counter: def __init__(self, val): self.val = val def get(self): return self.val def inc(self, inc): self.val += inc @serve.deployment def fn_hello(): return "hello" @serve.deployment def fn(val, incr=0): return val + incr @serve.deployment def combine(m1_output, m2_output, kwargs_output=0): return m1_output + m2_output + kwargs_output def class_factory(): class MyInlineClass: def __init__(self, val): self.val = val def get(self): return self.val return MyInlineClass