Skip to content

ashupednekar/quickgrpc

Repository files navigation

QuickGrpc-py

Python Package Release

This is a simple framework to help your kickstart your grpc service development in python, and to publish the same for someone to invoke...

Let's go

Here's the proto file

syntax = "proto3";

service Greet{
    rpc hi(Inp) returns (Out);
    rpc bye(Inp) returns (Out);
}

message Inp{
  string name = 1;
}

message Out{
  string text = 1;
}

Here's what a day to day workflow should look like.

~/Desktop via py v3.11.6 (base)
> tree
.
└── rpc
    └── greet.proto

2 directories, 1 file

~/Desktop via py v3.11.6 (base)
> cd rpc/

~/Desktop/rpc via py v3.11.6 (base)
> create_grpc_service -f greet.proto -c yes
path: greet.proto
pb_path: /home/ashu/venvs/base/lib/python3.11/site-packages/grpc_assets/greet
Generating Server Code...
Parsing protobuf...
Parsed protobuf: [
  {
    "name": "Greet",
    "methods": [
      "hi",
      "bye"
    ]
  }
]
Adding service: Greet
Adding method: hi
Adding method: bye
Generating Client Code...
Parsing protobuf...
Parsed protobuf: [
  {
    "name": "Greet",
    "methods": [
      "hi",
      "bye"
    ]
  }
]
Adding service: Greet
Adding method: hi
Adding method: bye

This generates, two things... one service class and a test case, like so...

~/Desktop via py v3.11.6 (base)
> tree rpc/
rpc/
├── greet.proto
├── greet.py
└── tests
    └── test_greet.py

2 directories, 3 files

service

from grpc_assets.greet import greet_pb2
from grpc_assets.greet.greet_pb2_grpc import GreetServicer

"""
Proto
syntax = "proto3";

service Greet{
    rpc hi(Inp) returns (Out);
    rpc bye(Inp) returns (Out);
}

message Inp{
  string name = 1;
}

message Out{
  string text = 1;
}

"""


class GreetService(GreetServicer):
    def hi(self, context):
        """
        # TODO: add inputs as per proto
        # TODO: add logic and return output as per proto
        """
        return

    def bye(self, context):
        """
        # TODO: add inputs as per proto
        # TODO: add logic and return output as per proto
        """
        return

testcase

from grpc_assets.stub import get_stub
import grpc_assets.greet.greet_pb2 as pb2
from unittest import TestCase


"""
Proto
syntax = "proto3";

service Greet{
    rpc hi(Inp) returns (Out);
    rpc bye(Inp) returns (Out);
}

message Inp{
  string name = 1;
}

message Out{
  string text = 1;
}

"""


class GreetClientTestCase(TestCase):
    stub = get_stub("greet")

    def test_hi(self):
        # stub.<your rpc method>(pb2.<your proto message>(params))
        ...

    def test_bye(self):
        # stub.<your rpc method>(pb2.<your proto message>(params))
        ...

Then all I have to do is implement the methods...

Service

class GreetService(GreetServicer):
    def hi(self, inp, context):
        print(f"req: {inp}")
        return greet_pb2.Out(text=f"Hi {inp.name}")

    def bye(self, inp, context):
        print(f"req: {inp}")
        return greet_pb2.Out(text=f"Bye {inp.name}")

Testcase

class GreetClientTestCase(TestCase):
    stub = get_stub("greet")

    def test_hi(self):
        print(self.stub.hi(pb2.Inp(name="Ashu")))

    def test_bye(self):
        print(self.stub.bye(pb2.Inp(name="Ashu")))

That's it, then I should be able to call the service like so...

server

~/Desktop via py v3.11.6 (base)
x export GRPC_PORT=50001

~/Desktop via py v3.11.6 (base)
> servegrpc
/home/ashu/venvs/base/bin/servegrpc:21: PydanticDeprecatedSince20: `pydantic.config.Extra` is deprecated, use literal values instead (e.g. `extra='allow'`). Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.3/migration/
  extra = Extra.ignore
starting grpc server...
req: name: "Ashu"

req: name: "Ashu"

client

> python3 -m unittest rpc.tests.test_greet
text: "Bye Ashu"

.text: "Hi Ashu"

.
----------------------------------------------------------------------
Ran 2 tests in 0.006s

OK

Note, here, I'm storing the protoc generated pb2 files under a package called grpc_assets under site-packages. Also, there's one catch, the code gen logic I wrote has one retriction, proto file name needs to match the main service name, which limits the number of services to 1.

This can always be improved upon.

About

No description or website provided.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages