Send plain JSON to a gRPC server using python

Viewed 2787

I'm able to send requests to one of our gRPC-enabled, reflection-enabled server using grpcurl with the following syntax:

grpcurl --plaintext -d '{"test_input": "Test 1 2 3", "config": { "max_results": 3 }}' localhost:6565 myorg.myproject.v1alpha6.MyService.MyStub

This does not require knowledge of the protos from grpcurl. And it's just perfect because I'm using it in a test script that I want to keep as simple as possible.

I've been able to leverage that to write a very simple python script:

import json
import subprocess

input = { "test_input": "Test 1 2 3", "config": { "max_results": 3 } }
result = subprocess.check_output(['grpcurl', '--plaintext', '-d', json.dumps(input), 'localhost:6565', 'MyStub'])
dict_result = json.loads(result)

But I'm not too happy about having to call an external process.

All the documentations I found on the internet require downloading the protos and their dependencies and compile them using protoc. I can do that and this is not the object of the question. The goal here it to use Python to exchange with the server using JSON and without downloading the proto. Just like it's done with grpcurl.

Can this be done using python only ?

2 Answers

I think not because (the excellent) gRPCurl does not appear to provide an API|SDK that you'd want to be able to script it from Python.

As you note, this only works (without a proto or protoset) on gRPC servers that support reflection.

I think your approach of controlling gRPCurl through a shell is probably the best way. It may be worth a feature request to see whether others would like to drive gRPCurl as a test harness; it could be interesting.

Alternatively, if you're not wedded to gRPCurl, there may be other tools that support reflection that can be scrpted by Python. See:

https://github.com/grpc-ecosystem/awesome-grpc#tools-test

gRPC uses HTTP2 in the transport layer. Just like any other RPC framework, it runs an http server which can be queried with basic http post requests. You can basically uses requests package to trigger a POST request to the gRPC server

import requests, json

payload = { "test_input": "Test 1 2 3", "config": { "max_results": 3 } }
response = requests.post("http://localhost:6565", data=json.dumps(payload))
Related