diff --git a/src/viam/components/audio_in/__init__.py b/src/viam/components/audio_in/__init__.py index 867aa01b0..ca61c6a94 100644 --- a/src/viam/components/audio_in/__init__.py +++ b/src/viam/components/audio_in/__init__.py @@ -1,7 +1,7 @@ +from viam.media.audio import AudioCodec +from viam.proto.common import AudioInfo from viam.resource.registry import Registry, ResourceRegistration -from viam.proto.common import AudioInfo -from viam.media.audio import AudioCodec from .audio_in import AudioIn from .client import AudioInClient from .service import AudioInRPCService diff --git a/src/viam/components/audio_in/audio_in.py b/src/viam/components/audio_in/audio_in.py index 303f2a1b6..5ee090edf 100644 --- a/src/viam/components/audio_in/audio_in.py +++ b/src/viam/components/audio_in/audio_in.py @@ -2,11 +2,10 @@ import sys from typing import Final, Optional -from viam.streams import Stream - from viam.proto.common import GetPropertiesResponse from viam.proto.component.audioin import GetAudioResponse from viam.resource.types import API, RESOURCE_NAMESPACE_RDK, RESOURCE_TYPE_COMPONENT +from viam.streams import Stream from ..component_base import ComponentBase @@ -32,12 +31,10 @@ class AudioIn(ComponentBase): AudioResponse: "TypeAlias" = GetAudioResponse AudioStream = Stream[AudioResponse] - @abc.abstractmethod - async def get_audio(self, codec: str, - duration_seconds: float, - previous_timestamp_ns:int, - *, timeout: Optional[float] = None, **kwargs) -> AudioStream: + async def get_audio( + self, codec: str, duration_seconds: float, previous_timestamp_ns: int, *, timeout: Optional[float] = None, **kwargs + ) -> AudioStream: """ Get a stream of audio from the device diff --git a/src/viam/components/audio_in/client.py b/src/viam/components/audio_in/client.py index fd45c1f0c..c025d6c25 100644 --- a/src/viam/components/audio_in/client.py +++ b/src/viam/components/audio_in/client.py @@ -1,44 +1,42 @@ -from typing import Any, Dict, List, Mapping, Optional import uuid +from typing import Any, Dict, List, Mapping, Optional from grpclib.client import Channel - -from viam.proto.component.audioin import GetAudioRequest, GetAudioResponse -from viam.proto.common import ( - DoCommandRequest, - DoCommandResponse, - GetPropertiesRequest, - Geometry) from grpclib.client import Stream as ClientStream -from viam.proto.component.audioin import AudioInServiceStub + +from viam.proto.common import DoCommandRequest, DoCommandResponse, Geometry, GetPropertiesRequest +from viam.proto.component.audioin import AudioInServiceStub, GetAudioRequest, GetAudioResponse from viam.resource.rpc_client_base import ReconfigurableResourceRPCClientBase from viam.streams import StreamWithIterator +from viam.utils import ValueTypes, dict_to_struct, get_geometries, struct_to_dict from .audio_in import AudioIn -from viam.utils import ValueTypes, dict_to_struct, get_geometries, struct_to_dict class AudioInClient(AudioIn, ReconfigurableResourceRPCClientBase): - def __init__(self, name: str, channel: Channel) -> None: self.channel = channel self.client = AudioInServiceStub(channel) super().__init__(name) + async def get_audio( + self, + codec: str, + duration_seconds: float, + previous_timestamp_ns: int, + *, + extra: Optional[Dict[str, Any]] = None, + **kwargs, + ): + request = GetAudioRequest( + name=self.name, + codec=codec, + duration_seconds=duration_seconds, + previous_timestamp_nanoseconds=previous_timestamp_ns, + request_id=str(uuid.uuid4()), + extra=dict_to_struct(extra), + ) - async def get_audio(self, - codec:str, - duration_seconds: float, - previous_timestamp_ns:int, - *, - extra: Optional[Dict[str, Any]] = None, - **kwargs, - ): - request = GetAudioRequest(name=self.name, codec = codec, - duration_seconds=duration_seconds, - previous_timestamp_nanoseconds = previous_timestamp_ns, - request_id = str(uuid.uuid4()), - extra=dict_to_struct(extra)) async def read(): md = kwargs.get("metadata", self.Metadata()).proto audio_stream: ClientStream[GetAudioRequest, GetAudioResponse] @@ -52,7 +50,6 @@ async def read(): return StreamWithIterator(read()) - async def get_properties( self, *, diff --git a/src/viam/components/audio_in/service.py b/src/viam/components/audio_in/service.py index 1cc11c43a..cf23cd6b9 100644 --- a/src/viam/components/audio_in/service.py +++ b/src/viam/components/audio_in/service.py @@ -1,21 +1,16 @@ from grpclib.server import Stream from h2.exceptions import StreamClosedError - from viam.logging import getLogger from viam.proto.common import ( DoCommandRequest, DoCommandResponse, + GetGeometriesRequest, + GetGeometriesResponse, GetPropertiesRequest, GetPropertiesResponse, - GetGeometriesRequest, - GetGeometriesResponse -) -from viam.proto.component.audioin import ( - AudioInServiceBase, - GetAudioRequest, - GetAudioResponse ) +from viam.proto.component.audioin import AudioInServiceBase, GetAudioRequest, GetAudioResponse from viam.resource.rpc_service_base import ResourceRPCServiceBase from viam.utils import dict_to_struct, struct_to_dict @@ -23,6 +18,7 @@ LOGGER = getLogger(__name__) + class AudioInRPCService(AudioInServiceBase, ResourceRPCServiceBase[AudioIn]): """ gRPC Service for a generic audio in. @@ -30,14 +26,17 @@ class AudioInRPCService(AudioInServiceBase, ResourceRPCServiceBase[AudioIn]): RESOURCE_TYPE = AudioIn - async def GetAudio(self, stream: Stream[GetAudioRequest, GetAudioResponse]) -> None: request = await stream.recv_message() assert request is not None name = request.name audio_in = self.get_resource(name) - audio_stream = await audio_in.get_audio(codec=request.codec, duration_seconds=request.duration_seconds, - previous_timestamp_ns=request.previous_timestamp_nanoseconds, metadata=stream.metadata) + audio_stream = await audio_in.get_audio( + codec=request.codec, + duration_seconds=request.duration_seconds, + previous_timestamp_ns=request.previous_timestamp_nanoseconds, + metadata=stream.metadata, + ) async for response in audio_stream: try: response.request_id = request.request_id @@ -48,7 +47,6 @@ async def GetAudio(self, stream: Stream[GetAudioRequest, GetAudioResponse]) -> N LOGGER.error(e) return - async def GetProperties(self, stream: Stream[GetPropertiesRequest, GetPropertiesResponse]) -> None: request = await stream.recv_message() assert request is not None @@ -65,7 +63,7 @@ async def DoCommand(self, stream: Stream[DoCommandRequest, DoCommandResponse]) - request = await stream.recv_message() assert request is not None name = request.name - audio_in= self.get_resource(name) + audio_in = self.get_resource(name) timeout = stream.deadline.time_remaining() if stream.deadline else None result = await audio_in.do_command( command=struct_to_dict(request.command), diff --git a/src/viam/components/audio_input/audio_input.py b/src/viam/components/audio_input/audio_input.py index e808543ea..10b56e0ba 100644 --- a/src/viam/components/audio_input/audio_input.py +++ b/src/viam/components/audio_input/audio_input.py @@ -15,7 +15,7 @@ class AudioInput(ComponentBase, StreamSource[Audio]): - """ DEPRECATED: AudioInput is deprecated, use AudioIn instead + """DEPRECATED: AudioInput is deprecated, use AudioIn instead AudioInput represents a component that can capture audio. This acts as an abstract base class for any drivers representing specific diff --git a/src/viam/components/audio_input/client.py b/src/viam/components/audio_input/client.py index 3826b368b..d086dd30f 100644 --- a/src/viam/components/audio_input/client.py +++ b/src/viam/components/audio_input/client.py @@ -1,5 +1,5 @@ -from typing import Any, AsyncIterator, Dict, List, Mapping, Optional, Union import warnings +from typing import Any, AsyncIterator, Dict, List, Mapping, Optional, Union from grpclib.client import Channel @@ -28,8 +28,7 @@ class AudioInputClient(AudioInput, ReconfigurableResourceRPCClientBase): def __init__(self, name: str, channel: Channel): warnings.warn( - "AudioInputClient is deprecated and will be removed in a future release. " - "Use AudioIn instead.", + "AudioInputClient is deprecated and will be removed in a future release. " "Use AudioIn instead.", DeprecationWarning, stacklevel=2, ) diff --git a/src/viam/components/audio_input/service.py b/src/viam/components/audio_input/service.py index 4ecc5f5b7..23586a485 100644 --- a/src/viam/components/audio_input/service.py +++ b/src/viam/components/audio_input/service.py @@ -1,5 +1,5 @@ -import wave import warnings +import wave from datetime import timedelta from io import BytesIO @@ -32,8 +32,7 @@ class AudioInputRPCService(AudioInputServiceBase, ResourceRPCServiceBase[AudioIn def __init__(self, *args, **kwargs): warnings.warn( - "AudioInput is deprecated and will be removed in a future release. " - "Use AudioIn instead.", + "AudioInput is deprecated and will be removed in a future release. " "Use AudioIn instead.", DeprecationWarning, stacklevel=2, ) diff --git a/src/viam/components/audio_out/__init__.py b/src/viam/components/audio_out/__init__.py index 170204575..ce29703e0 100644 --- a/src/viam/components/audio_out/__init__.py +++ b/src/viam/components/audio_out/__init__.py @@ -1,7 +1,7 @@ +from viam.media.audio import AudioCodec +from viam.proto.common import AudioInfo from viam.resource.registry import Registry, ResourceRegistration -from viam.proto.common import AudioInfo -from viam.media.audio import AudioCodec from .audio_out import AudioOut from .client import AudioOutClient from .service import AudioOutRPCService diff --git a/src/viam/components/audio_out/audio_out.py b/src/viam/components/audio_out/audio_out.py index ae8c21e50..7c441f19f 100644 --- a/src/viam/components/audio_out/audio_out.py +++ b/src/viam/components/audio_out/audio_out.py @@ -29,13 +29,15 @@ class AudioOut(ComponentBase): Properties: "TypeAlias" = GetPropertiesResponse @abc.abstractmethod - async def play(self, - data: bytes, - info: Optional[AudioInfo] = None, - *, - extra: Optional[Dict[str, Any]] = None, - timeout: Optional[float] = None, - **kwargs) -> None: + async def play( + self, + data: bytes, + info: Optional[AudioInfo] = None, + *, + extra: Optional[Dict[str, Any]] = None, + timeout: Optional[float] = None, + **kwargs, + ) -> None: """ Play the given audio data. @@ -55,11 +57,7 @@ async def play(self, """ @abc.abstractmethod - async def get_properties(self, - *, - extra: Optional[Dict[str, Any]] = None, - timeout: Optional[float] = None, - **kwargs) -> Properties: + async def get_properties(self, *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs) -> Properties: """ Get the audio output device's properties. diff --git a/src/viam/components/audio_out/client.py b/src/viam/components/audio_out/client.py index 2b986ea0e..f520ffde0 100644 --- a/src/viam/components/audio_out/client.py +++ b/src/viam/components/audio_out/client.py @@ -2,24 +2,12 @@ from grpclib.client import Channel -from viam.proto.common import ( - DoCommandRequest, - DoCommandResponse, - GetPropertiesRequest, - GetPropertiesResponse, - Geometry -) -from viam.proto.component.audioout import ( - AudioOutServiceStub, - PlayRequest -) - - +from viam.proto.common import DoCommandRequest, DoCommandResponse, Geometry, GetPropertiesRequest, GetPropertiesResponse +from viam.proto.component.audioout import AudioOutServiceStub, PlayRequest from viam.resource.rpc_client_base import ReconfigurableResourceRPCClientBase - from viam.utils import ValueTypes, dict_to_struct, get_geometries, struct_to_dict -from .audio_out import AudioOut, AudioInfo +from .audio_out import AudioInfo, AudioOut class AudioOutClient(AudioOut, ReconfigurableResourceRPCClientBase): @@ -30,13 +18,15 @@ def __init__(self, name: str, channel: Channel) -> None: self.client = AudioOutServiceStub(channel) super().__init__(name) - async def play(self, - data: bytes, - info: Optional[AudioInfo] = None, - *, - extra: Optional[Dict[str, Any]] = None, - timeout: Optional[float] = None, - **kwargs) -> None: + async def play( + self, + data: bytes, + info: Optional[AudioInfo] = None, + *, + extra: Optional[Dict[str, Any]] = None, + timeout: Optional[float] = None, + **kwargs, + ) -> None: if extra is None: extra = {} @@ -49,11 +39,9 @@ async def play(self, ) await self.client.Play(request, timeout=timeout, metadata=md) - async def get_properties(self, - *, - extra: Optional[Dict[str, Any]] = None, - timeout: Optional[float] = None, - **kwargs) -> AudioOut.Properties: + async def get_properties( + self, *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs + ) -> AudioOut.Properties: if extra is None: extra = {} diff --git a/src/viam/media/audio.py b/src/viam/media/audio.py index 7dbf4846c..5b0ee19ba 100644 --- a/src/viam/media/audio.py +++ b/src/viam/media/audio.py @@ -16,6 +16,7 @@ class Audio: AudioReader = StreamReader[Audio] AudioStream = Stream[Audio] + class AudioCodec(str, Enum): """Common audio codec identifiers. diff --git a/src/viam/resource/easy_resource.py b/src/viam/resource/easy_resource.py index c1d692a93..0358df386 100644 --- a/src/viam/resource/easy_resource.py +++ b/src/viam/resource/easy_resource.py @@ -113,12 +113,11 @@ def __init__(self, name: str): @classmethod def new(cls, config: ComponentConfig, dependencies: Mapping[ResourceName, ResourceBase]): """ - This is passed to register_resource_creator; the default implementation calls reconfigure() + This is passed to register_resource_creator. The default implementation only sets the resource name when an instance of your model is instantiated. You can override this in your subclass. """ self = cls(config.name) logger.debug("created %s %s %s", cls.API, cls.MODEL, config.name) - self.reconfigure(config, dependencies) return self @classmethod @@ -148,6 +147,3 @@ def register(cls): cls.MODEL, ResourceCreatorRegistration(cls.new, cls.validate_config), # pyright: ignore [reportArgumentType] ) - - def reconfigure(self, config: ComponentConfig, dependencies: Mapping[ResourceName, ResourceBase]): - logger.debug("reconfigure %s %s", self.API, self.MODEL) diff --git a/tests/mocks/components.py b/tests/mocks/components.py index 1e3f471ba..1fbae9b16 100644 --- a/tests/mocks/components.py +++ b/tests/mocks/components.py @@ -13,8 +13,8 @@ from google.protobuf.timestamp_pb2 import Timestamp from viam.components.arm import Arm, JointPositions, KinematicsFileFormat -from viam.components.audio_input import AudioInput from viam.components.audio_in import AudioIn, AudioResponse +from viam.components.audio_input import AudioInput from viam.components.audio_out import AudioOut from viam.components.base import Base from viam.components.board import Board, Tick @@ -35,15 +35,13 @@ from viam.errors import ResourceNotFoundError from viam.media.audio import Audio, AudioStream from viam.media.video import CameraMimeType, NamedImage, ViamImage -from viam.proto.common import Capsule, Geometry, GeoPoint, Orientation, Pose, PoseInFrame, ResponseMetadata, Sphere, Vector3 +from viam.proto.common import AudioInfo, Capsule, Geometry, GeoPoint, Orientation, Pose, PoseInFrame, ResponseMetadata, Sphere, Vector3 +from viam.proto.component.audioin import AudioChunk as Chunk from viam.proto.component.audioinput import AudioChunk, AudioChunkInfo, SampleFormat from viam.proto.component.board import PowerMode from viam.proto.component.encoder import PositionType from viam.streams import StreamWithIterator from viam.utils import SensorReading, ValueTypes -from viam.proto.common import AudioInfo -from viam.proto.component.audioin import AudioChunk as Chunk - GEOMETRIES = [ Geometry(center=Pose(x=1, y=2, z=3, o_x=2, o_y=3, o_z=4, theta=20), sphere=Sphere(radius_mm=2)), @@ -127,8 +125,16 @@ def __init__(self, name: str, properties: AudioIn.Properties): self.timeout: Optional[float] = None self.extra: Optional[Dict[str, Any]] = None - async def get_audio(self, codec: str, duration_seconds: float, previous_timestamp_ns: int, - *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs): + async def get_audio( + self, + codec: str, + duration_seconds: float, + previous_timestamp_ns: int, + *, + extra: Optional[Dict[str, Any]] = None, + timeout: Optional[float] = None, + **kwargs, + ): async def read() -> AsyncIterator[AudioResponse]: # Generate mock audio chunks for i in range(2): @@ -139,26 +145,23 @@ async def read() -> AsyncIterator[AudioResponse]: audio_chunk = Chunk( audio_data=chunk_data, audio_info=AudioInfo( - codec=codec, - sample_rate_hz=self.properties.sample_rate_hz, - num_channels=self.properties.num_channels + codec=codec, sample_rate_hz=self.properties.sample_rate_hz, num_channels=self.properties.num_channels ), sequence=i, start_timestamp_nanoseconds=timestamp_start, - end_timestamp_nanoseconds=timestamp_end + end_timestamp_nanoseconds=timestamp_end, ) - audio_response = AudioResponse( - audio=audio_chunk, - request_id="mock_request" - ) + audio_response = AudioResponse(audio=audio_chunk, request_id="mock_request") yield audio_response self.extra = extra self.timeout = timeout return StreamWithIterator(read()) - async def get_properties(self, *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs) -> AudioIn.Properties: + async def get_properties( + self, *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs + ) -> AudioIn.Properties: self.extra = extra self.timeout = timeout return self.properties @@ -171,6 +174,7 @@ async def get_geometries(self, *, extra: Optional[Dict[str, Any]] = None, timeou async def do_command(self, command: Mapping[str, ValueTypes], *, timeout: Optional[float] = None, **kwargs) -> Mapping[str, ValueTypes]: return {"command": command} + class MockAudioInput(AudioInput): def __init__(self, name: str, properties: AudioInput.Properties): super().__init__(name) @@ -205,6 +209,7 @@ async def get_geometries(self, *, extra: Optional[Dict[str, Any]] = None, timeou async def do_command(self, command: Mapping[str, ValueTypes], *, timeout: Optional[float] = None, **kwargs) -> Mapping[str, ValueTypes]: return {"command": command} + class MockAudioOut(AudioOut): def __init__(self, name: str, properties: AudioOut.Properties): super().__init__(name) @@ -216,7 +221,15 @@ def __init__(self, name: str, properties: AudioOut.Properties): self.timeout: Optional[float] = None self.extra: Optional[Dict[str, Any]] = None - async def play(self, data: bytes, info: Optional[AudioInfo] = None, *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs) -> None: + async def play( + self, + data: bytes, + info: Optional[AudioInfo] = None, + *, + extra: Optional[Dict[str, Any]] = None, + timeout: Optional[float] = None, + **kwargs, + ) -> None: self.play_called = True self.last_audio_data = data self.last_audio_info = info @@ -233,6 +246,7 @@ async def get_geometries(self, *, extra: Optional[Dict[str, Any]] = None, timeou self.timeout = timeout return self.geometries + class MockBase(Base): def __init__(self, name: str): self.position = 0 @@ -1161,4 +1175,3 @@ async def push(self, *, extra: Optional[Mapping[str, Any]] = None, timeout: Opti async def do_command(self, command: Mapping[str, ValueTypes], *, timeout: Optional[float] = None, **kwargs) -> Mapping[str, ValueTypes]: return {"command": command} - diff --git a/tests/test_audio_in.py b/tests/test_audio_in.py index 6182b829b..af9684e6b 100644 --- a/tests/test_audio_in.py +++ b/tests/test_audio_in.py @@ -11,10 +11,7 @@ GetPropertiesRequest, GetPropertiesResponse, ) -from viam.proto.component.audioin import ( - AudioInServiceStub, - GetAudioRequest -) +from viam.proto.component.audioin import AudioInServiceStub, GetAudioRequest from viam.resource.manager import ResourceManager from viam.utils import dict_to_struct, struct_to_dict @@ -83,6 +80,7 @@ async def test_get_geometries(self, audio_in: AudioIn): geometries = await audio_in.get_geometries() assert geometries == GEOMETRIES + class TestService: async def test_get_audio(self, audio_in: AudioIn, service: AudioInRPCService): async with ChannelFor([service]) as channel: @@ -92,10 +90,7 @@ async def test_get_audio(self, audio_in: AudioIn, service: AudioInRPCService): duration_seconds = 2.0 request = GetAudioRequest( - name=audio_in.name, - codec=codec, - duration_seconds=duration_seconds, - previous_timestamp_nanoseconds=previous_timestamp + name=audio_in.name, codec=codec, duration_seconds=duration_seconds, previous_timestamp_nanoseconds=previous_timestamp ) async with client.GetAudio.open() as stream: @@ -117,9 +112,7 @@ async def test_get_properties(self, audio_in: MockAudioIn, service: AudioInRPCSe assert audio_in.timeout is None async with ChannelFor([service]) as channel: client = AudioInServiceStub(channel) - response: GetPropertiesResponse = await client.GetProperties( - GetPropertiesRequest(name=audio_in.name), timeout=1.82 - ) + response: GetPropertiesResponse = await client.GetProperties(GetPropertiesRequest(name=audio_in.name), timeout=1.82) assert response.supported_codecs == PROPERTIES.supported_codecs assert response.sample_rate_hz == PROPERTIES.sample_rate_hz assert response.num_channels == PROPERTIES.num_channels diff --git a/tests/test_audio_out.py b/tests/test_audio_out.py index a43800854..201972e4e 100644 --- a/tests/test_audio_out.py +++ b/tests/test_audio_out.py @@ -1,21 +1,20 @@ import pytest from grpclib.testing import ChannelFor -from viam.components.audio_out import AudioOutClient, AudioOutRPCService, AudioOut +from viam.components.audio_out import AudioOut, AudioOutClient, AudioOutRPCService from viam.proto.common import ( + AudioInfo, + DoCommandRequest, GetGeometriesResponse, - AudioInfo, - GetPropertiesRequest, - GetPropertiesResponse, - DoCommandRequest, + GetPropertiesRequest, + GetPropertiesResponse, ) +from viam.proto.component.audioout import AudioOutServiceStub, PlayRequest from viam.resource.manager import ResourceManager from viam.utils import dict_to_struct, struct_to_dict -from viam.proto.component.audioout import PlayRequest, AudioOutServiceStub -from . import loose_approx - -from .mocks.components import MockAudioOut, GEOMETRIES +from . import loose_approx +from .mocks.components import GEOMETRIES, MockAudioOut # Test properties for the mock AudioIn PROPERTIES = AudioOut.Properties( @@ -24,6 +23,7 @@ num_channels=2, ) + @pytest.fixture(scope="function") def audio_out() -> MockAudioOut: return MockAudioOut(name="audio_out", properties=PROPERTIES) @@ -72,10 +72,10 @@ async def test_get_geometries(self, audio_out: MockAudioOut): geometries = await audio_out.get_geometries() assert geometries == GEOMETRIES + class TestService: @pytest.mark.asyncio async def test_play(self, audio_out: MockAudioOut, service: AudioOutRPCService): - audio_data = b"test_audio_data" audio_info = AudioInfo(codec="pcm16", sample_rate_hz=44100, num_channels=2) @@ -117,9 +117,7 @@ async def test_play_without_audio_info(self, audio_out: MockAudioOut, service: A async def test_get_properties(self, audio_out: MockAudioOut, service: AudioOutRPCService): async with ChannelFor([service]) as channel: client = AudioOutServiceStub(channel) - response: GetPropertiesResponse = await client.GetProperties( - GetPropertiesRequest(name=audio_out.name), timeout=1.82 - ) + response: GetPropertiesResponse = await client.GetProperties(GetPropertiesRequest(name=audio_out.name), timeout=1.82) assert response.supported_codecs == PROPERTIES.supported_codecs assert response.sample_rate_hz == PROPERTIES.sample_rate_hz assert response.num_channels == PROPERTIES.num_channels @@ -127,7 +125,6 @@ async def test_get_properties(self, audio_out: MockAudioOut, service: AudioOutRP @pytest.mark.asyncio async def test_do_command(self, audio_out: MockAudioOut, service: AudioOutRPCService): - command = {"test": "command"} async with ChannelFor([service]) as channel: @@ -178,7 +175,7 @@ async def test_play_without_audio_info(self, audio_out: MockAudioOut, service: A assert audio_out.last_audio_info is None @pytest.mark.asyncio - async def test_get_properties(self, audio_out: MockAudioOut,service: AudioOutRPCService): + async def test_get_properties(self, audio_out: MockAudioOut, service: AudioOutRPCService): async with ChannelFor([service]) as channel: client = AudioOutClient(audio_out.name, channel) properties = await client.get_properties(timeout=4.4) @@ -190,7 +187,7 @@ async def test_get_properties(self, audio_out: MockAudioOut,service: AudioOutRPC @pytest.mark.asyncio async def test_do_command(self, audio_out: MockAudioOut, service: AudioOutRPCService): - async with ChannelFor([service]) as channel: + async with ChannelFor([service]) as channel: client = AudioOutClient(audio_out.name, channel) command = {"command": "args"} resp = await client.do_command(command)