Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/module/src/gizmo/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
as all component types must. It also defines its specific ``SUBTYPE``, which is used internally to keep track of supported types.

The ``GizmoService`` implements the gRPC service for the Gizmo. This will allow other robots and clients to make requests of the Gizmo.
It extends both from ``GizmoServiceBase`` and ``ResourceRPCServiceBase[Gizmo]``. The former is the gRPC service as defined by the proto,
It extends both from ``GizmoServiceBase`` and ``ResourceRPCServiceBase``. The former is the gRPC service as defined by the proto,
and the latter is the class that all gRPC services for components must inherit from.

Finally, the ``GizmoClient`` is the gRPC client for a Gizmo. It inherits from Gizmo since it implements all the same functions. The
Expand Down Expand Up @@ -72,7 +72,7 @@ async def do_two(self, arg1: bool, **kwargs) -> str:
...


class GizmoService(GizmoServiceBase, ResourceRPCServiceBase[Gizmo]):
class GizmoService(GizmoServiceBase, ResourceRPCServiceBase):
"""Example gRPC service for the Gizmo component"""

RESOURCE_TYPE = Gizmo
Expand Down
2 changes: 1 addition & 1 deletion examples/module/src/summation/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ async def sum(self, nums: Sequence[float]) -> float:
...


class SummationRPCService(SummationServiceBase, ResourceRPCServiceBase[SummationService]):
class SummationRPCService(SummationServiceBase, ResourceRPCServiceBase):
"""Example gRPC service for the Summation service"""

RESOURCE_TYPE = SummationService
Expand Down
2 changes: 1 addition & 1 deletion src/viam/components/arm/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from .arm import Arm


class ArmRPCService(ArmServiceBase, ResourceRPCServiceBase[Arm]):
class ArmRPCService(ArmServiceBase, ResourceRPCServiceBase):
"""
gRPC Service for an Arm
"""
Expand Down
2 changes: 1 addition & 1 deletion src/viam/components/audio_input/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from .audio_input import AudioInput


class AudioInputRPCService(AudioInputServiceBase, ResourceRPCServiceBase[AudioInput]):
class AudioInputRPCService(AudioInputServiceBase, ResourceRPCServiceBase):
"""
gRPC Service for a generic AudioInput
"""
Expand Down
2 changes: 1 addition & 1 deletion src/viam/components/base/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from .base import Base


class BaseRPCService(BaseServiceBase, ResourceRPCServiceBase[Base]):
class BaseRPCService(BaseServiceBase, ResourceRPCServiceBase):
"""
gRPC service for a robotic Base
"""
Expand Down
2 changes: 1 addition & 1 deletion src/viam/components/board/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
from .board import Board


class BoardRPCService(BoardServiceBase, ResourceRPCServiceBase[Board]):
class BoardRPCService(BoardServiceBase, ResourceRPCServiceBase):
"""
gRPC Service for a Board
"""
Expand Down
2 changes: 1 addition & 1 deletion src/viam/components/camera/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from . import Camera, RawImage


class CameraRPCService(CameraServiceBase, ResourceRPCServiceBase[Camera]):
class CameraRPCService(CameraServiceBase, ResourceRPCServiceBase):
"""
gRPC Service for a generic Camera
"""
Expand Down
2 changes: 1 addition & 1 deletion src/viam/components/encoder/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from .encoder import Encoder


class EncoderRPCService(EncoderServiceBase, ResourceRPCServiceBase[Encoder]):
class EncoderRPCService(EncoderServiceBase, ResourceRPCServiceBase):
"""
gRPC Service for an Encoder
"""
Expand Down
2 changes: 1 addition & 1 deletion src/viam/components/gantry/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from .gantry import Gantry


class GantryRPCService(GantryServiceBase, ResourceRPCServiceBase[Gantry]):
class GantryRPCService(GantryServiceBase, ResourceRPCServiceBase):
"""
gRPC Service for a Gantry
"""
Expand Down
2 changes: 1 addition & 1 deletion src/viam/components/generic/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# from .generic import Generic


class GenericRPCService(GenericServiceBase, ResourceRPCServiceBase[ComponentBase]):
class GenericRPCService(GenericServiceBase, ResourceRPCServiceBase):
"""
gRPC Service for a Generic component
"""
Expand Down
2 changes: 1 addition & 1 deletion src/viam/components/gripper/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from .gripper import Gripper


class GripperRPCService(GripperServiceBase, ResourceRPCServiceBase[Gripper]):
class GripperRPCService(GripperServiceBase, ResourceRPCServiceBase):
"""
gRPC Service for a Gripper
"""
Expand Down
2 changes: 1 addition & 1 deletion src/viam/components/input/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
LOGGER = viam.logging.getLogger(__name__)


class InputControllerRPCService(InputControllerServiceBase, ResourceRPCServiceBase[Controller]):
class InputControllerRPCService(InputControllerServiceBase, ResourceRPCServiceBase):
"""
gRPC Service for an input controller
"""
Expand Down
2 changes: 1 addition & 1 deletion src/viam/components/motor/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from .motor import Motor


class MotorRPCService(MotorServiceBase, ResourceRPCServiceBase[Motor]):
class MotorRPCService(MotorServiceBase, ResourceRPCServiceBase):
"""
gRPC Service for a Motor
"""
Expand Down
2 changes: 1 addition & 1 deletion src/viam/components/movement_sensor/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from viam.utils import dict_to_struct, struct_to_dict


class MovementSensorRPCService(MovementSensorServiceBase, ResourceRPCServiceBase[MovementSensor]):
class MovementSensorRPCService(MovementSensorServiceBase, ResourceRPCServiceBase):
"""
gRPC Service for a MovementSensor
"""
Expand Down
2 changes: 1 addition & 1 deletion src/viam/components/pose_tracker/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from .pose_tracker import PoseTracker


class PoseTrackerRPCService(PoseTrackerServiceBase, ResourceRPCServiceBase[PoseTracker]):
class PoseTrackerRPCService(PoseTrackerServiceBase, ResourceRPCServiceBase):
"""
gRPC service for a pose tracker
"""
Expand Down
2 changes: 1 addition & 1 deletion src/viam/components/sensor/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from .sensor import Sensor


class SensorRPCService(SensorServiceBase, ResourceRPCServiceBase[Sensor]):
class SensorRPCService(SensorServiceBase, ResourceRPCServiceBase):
"""
gRPC Service for a generic Sensor
"""
Expand Down
2 changes: 1 addition & 1 deletion src/viam/components/servo/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from .servo import Servo


class ServoRPCService(ServoServiceBase, ResourceRPCServiceBase[Servo]):
class ServoRPCService(ServoServiceBase, ResourceRPCServiceBase):
"""
gRPC Service for a Servo
"""
Expand Down
20 changes: 11 additions & 9 deletions src/viam/module/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
from typing_extensions import Self

from viam import logging
from viam.components.component_base import ComponentBase
from viam.errors import ResourceNotFoundError, ValidationError
from viam.proto.app.robot import ComponentConfig
from viam.proto.module import (
Expand All @@ -24,7 +23,7 @@
from viam.proto.robot import ResourceRPCSubtype
from viam.resource.base import ResourceBase
from viam.resource.registry import Registry
from viam.resource.types import Model, ResourceName, Subtype, resource_name_from_string
from viam.resource.types import RESOURCE_TYPE_COMPONENT, RESOURCE_TYPE_SERVICE, Model, ResourceName, Subtype, resource_name_from_string
from viam.robot.client import RobotClient
from viam.rpc.dial import DialOptions
from viam.rpc.server import Server
Expand Down Expand Up @@ -83,18 +82,21 @@ async def _connect_to_parent(self):
),
)

async def _get_component(self, name: ResourceName) -> ComponentBase:
async def _get_resource(self, name: ResourceName) -> ResourceBase:
await self._connect_to_parent()
assert self.parent is not None
await self.parent.refresh()
return self.parent.get_component(name)

async def _get_dependencies(self, dependencies: Sequence[str]) -> Mapping[ResourceName, ComponentBase]:
deps: Mapping[ResourceName, ComponentBase] = {}
if name.type == RESOURCE_TYPE_COMPONENT:
return self.parent.get_component(name)
elif name.type == RESOURCE_TYPE_SERVICE:
return self.parent.get_service(name)
raise ValueError("Dependency does not describe a component nor a service")

async def _get_dependencies(self, dependencies: Sequence[str]) -> Mapping[ResourceName, ResourceBase]:
deps: Mapping[ResourceName, ResourceBase] = {}
for dep in dependencies:
rn = resource_name_from_string(dep)
component = await self._get_component(rn)
deps[rn] = component
deps[rn] = await self._get_resource(rn)
return deps

async def start(self):
Expand Down
25 changes: 13 additions & 12 deletions src/viam/resource/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,29 +28,30 @@ def __init__(self, components: List[ResourceBase] = []) -> None:
for component in components:
self.register(component)

def register(self, component: ResourceBase):
def register(self, resource: ResourceBase):
"""
Register a new component with the registry.
Components may not have the same name.
If a component is remote and the short name is unique, save a short name version.
Register a new resource with the registry.
Resources may not have the same name.
If a resource is remote and the short name is unique, save a short name version.

Raises:
DuplicateComponentError: Error if attempting to register component
with the name of an existing component
DuplicateResourceError: Error if attempting to register resource
with the name of an existing resource
ResourceNotFoundError: Raised if the subtype of the resource is not registered

Args:
component (ResourceBase): The component to register
resource (ResourceBase): The resource to register
"""
Registry.lookup_subtype(component.SUBTYPE) # confirm the subtype is registered in Registry
Registry.lookup_subtype(resource.SUBTYPE) # confirm the subtype is registered in Registry

_BaseClasses = (ResourceBase, ComponentBase, ServiceBase)
rnames: Dict[ResourceName, ResourceBase] = {}
for subtype in component.__class__.mro():
for subtype in resource.__class__.mro():
if subtype in _BaseClasses:
continue
if hasattr(subtype, "get_resource_name"):
rn = subtype.get_resource_name(component.name) # type: ignore
rnames[rn] = component
rn = subtype.get_resource_name(resource.name) # type: ignore
rnames[rn] = resource
for rn in rnames:
if ":" in rn.name:
short_name = rn.name.split(":")[-1]
Expand All @@ -60,7 +61,7 @@ def register(self, component: ResourceBase):
self._short_to_long_name[short_name] = [rn]

if rnames.keys() & self.resources.keys():
raise DuplicateResourceError(component.name)
raise DuplicateResourceError(resource.name)

with self._lock:
self.resources.update(rnames)
Expand Down
14 changes: 8 additions & 6 deletions src/viam/resource/rpc_service_base.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@
import abc
from typing import Generic, Type
from typing import Type, TYPE_CHECKING

from viam.components.component_base import ComponentBase
from viam.errors import ResourceNotFoundError
from viam.resource.manager import ResourceManager, ResourceType
from viam.rpc.types import RPCServiceBase
from viam.services.service_base import ServiceBase

from .base import ResourceBase

if TYPE_CHECKING:
from viam.resource.manager import ResourceManager

class ResourceRPCServiceBase(abc.ABC, RPCServiceBase, Generic[ResourceType]):

class ResourceRPCServiceBase(abc.ABC, RPCServiceBase):
"""
Base RPC service for a resource.
All resource RPC services must inherit from this class.
"""

RESOURCE_TYPE = Type
manager: ResourceManager
manager: "ResourceManager"

def __init__(self, manager: ResourceManager):
def __init__(self, manager: "ResourceManager"):
self.manager = manager

def get_resource(self, name: str) -> ResourceType:
def get_resource(self, name: str) -> RESOURCE_TYPE:
"""
Return the resource with the given name if it exists in the registry.
If the resource does not exist in the registry,
Expand Down
6 changes: 6 additions & 0 deletions src/viam/robot/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import viam
from viam import logging
from viam.components.component_base import ComponentBase
from viam.components.movement_sensor import MovementSensor
from viam.components.sensor import Sensor
from viam.errors import ResourceNotFoundError
from viam.proto.common import PoseInFrame, ResourceName, Transform
from viam.proto.robot import (
Expand Down Expand Up @@ -205,6 +207,10 @@ async def refresh(self):
if rname.subtype == "remote":
continue

# If the resource is a MovementSensor, DO NOT include Sensor as well (it will get added via MovementSensor)
if rname.subtype == Sensor.SUBTYPE.resource_subtype and MovementSensor.get_resource_name(rname.name) in resource_names:
continue

self._create_or_reset_client(rname)

for rname in self.resource_names:
Expand Down
18 changes: 12 additions & 6 deletions src/viam/robot/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
from viam.resource.registry import Registry
from viam.resource.rpc_service_base import ResourceRPCServiceBase
from viam.utils import resource_names_for_resource, struct_to_dict
from viam.components.sensor import Sensor
from viam.components.movement_sensor import MovementSensor

LOGGER = logging.getLogger(__name__)

Expand All @@ -51,22 +53,26 @@ class RobotService(RobotServiceBase, ResourceRPCServiceBase):
def _generate_metadata(self) -> List[ResourceName]:
md: Set[ResourceName] = set()

for component in self.manager.resources.values():
md.update(resource_names_for_resource(component))
for resource in self.manager.resources.values():
# If the resource is a MovementSensor, DO NOT include Sensor as well (it will get added via MovementSensor)
if resource.SUBTYPE == Sensor.SUBTYPE and MovementSensor.get_resource_name(resource.name) in self.manager.resources:
continue

md.update(resource_names_for_resource(resource))

return list(md)

async def _generate_status(self, resource_names: Iterable[ResourceName]) -> List[Status]:
statuses: List[Status] = []
seen_resource_names: Set[ResourceName] = set()

for component in self.manager.resources.values():
for resource in self.manager.resources.values():
for registration in Registry.REGISTERED_SUBTYPES().values():
if isinstance(component, registration.resource_type):
if resource_names and component.get_resource_name(component.name) not in resource_names:
if isinstance(resource, registration.resource_type):
if resource_names and resource.get_resource_name(resource.name) not in resource_names:
continue
try:
status = await registration.create_status(component)
status = await registration.create_status(resource)
if status.name not in seen_resource_names:
seen_resource_names.add(status.name)
statuses.append(status)
Expand Down
2 changes: 1 addition & 1 deletion src/viam/services/mlmodel/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from .mlmodel import MLModel


class MLModelRPCService(MLModelServiceBase, ResourceRPCServiceBase[MLModel]):
class MLModelRPCService(MLModelServiceBase, ResourceRPCServiceBase):
"""
gRPC service for a ML Model service
"""
Expand Down
2 changes: 1 addition & 1 deletion src/viam/services/slam/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from .slam import SLAM


class SLAMRPCService(SLAMServiceBase, ResourceRPCServiceBase[SLAM]):
class SLAMRPCService(SLAMServiceBase, ResourceRPCServiceBase):
"""
gRPC Service for a SLAM service
"""
Expand Down
2 changes: 1 addition & 1 deletion src/viam/services/vision/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from .vision import Vision


class VisionRPCService(VisionServiceBase, ResourceRPCServiceBase[Vision]):
class VisionRPCService(VisionServiceBase, ResourceRPCServiceBase):
"""
gRPC service for a Vision service
"""
Expand Down
2 changes: 1 addition & 1 deletion tests/mocks/module/gizmo/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ async def do_two(self, arg1: bool, **kwargs) -> str:
...


class GizmoService(GizmoServiceBase, ResourceRPCServiceBase[Gizmo]):
class GizmoService(GizmoServiceBase, ResourceRPCServiceBase):
"""Example gRPC service for the Gizmo component"""

RESOURCE_TYPE = Gizmo
Expand Down
Loading