Skip to content

Commit

Permalink
Start of work on revamped descriptor printer
Browse files Browse the repository at this point in the history
  • Loading branch information
ViridianForge committed Nov 22, 2023
1 parent 4f26499 commit 662936f
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 2 deletions.
10 changes: 9 additions & 1 deletion src/grpc_requests/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from enum import Enum
from functools import partial
from typing import Any, Dict, Iterable, List, NamedTuple, Optional, Tuple, TypeVar, Union
import warnings

import grpc
from google.protobuf import descriptor_pb2, descriptor_pool as _descriptor_pool, message_factory
Expand All @@ -11,7 +12,7 @@
from google.protobuf.json_format import MessageToDict, ParseDict
from grpc_reflection.v1alpha import reflection_pb2, reflection_pb2_grpc

from .utils import describe_request, load_data
from .utils import describe_descriptor, describe_request, load_data

if sys.version_info >= (3, 8):
from typing import TypedDict # pylint: disable=no-name-in-module
Expand Down Expand Up @@ -307,7 +308,14 @@ def get_service_descriptor(self, service):
return self._desc_pool.FindServiceByName(service)

def describe_method_request(self, service, method):
warnings.warn("This function is deprecated, and will be removed in a future release. Use describe_request() instead.", DeprecationWarning)
return describe_request(self.get_method_descriptor(service, method))

def describe_request(self, service, method):
return describe_descriptor(self.get_method_descriptor(service, method).input_type)

def describe_response(self, service, method):
return describe_descriptor(self.get_method_descriptor(service, method).output_type)

def get_method_descriptor(self, service, method):
svc_desc = self.get_service_descriptor(service)
Expand Down
35 changes: 34 additions & 1 deletion src/grpc_requests/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from pathlib import Path
from google.protobuf.descriptor import MethodDescriptor
from google.protobuf.descriptor import Descriptor, MethodDescriptor

import warnings

# String descriptions of protobuf field types
FIELD_TYPES = [
Expand Down Expand Up @@ -35,7 +37,38 @@ def describe_request(method_descriptor: MethodDescriptor) -> dict:
:param method_descriptor: MethodDescriptor
:return: dict - a mapping of field names to their types
"""
warnings.warn("This function is deprecated, and will be removed in a future release. Use describe_descriptor() instead.", DeprecationWarning)
description = {}
for field in method_descriptor.input_type.fields:
description[field.name] = FIELD_TYPES[field.type-1]
return description

def describe_descriptor(descriptor: Descriptor) -> str:
"""
Prints a human readable description of a protobuf descriptor.
:param descriptor: Descriptor - a protobuf descriptor
:return: str - a human readable description of the descriptor
"""
description = descriptor.full_name

if descriptor.enum_types:
description += "\nEnums:"
for enum in descriptor.enum_types:
description += f"\n{enum.name}: {enum.values}"

if descriptor.fields:
description += "\nFields:"
for field in descriptor.fields:
description += f"\n{field.name}: {FIELD_TYPES[field.type-1]}"

if descriptor.nested_types:
description += "\nNested Types:"
for nested_type in descriptor.nested_types:
description += f"\n{nested_type.name}"

if descriptor.oneofs:
description += "\nOneofs:"
for oneof in descriptor.oneofs:
description += f"\n{oneof.name}"

return description
10 changes: 10 additions & 0 deletions src/tests/reflection_client_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@ def test_describe_method_request(client_tester_reflection_client):
request_description == expected_request_description
), f"Expected: {expected_request_description}, Actual: {request_description}"

def test_describe_request(client_tester_reflection_client):
request_description = \
client_tester_reflection_client.describe_request('client_tester.ClientTester', 'TestUnaryUnary')
assert request_description == 'client_tester.ClientTester.TestUnaryUnaryRequest'

def test_describe_response(client_tester_reflection_client):
request_description = \
client_tester_reflection_client.describe_response('client_tester.ClientTester', 'TestUnaryUnary')
assert request_description == 'client_tester.ClientTester.TestUnaryUnaryResponse'

def test_empty_body_request(helloworld_reflection_client):
response = helloworld_reflection_client.request('helloworld.Greeter', 'SayHello', {})
assert isinstance(response, dict)
Expand Down

0 comments on commit 662936f

Please sign in to comment.