Using gRPC from Ignition Jython Script

Hi folks. I'm pretty new to ignition, so I'm trying to figure out the right questions to ask.

We have a service downstream that exposes gRPC endpoints. I need to make calls to this service from a jython script in ignition. What's the best way to import the protos and generated files?

Can I use the python generated files directly? Where would I put them?

If I have to use the Java ones, how do I import them? Can I put a JAR somewhere? Do I need to create a scripting module with the sdk and then import that into my script? And if that's the case, do I need to explicitly create a stub under -common and then call the implementation from -gateway or can I somehow import it directly?

Or is there some other 3rd method that I'm not even thinking of.

This is probably what I'd do...

Gotcha. What will that look like? I'm using the SDK Scripting Example as a reference.

protoc generates a lot of boilerplate methods. Do I need to individually import each one as a ScriptFunction? Can I import them all as a group?

Or I guess I'd have to do the majority of implementation in the java module directly and then only export the top level functions to the script

That's what I had in mind. I imagine there's a relatively small number of different RPC calls you need to make? Each of those could be your own system.myrpc.foo() or system.myrpc.bar() call, and you hide that gRPC and protobufs are involved completely.

If you have a really large API and you need to expose all of it then you may need to come up with a better approach.

If you just want to expose classes generated by protoc, then you can just mount them as public static final fields in whatever your provide as a script module. There's no autocomplete support (until 8.3) but if you have

public MyScriptModule() {
    public static final Class<?> SOME_PROTO_CLASS = path.to.some.proto.Class;
}

Then in scripting, you can reference it as system.yourScriptModule.SOME_PROTO_CLASS, and Jython will automatically turn Java bean style getters and setters into properties with accessors; that is, code like this will "just work":

someClass = system.yourScriptModule.SOME_PROTO_CLASS()
someClass.someProtoValue = 123
otherValue = someClass.someOtherProtoValue

If you're talking about exposing actual gRPC methods, there's no special shortcut. You're going to have to do some amount of legwork yourself. Less if you only expose your function on the gateway scope (so no need to deal with serialization/RPC), more if you want your function(s) callable from the script console/Vision client scope.

Yeah I think this is the way.

There are a half dozen or so RPCs. I was hoping to do the message building and some of the processing in python, but I can do that in the java module instead and expose just the top level functions. Honestly that's better encapsulation anyway.