diff --git a/sdk/types/scrypted_python/scrypted_sdk/types.py b/sdk/types/scrypted_python/scrypted_sdk/types.py index 07e08965b..8646c076b 100644 --- a/sdk/types/scrypted_python/scrypted_sdk/types.py +++ b/sdk/types/scrypted_python/scrypted_sdk/types.py @@ -4,7 +4,7 @@ try: from typing import TypedDict except: from typing_extensions import TypedDict -from typing import Union, Any +from typing import Union, Any, AsyncGenerator from .other import * @@ -1202,7 +1202,7 @@ class ObjectDetection: async def detectObjects(self, mediaObject: MediaObject, session: ObjectDetectionSession = None) -> ObjectsDetected: pass - async def generateObjectDetections(self, videoFrames: MediaObject | VideoFrame, session: ObjectDetectionGeneratorSession) -> ObjectDetectionGeneratorResult: + async def generateObjectDetections(self, videoFrames: MediaObject | AsyncGenerator[VideoFrame, None], session: ObjectDetectionGeneratorSession) -> AsyncGenerator[ObjectDetectionGeneratorResult, None]: pass async def getDetectionModel(self, settings: Any = None) -> ObjectDetectionModel: @@ -1463,7 +1463,7 @@ class StartStop: class StreamService: """Generic bidirectional stream connection.""" - async def connectStream(self, input: Any = None, options: Any = None) -> Any: + async def connectStream(self, input: AsyncGenerator[Any, None] = None, options: Any = None) -> AsyncGenerator[Any, None]: pass @@ -1543,7 +1543,7 @@ class VideoClips: class VideoFrameGenerator: - async def generateVideoFrames(self, mediaObject: MediaObject, options: VideoFrameGeneratorOptions = None) -> VideoFrame: + async def generateVideoFrames(self, mediaObject: MediaObject, options: VideoFrameGeneratorOptions = None) -> AsyncGenerator[VideoFrame, None]: pass diff --git a/sdk/types/src/build.ts b/sdk/types/src/build.ts index c1d069be9..9fe03647f 100644 --- a/sdk/types/src/build.ts +++ b/sdk/types/src/build.ts @@ -79,6 +79,11 @@ fs.writeFileSync(path.join(__dirname, '../gen/index.ts'), contents); const discoveredTypes = new Set(); discoveredTypes.add('EventDetails'); +// When computing method signatures, we push the generic parameter types +// into this set. We can then convert them to Any. +// Pop the types off when we're done. +const parameterTypes = new Set(); + function toPythonType(type: any): string { if (type.type === 'array') return `list[${toPythonType(type.elementType)}]`; @@ -88,7 +93,11 @@ function toPythonType(type: any): string { return `tuple[${type.elements.map((et: any) => toPythonType(et)).join(', ')}]`; if (type.type === 'union') return type.types.map((type: any) => toPythonType(type)).join(' | ') + if (type.name === 'AsyncGenerator') + return `AsyncGenerator[${toPythonType(type.typeArguments[0])}, None]`; type = type.typeArguments?.[0]?.name || type.name || type; + if (parameterTypes.has(type)) + return 'Any'; switch (type) { case 'boolean': return 'bool'; @@ -133,11 +142,24 @@ function toPythonMethodDeclaration(method: any) { } function selfSignature(method: any) { + for (const typeParameter of method.signatures[0].typeParameter || []) { + parameterTypes.add(typeParameter.name); + } const params = (method.signatures[0].parameters || []).map((p: any) => toPythonParameter(p)); + parameterTypes.clear(); params.unshift('self'); return params.join(', '); } +function selfReturnType(method: any) { + for (const typeParameter of method.signatures[0].typeParameter || []) { + parameterTypes.add(typeParameter.name); + } + const retType = toPythonReturnType(method.signatures[0].type); + parameterTypes.clear(); + return retType +} + const enums = schema.children?.filter((child: any) => child.kindString === 'Enumeration') ?? []; const interfaces = schema.children?.filter((child: any) => Object.values(ScryptedInterface).includes(child.name)) ?? []; let python = ''; @@ -210,7 +232,7 @@ ${toDocstring(td)} ` } for (const method of methods) { - python += ` ${toPythonMethodDeclaration(method)} ${method.name}(${selfSignature(method)}) -> ${toPythonReturnType(method.signatures[0].type)}: + python += ` ${toPythonMethodDeclaration(method)} ${method.name}(${selfSignature(method)}) -> ${selfReturnType(method)}: ${toDocstring(method, true)} ` @@ -229,7 +251,7 @@ for (const td of interfaces) { let pythonEnums = '' for (const e of enums) { - if (e.children) { + if (e.children) { pythonEnums += ` class ${e.name}(str, Enum): ${toDocstring(e)} @@ -331,7 +353,7 @@ try: from typing import TypedDict except: from typing_extensions import TypedDict -from typing import Union, Any +from typing import Union, Any, AsyncGenerator from .other import * diff --git a/sdk/types/src/types.input.ts b/sdk/types/src/types.input.ts index 551ff5ff7..ad1736f3f 100644 --- a/sdk/types/src/types.input.ts +++ b/sdk/types/src/types.input.ts @@ -1525,7 +1525,7 @@ export interface VideoFrameGenerator { * Generic bidirectional stream connection. */ export interface StreamService { - connectStream(input?: AsyncGenerator, options?: any): Promise>; + connectStream(input?: AsyncGenerator, options?: any): Promise>; } /** * TTY connection offered by a remote device that can be connected to