# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
"""Client and server classes corresponding to protobuf-defined services."""
import grpc

from dmi import hw_metrics_mgmt_service_pb2 as dmi_dot_hw__metrics__mgmt__service__pb2
from dmi import hw_pb2 as dmi_dot_hw__pb2


class NativeMetricsManagementServiceStub(object):
    """Missing associated documentation comment in .proto file."""

    def __init__(self, channel):
        """Constructor.

        Args:
            channel: A grpc.Channel.
        """
        self.ListMetrics = channel.unary_unary(
                '/dmi.NativeMetricsManagementService/ListMetrics',
                request_serializer=dmi_dot_hw__pb2.HardwareID.SerializeToString,
                response_deserializer=dmi_dot_hw__metrics__mgmt__service__pb2.ListMetricsResponse.FromString,
                )
        self.UpdateMetricsConfiguration = channel.unary_unary(
                '/dmi.NativeMetricsManagementService/UpdateMetricsConfiguration',
                request_serializer=dmi_dot_hw__metrics__mgmt__service__pb2.MetricsConfigurationRequest.SerializeToString,
                response_deserializer=dmi_dot_hw__metrics__mgmt__service__pb2.MetricsConfigurationResponse.FromString,
                )
        self.GetMetric = channel.unary_unary(
                '/dmi.NativeMetricsManagementService/GetMetric',
                request_serializer=dmi_dot_hw__metrics__mgmt__service__pb2.GetMetricRequest.SerializeToString,
                response_deserializer=dmi_dot_hw__metrics__mgmt__service__pb2.GetMetricResponse.FromString,
                )


class NativeMetricsManagementServiceServicer(object):
    """Missing associated documentation comment in .proto file."""

    def ListMetrics(self, request, context):
        """List the supported metrics for the passed device.
        This would be the first call that you make to know about the metrics that a particular device supports and
        then use the UpdateMetricsConfiguration API to monitor only the required metrics.
        """
        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
        context.set_details('Method not implemented!')
        raise NotImplementedError('Method not implemented!')

    def UpdateMetricsConfiguration(self, request, context):
        """Updates the configuration of the list of metrics in the request
        Acts upon single metric configuration, collection of a single metric can be started/stopped
        by changing its configuration.
        
        This configuration is persisted across restart of the device or the device manager
        """
        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
        context.set_details('Method not implemented!')
        raise NotImplementedError('Method not implemented!')

    def GetMetric(self, request, context):
        """Get the instantenous value of a metric
        """
        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
        context.set_details('Method not implemented!')
        raise NotImplementedError('Method not implemented!')


def add_NativeMetricsManagementServiceServicer_to_server(servicer, server):
    rpc_method_handlers = {
            'ListMetrics': grpc.unary_unary_rpc_method_handler(
                    servicer.ListMetrics,
                    request_deserializer=dmi_dot_hw__pb2.HardwareID.FromString,
                    response_serializer=dmi_dot_hw__metrics__mgmt__service__pb2.ListMetricsResponse.SerializeToString,
            ),
            'UpdateMetricsConfiguration': grpc.unary_unary_rpc_method_handler(
                    servicer.UpdateMetricsConfiguration,
                    request_deserializer=dmi_dot_hw__metrics__mgmt__service__pb2.MetricsConfigurationRequest.FromString,
                    response_serializer=dmi_dot_hw__metrics__mgmt__service__pb2.MetricsConfigurationResponse.SerializeToString,
            ),
            'GetMetric': grpc.unary_unary_rpc_method_handler(
                    servicer.GetMetric,
                    request_deserializer=dmi_dot_hw__metrics__mgmt__service__pb2.GetMetricRequest.FromString,
                    response_serializer=dmi_dot_hw__metrics__mgmt__service__pb2.GetMetricResponse.SerializeToString,
            ),
    }
    generic_handler = grpc.method_handlers_generic_handler(
            'dmi.NativeMetricsManagementService', rpc_method_handlers)
    server.add_generic_rpc_handlers((generic_handler,))


 # This class is part of an EXPERIMENTAL API.
class NativeMetricsManagementService(object):
    """Missing associated documentation comment in .proto file."""

    @staticmethod
    def ListMetrics(request,
            target,
            options=(),
            channel_credentials=None,
            call_credentials=None,
            insecure=False,
            compression=None,
            wait_for_ready=None,
            timeout=None,
            metadata=None):
        return grpc.experimental.unary_unary(request, target, '/dmi.NativeMetricsManagementService/ListMetrics',
            dmi_dot_hw__pb2.HardwareID.SerializeToString,
            dmi_dot_hw__metrics__mgmt__service__pb2.ListMetricsResponse.FromString,
            options, channel_credentials,
            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)

    @staticmethod
    def UpdateMetricsConfiguration(request,
            target,
            options=(),
            channel_credentials=None,
            call_credentials=None,
            insecure=False,
            compression=None,
            wait_for_ready=None,
            timeout=None,
            metadata=None):
        return grpc.experimental.unary_unary(request, target, '/dmi.NativeMetricsManagementService/UpdateMetricsConfiguration',
            dmi_dot_hw__metrics__mgmt__service__pb2.MetricsConfigurationRequest.SerializeToString,
            dmi_dot_hw__metrics__mgmt__service__pb2.MetricsConfigurationResponse.FromString,
            options, channel_credentials,
            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)

    @staticmethod
    def GetMetric(request,
            target,
            options=(),
            channel_credentials=None,
            call_credentials=None,
            insecure=False,
            compression=None,
            wait_for_ready=None,
            timeout=None,
            metadata=None):
        return grpc.experimental.unary_unary(request, target, '/dmi.NativeMetricsManagementService/GetMetric',
            dmi_dot_hw__metrics__mgmt__service__pb2.GetMetricRequest.SerializeToString,
            dmi_dot_hw__metrics__mgmt__service__pb2.GetMetricResponse.FromString,
            options, channel_credentials,
            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
