diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 922a93ed..55ea8455 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,17 +6,17 @@ permissions: contents: read jobs: - build: + test: runs-on: ubuntu-latest strategy: matrix: - python-versions: ["3.11", "3.12"] + python: ["3.11", "3.12"] steps: - uses: actions/checkout@v4 - - name: Set up Python ${{ matrix.python-version }} + - name: Set up Python ${{ matrix.python }} uses: actions/setup-python@v4 with: - python-version: ${{ matrix.python-version }} + python-version: ${{ matrix.python }} cache: 'pip' - run: make dev - run: make test diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..f416ef4e --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.pyc +__pycache__ +.proto \ No newline at end of file diff --git a/Makefile b/Makefile index 0e5d570c..3dc808ef 100644 --- a/Makefile +++ b/Makefile @@ -5,11 +5,9 @@ PYTHON := python all: test install: - export PIP_EXTRA_INDEX_URL=https://buf.build/gen/python $(PYTHON) -m pip install -e . dev: - export PIP_EXTRA_INDEX_URL=https://buf.build/gen/python $(PYTHON) -m pip install -e .[dev] fmt: diff --git a/buf.gen.yaml b/buf.gen.yaml index 91fb9e13..4337662f 100644 --- a/buf.gen.yaml +++ b/buf.gen.yaml @@ -5,3 +5,5 @@ managed: plugins: - plugin: buf.build/protocolbuffers/python:v25.2 out: src/ + - plugin: buf.build/grpc/python:v1.60.0 + out: src/ diff --git a/pyproject.toml b/pyproject.toml index f5ebc4b5..86b68d10 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,11 +5,10 @@ build-backend = "setuptools.build_meta" [project] name = "dispatch-sdk" dynamic = ["version"] -requires-python = ">= 3.12" +requires-python = ">= 3.11" dependencies = [ - "stealthrocket_ring_grpc_python==1.60.0.1.20240126005632+6a2bbfaf59e6", - "stealthrocket_ring_protocolbuffers_python==25.2.0.1.20240126005632+6a2bbfaf59e6", - "stealthrocket_dispatch_protocolbuffers_python==25.2.0.1.20240119005337+14bf27236bb7", + "grpcio==1.60.0", + "protobuf==4.25.2" ] [project.optional-dependencies] diff --git a/src/dispatch/http/v1/http_pb2_grpc.py b/src/dispatch/http/v1/http_pb2_grpc.py new file mode 100644 index 00000000..8a939394 --- /dev/null +++ b/src/dispatch/http/v1/http_pb2_grpc.py @@ -0,0 +1,3 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc diff --git a/src/dispatch/security/v1/security_pb2_grpc.py b/src/dispatch/security/v1/security_pb2_grpc.py new file mode 100644 index 00000000..8a939394 --- /dev/null +++ b/src/dispatch/security/v1/security_pb2_grpc.py @@ -0,0 +1,3 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc diff --git a/src/dispatch/v1/metadata_pb2_grpc.py b/src/dispatch/v1/metadata_pb2_grpc.py new file mode 100644 index 00000000..8a939394 --- /dev/null +++ b/src/dispatch/v1/metadata_pb2_grpc.py @@ -0,0 +1,3 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc diff --git a/src/ring/admin/v1/cluster_pb2_grpc.py b/src/ring/admin/v1/cluster_pb2_grpc.py new file mode 100644 index 00000000..009ee87e --- /dev/null +++ b/src/ring/admin/v1/cluster_pb2_grpc.py @@ -0,0 +1,304 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +from ring.admin.v1 import cluster_pb2 as ring_dot_admin_dot_v1_dot_cluster__pb2 + + +class ClusterServiceStub(object): + """Missing associated documentation comment in .proto file.""" + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.DescribeInstances = channel.unary_unary( + "/ring.admin.v1.ClusterService/DescribeInstances", + request_serializer=ring_dot_admin_dot_v1_dot_cluster__pb2.DescribeInstancesRequest.SerializeToString, + response_deserializer=ring_dot_admin_dot_v1_dot_cluster__pb2.DescribeInstancesResponse.FromString, + ) + self.DescribePartitions = channel.unary_unary( + "/ring.admin.v1.ClusterService/DescribePartitions", + request_serializer=ring_dot_admin_dot_v1_dot_cluster__pb2.DescribePartitionsRequest.SerializeToString, + response_deserializer=ring_dot_admin_dot_v1_dot_cluster__pb2.DescribePartitionsResponse.FromString, + ) + self.DescribeZones = channel.unary_unary( + "/ring.admin.v1.ClusterService/DescribeZones", + request_serializer=ring_dot_admin_dot_v1_dot_cluster__pb2.DescribeZonesRequest.SerializeToString, + response_deserializer=ring_dot_admin_dot_v1_dot_cluster__pb2.DescribeZonesResponse.FromString, + ) + self.ListInstances = channel.unary_unary( + "/ring.admin.v1.ClusterService/ListInstances", + request_serializer=ring_dot_admin_dot_v1_dot_cluster__pb2.ListInstancesRequest.SerializeToString, + response_deserializer=ring_dot_admin_dot_v1_dot_cluster__pb2.ListInstancesResponse.FromString, + ) + self.ListPartitions = channel.unary_unary( + "/ring.admin.v1.ClusterService/ListPartitions", + request_serializer=ring_dot_admin_dot_v1_dot_cluster__pb2.ListPartitionsRequest.SerializeToString, + response_deserializer=ring_dot_admin_dot_v1_dot_cluster__pb2.ListPartitionsResponse.FromString, + ) + self.ListZones = channel.unary_unary( + "/ring.admin.v1.ClusterService/ListZones", + request_serializer=ring_dot_admin_dot_v1_dot_cluster__pb2.ListZonesRequest.SerializeToString, + response_deserializer=ring_dot_admin_dot_v1_dot_cluster__pb2.ListZonesResponse.FromString, + ) + + +class ClusterServiceServicer(object): + """Missing associated documentation comment in .proto file.""" + + def DescribeInstances(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def DescribePartitions(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def DescribeZones(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def ListInstances(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def ListPartitions(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def ListZones(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + +def add_ClusterServiceServicer_to_server(servicer, server): + rpc_method_handlers = { + "DescribeInstances": grpc.unary_unary_rpc_method_handler( + servicer.DescribeInstances, + request_deserializer=ring_dot_admin_dot_v1_dot_cluster__pb2.DescribeInstancesRequest.FromString, + response_serializer=ring_dot_admin_dot_v1_dot_cluster__pb2.DescribeInstancesResponse.SerializeToString, + ), + "DescribePartitions": grpc.unary_unary_rpc_method_handler( + servicer.DescribePartitions, + request_deserializer=ring_dot_admin_dot_v1_dot_cluster__pb2.DescribePartitionsRequest.FromString, + response_serializer=ring_dot_admin_dot_v1_dot_cluster__pb2.DescribePartitionsResponse.SerializeToString, + ), + "DescribeZones": grpc.unary_unary_rpc_method_handler( + servicer.DescribeZones, + request_deserializer=ring_dot_admin_dot_v1_dot_cluster__pb2.DescribeZonesRequest.FromString, + response_serializer=ring_dot_admin_dot_v1_dot_cluster__pb2.DescribeZonesResponse.SerializeToString, + ), + "ListInstances": grpc.unary_unary_rpc_method_handler( + servicer.ListInstances, + request_deserializer=ring_dot_admin_dot_v1_dot_cluster__pb2.ListInstancesRequest.FromString, + response_serializer=ring_dot_admin_dot_v1_dot_cluster__pb2.ListInstancesResponse.SerializeToString, + ), + "ListPartitions": grpc.unary_unary_rpc_method_handler( + servicer.ListPartitions, + request_deserializer=ring_dot_admin_dot_v1_dot_cluster__pb2.ListPartitionsRequest.FromString, + response_serializer=ring_dot_admin_dot_v1_dot_cluster__pb2.ListPartitionsResponse.SerializeToString, + ), + "ListZones": grpc.unary_unary_rpc_method_handler( + servicer.ListZones, + request_deserializer=ring_dot_admin_dot_v1_dot_cluster__pb2.ListZonesRequest.FromString, + response_serializer=ring_dot_admin_dot_v1_dot_cluster__pb2.ListZonesResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + "ring.admin.v1.ClusterService", rpc_method_handlers + ) + server.add_generic_rpc_handlers((generic_handler,)) + + +# This class is part of an EXPERIMENTAL API. +class ClusterService(object): + """Missing associated documentation comment in .proto file.""" + + @staticmethod + def DescribeInstances( + 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, + "/ring.admin.v1.ClusterService/DescribeInstances", + ring_dot_admin_dot_v1_dot_cluster__pb2.DescribeInstancesRequest.SerializeToString, + ring_dot_admin_dot_v1_dot_cluster__pb2.DescribeInstancesResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def DescribePartitions( + 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, + "/ring.admin.v1.ClusterService/DescribePartitions", + ring_dot_admin_dot_v1_dot_cluster__pb2.DescribePartitionsRequest.SerializeToString, + ring_dot_admin_dot_v1_dot_cluster__pb2.DescribePartitionsResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def DescribeZones( + 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, + "/ring.admin.v1.ClusterService/DescribeZones", + ring_dot_admin_dot_v1_dot_cluster__pb2.DescribeZonesRequest.SerializeToString, + ring_dot_admin_dot_v1_dot_cluster__pb2.DescribeZonesResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def ListInstances( + 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, + "/ring.admin.v1.ClusterService/ListInstances", + ring_dot_admin_dot_v1_dot_cluster__pb2.ListInstancesRequest.SerializeToString, + ring_dot_admin_dot_v1_dot_cluster__pb2.ListInstancesResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def ListPartitions( + 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, + "/ring.admin.v1.ClusterService/ListPartitions", + ring_dot_admin_dot_v1_dot_cluster__pb2.ListPartitionsRequest.SerializeToString, + ring_dot_admin_dot_v1_dot_cluster__pb2.ListPartitionsResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def ListZones( + 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, + "/ring.admin.v1.ClusterService/ListZones", + ring_dot_admin_dot_v1_dot_cluster__pb2.ListZonesRequest.SerializeToString, + ring_dot_admin_dot_v1_dot_cluster__pb2.ListZonesResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) diff --git a/src/ring/admin/v1/member_pb2_grpc.py b/src/ring/admin/v1/member_pb2_grpc.py new file mode 100644 index 00000000..11038de8 --- /dev/null +++ b/src/ring/admin/v1/member_pb2_grpc.py @@ -0,0 +1,79 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +from ring.admin.v1 import member_pb2 as ring_dot_admin_dot_v1_dot_member__pb2 + + +class MemberServiceStub(object): + """Missing associated documentation comment in .proto file.""" + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.MemberState = channel.unary_unary( + "/ring.admin.v1.MemberService/MemberState", + request_serializer=ring_dot_admin_dot_v1_dot_member__pb2.MemberStateRequest.SerializeToString, + response_deserializer=ring_dot_admin_dot_v1_dot_member__pb2.MemberStateResponse.FromString, + ) + + +class MemberServiceServicer(object): + """Missing associated documentation comment in .proto file.""" + + def MemberState(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + +def add_MemberServiceServicer_to_server(servicer, server): + rpc_method_handlers = { + "MemberState": grpc.unary_unary_rpc_method_handler( + servicer.MemberState, + request_deserializer=ring_dot_admin_dot_v1_dot_member__pb2.MemberStateRequest.FromString, + response_serializer=ring_dot_admin_dot_v1_dot_member__pb2.MemberStateResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + "ring.admin.v1.MemberService", rpc_method_handlers + ) + server.add_generic_rpc_handlers((generic_handler,)) + + +# This class is part of an EXPERIMENTAL API. +class MemberService(object): + """Missing associated documentation comment in .proto file.""" + + @staticmethod + def MemberState( + 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, + "/ring.admin.v1.MemberService/MemberState", + ring_dot_admin_dot_v1_dot_member__pb2.MemberStateRequest.SerializeToString, + ring_dot_admin_dot_v1_dot_member__pb2.MemberStateResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) diff --git a/src/ring/coroutine/v1/coroutine_pb2_grpc.py b/src/ring/coroutine/v1/coroutine_pb2_grpc.py new file mode 100644 index 00000000..5280f1bb --- /dev/null +++ b/src/ring/coroutine/v1/coroutine_pb2_grpc.py @@ -0,0 +1,81 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +from ring.coroutine.v1 import ( + coroutine_pb2 as ring_dot_coroutine_dot_v1_dot_coroutine__pb2, +) + + +class ExecutorServiceStub(object): + """The Executor service is used to execute coroutines remotely.""" + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.Execute = channel.unary_unary( + "/ring.coroutine.v1.ExecutorService/Execute", + request_serializer=ring_dot_coroutine_dot_v1_dot_coroutine__pb2.ExecuteRequest.SerializeToString, + response_deserializer=ring_dot_coroutine_dot_v1_dot_coroutine__pb2.ExecuteResponse.FromString, + ) + + +class ExecutorServiceServicer(object): + """The Executor service is used to execute coroutines remotely.""" + + def Execute(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + +def add_ExecutorServiceServicer_to_server(servicer, server): + rpc_method_handlers = { + "Execute": grpc.unary_unary_rpc_method_handler( + servicer.Execute, + request_deserializer=ring_dot_coroutine_dot_v1_dot_coroutine__pb2.ExecuteRequest.FromString, + response_serializer=ring_dot_coroutine_dot_v1_dot_coroutine__pb2.ExecuteResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + "ring.coroutine.v1.ExecutorService", rpc_method_handlers + ) + server.add_generic_rpc_handlers((generic_handler,)) + + +# This class is part of an EXPERIMENTAL API. +class ExecutorService(object): + """The Executor service is used to execute coroutines remotely.""" + + @staticmethod + def Execute( + 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, + "/ring.coroutine.v1.ExecutorService/Execute", + ring_dot_coroutine_dot_v1_dot_coroutine__pb2.ExecuteRequest.SerializeToString, + ring_dot_coroutine_dot_v1_dot_coroutine__pb2.ExecuteResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) diff --git a/src/ring/http/v1/http_pb2_grpc.py b/src/ring/http/v1/http_pb2_grpc.py new file mode 100644 index 00000000..8a939394 --- /dev/null +++ b/src/ring/http/v1/http_pb2_grpc.py @@ -0,0 +1,3 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc diff --git a/src/ring/record/v1/record_pb2_grpc.py b/src/ring/record/v1/record_pb2_grpc.py new file mode 100644 index 00000000..a704a76c --- /dev/null +++ b/src/ring/record/v1/record_pb2_grpc.py @@ -0,0 +1,190 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +from ring.record.v1 import record_pb2 as ring_dot_record_dot_v1_dot_record__pb2 + + +class BlockStoreServiceStub(object): + """BlockStoreService is a service that provides access to record blocks stored + by Ring instances. + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.GetBlockRanges = channel.unary_unary( + "/ring.record.v1.BlockStoreService/GetBlockRanges", + request_serializer=ring_dot_record_dot_v1_dot_record__pb2.GetBlockRangesRequest.SerializeToString, + response_deserializer=ring_dot_record_dot_v1_dot_record__pb2.GetBlockRangesResponse.FromString, + ) + self.GetBlockMetadata = channel.unary_unary( + "/ring.record.v1.BlockStoreService/GetBlockMetadata", + request_serializer=ring_dot_record_dot_v1_dot_record__pb2.GetBlockMetadataRequest.SerializeToString, + response_deserializer=ring_dot_record_dot_v1_dot_record__pb2.GetBlockMetadataResponse.FromString, + ) + self.ScanBlocks = channel.unary_stream( + "/ring.record.v1.BlockStoreService/ScanBlocks", + request_serializer=ring_dot_record_dot_v1_dot_record__pb2.ScanBlocksRequest.SerializeToString, + response_deserializer=ring_dot_record_dot_v1_dot_record__pb2.ScanBlocksResponse.FromString, + ) + + +class BlockStoreServiceServicer(object): + """BlockStoreService is a service that provides access to record blocks stored + by Ring instances. + """ + + def GetBlockRanges(self, request, context): + """GetBlockRanges queries ranges of record blocks. + + The method allows querying multiple ranges, and returns one block range + for each range that was queried. If one of the requested ranges could not + be read, the corresponding block range will contain an error. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def GetBlockMetadata(self, request, context): + """GetBlockMetadata queries metadata about record blocks. + + The method allows querying multiple prefixes, and returns one block entry + for each prefix that was queried. If one of the requested prefixes could + not be read, the corresponding block entry will contain an error. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def ScanBlocks(self, request, context): + """ScanBlocks scans blocks of records for a given partition, returning a + stream of ScanBlocksResponse messages. + + The request can set a limit to the number of block entries returned in the + response. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + +def add_BlockStoreServiceServicer_to_server(servicer, server): + rpc_method_handlers = { + "GetBlockRanges": grpc.unary_unary_rpc_method_handler( + servicer.GetBlockRanges, + request_deserializer=ring_dot_record_dot_v1_dot_record__pb2.GetBlockRangesRequest.FromString, + response_serializer=ring_dot_record_dot_v1_dot_record__pb2.GetBlockRangesResponse.SerializeToString, + ), + "GetBlockMetadata": grpc.unary_unary_rpc_method_handler( + servicer.GetBlockMetadata, + request_deserializer=ring_dot_record_dot_v1_dot_record__pb2.GetBlockMetadataRequest.FromString, + response_serializer=ring_dot_record_dot_v1_dot_record__pb2.GetBlockMetadataResponse.SerializeToString, + ), + "ScanBlocks": grpc.unary_stream_rpc_method_handler( + servicer.ScanBlocks, + request_deserializer=ring_dot_record_dot_v1_dot_record__pb2.ScanBlocksRequest.FromString, + response_serializer=ring_dot_record_dot_v1_dot_record__pb2.ScanBlocksResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + "ring.record.v1.BlockStoreService", rpc_method_handlers + ) + server.add_generic_rpc_handlers((generic_handler,)) + + +# This class is part of an EXPERIMENTAL API. +class BlockStoreService(object): + """BlockStoreService is a service that provides access to record blocks stored + by Ring instances. + """ + + @staticmethod + def GetBlockRanges( + 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, + "/ring.record.v1.BlockStoreService/GetBlockRanges", + ring_dot_record_dot_v1_dot_record__pb2.GetBlockRangesRequest.SerializeToString, + ring_dot_record_dot_v1_dot_record__pb2.GetBlockRangesResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def GetBlockMetadata( + 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, + "/ring.record.v1.BlockStoreService/GetBlockMetadata", + ring_dot_record_dot_v1_dot_record__pb2.GetBlockMetadataRequest.SerializeToString, + ring_dot_record_dot_v1_dot_record__pb2.GetBlockMetadataResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def ScanBlocks( + 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_stream( + request, + target, + "/ring.record.v1.BlockStoreService/ScanBlocks", + ring_dot_record_dot_v1_dot_record__pb2.ScanBlocksRequest.SerializeToString, + ring_dot_record_dot_v1_dot_record__pb2.ScanBlocksResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) diff --git a/src/ring/snapshot/v1/snapshot_pb2_grpc.py b/src/ring/snapshot/v1/snapshot_pb2_grpc.py new file mode 100644 index 00000000..8a939394 --- /dev/null +++ b/src/ring/snapshot/v1/snapshot_pb2_grpc.py @@ -0,0 +1,3 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc diff --git a/src/ring/status/v1/status_pb2_grpc.py b/src/ring/status/v1/status_pb2_grpc.py new file mode 100644 index 00000000..8a939394 --- /dev/null +++ b/src/ring/status/v1/status_pb2_grpc.py @@ -0,0 +1,3 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc diff --git a/src/ring/task/v1/config_pb2_grpc.py b/src/ring/task/v1/config_pb2_grpc.py new file mode 100644 index 00000000..8a939394 --- /dev/null +++ b/src/ring/task/v1/config_pb2_grpc.py @@ -0,0 +1,3 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc diff --git a/src/ring/task/v1/service_pb2_grpc.py b/src/ring/task/v1/service_pb2_grpc.py new file mode 100644 index 00000000..b576cc3c --- /dev/null +++ b/src/ring/task/v1/service_pb2_grpc.py @@ -0,0 +1,85 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +from ring.task.v1 import service_pb2 as ring_dot_task_dot_v1_dot_service__pb2 + + +class ServiceStub(object): + """Service represents the set of APIs to perform the administration of tasks in + a Ring instance. + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.CreateTasks = channel.unary_unary( + "/ring.task.v1.Service/CreateTasks", + request_serializer=ring_dot_task_dot_v1_dot_service__pb2.CreateTasksRequest.SerializeToString, + response_deserializer=ring_dot_task_dot_v1_dot_service__pb2.CreateTasksResponse.FromString, + ) + + +class ServiceServicer(object): + """Service represents the set of APIs to perform the administration of tasks in + a Ring instance. + """ + + def CreateTasks(self, request, context): + """CreateTasks is invoked to create new tasks.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + +def add_ServiceServicer_to_server(servicer, server): + rpc_method_handlers = { + "CreateTasks": grpc.unary_unary_rpc_method_handler( + servicer.CreateTasks, + request_deserializer=ring_dot_task_dot_v1_dot_service__pb2.CreateTasksRequest.FromString, + response_serializer=ring_dot_task_dot_v1_dot_service__pb2.CreateTasksResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + "ring.task.v1.Service", rpc_method_handlers + ) + server.add_generic_rpc_handlers((generic_handler,)) + + +# This class is part of an EXPERIMENTAL API. +class Service(object): + """Service represents the set of APIs to perform the administration of tasks in + a Ring instance. + """ + + @staticmethod + def CreateTasks( + 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, + "/ring.task.v1.Service/CreateTasks", + ring_dot_task_dot_v1_dot_service__pb2.CreateTasksRequest.SerializeToString, + ring_dot_task_dot_v1_dot_service__pb2.CreateTasksResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) diff --git a/src/ring/task/v1/task_pb2_grpc.py b/src/ring/task/v1/task_pb2_grpc.py new file mode 100644 index 00000000..8a939394 --- /dev/null +++ b/src/ring/task/v1/task_pb2_grpc.py @@ -0,0 +1,3 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc diff --git a/tests/test_ring.py b/tests/test_ring.py index 3c22030e..fbdd7908 100644 --- a/tests/test_ring.py +++ b/tests/test_ring.py @@ -1,21 +1,51 @@ import unittest +import concurrent.futures.thread import dispatch -import ring.task.v1.service_pb2 +import ring.task.v1.service_pb2 as service_pb +import ring.task.v1.service_pb2_grpc as service_grpc +import dispatch.http.v1.http_pb2 import grpc +import google.protobuf.any_pb2 + + +class FakeRing(service_grpc.ServiceServicer): + def CreateTasks(self, request, context): + return service_pb.CreateTasksResponse() class TestRing(unittest.TestCase): + def setUp(self): + self.thread_pool = concurrent.futures.thread.ThreadPoolExecutor() + self.server = grpc.server(self.thread_pool) + + port = self.server.add_insecure_port("127.0.0.1:0") + + servicer = FakeRing() + + service_grpc.add_ServiceServicer_to_server(servicer, self.server) + self.server.start() + + channel = grpc.insecure_channel(f"127.0.0.1:{port}") + self.ring_stub = service_grpc.ServiceStub(channel) + + def tearDown(self): + self.server.stop(0) + self.server.wait_for_termination() + self.thread_pool.shutdown(wait=True, cancel_futures=True) + def test_ring(self): - channel = grpc.insecure_channel("localhost:4001") - stub = ring.task.v1.service_pb2_grpc.ServiceStub(channel) - create_task_input = ring.task.v1.service_pb2.CreateTaskInput( - coroutine_uri="dispatch-http", - input=ring.http.v1.service_pb2.HttpInput( - url="https://www.google.com", - method="GET", - headers={"Accept": "text/html", "User-Agent": "dispatch"}, - ), + + request = dispatch.http.v1.http_pb2.Request( + url="https://www.google.com", method="GET" + ) + + input = google.protobuf.any_pb2.Any() + input.Pack(request) + + create_task_input = service_pb.CreateTaskInput( + coroutine_uri="arn:aws:lambda:us-west-2:012345678912:function:dispatch-http", + input=input, ) - req = ring.task.v1.service_pb2.CreateTasksRequest(tasks=[create_task_input]) - resp = stub.CreateTasks(req) + req = service_pb.CreateTasksRequest(tasks=[create_task_input]) + resp = self.ring_stub.CreateTasks(req)