diff --git a/.github/workflows/wheels.yaml b/.github/workflows/wheels.yaml index f7a30b8a8..c3804923d 100644 --- a/.github/workflows/wheels.yaml +++ b/.github/workflows/wheels.yaml @@ -17,7 +17,10 @@ name: Build Wheels on: push: branches: + - production - scikit_build_core + pull_request: + branches: [ "main", "production", "incubating" ] env: VCPKG_ROOT: ${{ github.workspace }}/vendor/vcpkg diff --git a/modules/pymol/invocation.py b/modules/pymol/invocation.py index 2dc6bcf38..5bced2c79 100644 --- a/modules/pymol/invocation.py +++ b/modules/pymol/invocation.py @@ -519,7 +519,17 @@ def parse_args(argv, _pymol=None, options=None, restricted=0): for a in pymolrc] + options.deferred options.pymolrc = pymolrc if options.rpcServer: - options.deferred.append('_do__ /import pymol.rpc;pymol.rpc.launch_XMLRPC()') + # Replaced old XML-RPC implementation with modern gRPC implementation. + # However, to enforce this change, it uses the same command line argument. + # This enforcement comes from clear security concerns, like vulnerabilities in the + # Apache XML RPC Client Library (https://mvnrepository.com/artifact/org.apache.xmlrpc/xmlrpc-client/3.1.3) + # that has its last official release in 2010. + # It contains two Vulnerabilities from dependencies: + # CVE-2016-5004: https://www.cve.org/CVERecord?id=CVE-2016-5004 + # CVE-2012-5783: https://www.cve.org/CVERecord?id=CVE-2012-5783 + # + # options.deferred.append('_do__ /import pymol.rpc;pymol.rpc.launch_XMLRPC()') + options.deferred.append('_do__ /import pymol.pml_grpc;pymol.pml_grpc.launch_gRPC()') if options.plugins == 1: # Load plugins independent of PMGApp (will not add menu items) options.deferred.append('_do__ /import pymol.plugins;pymol.plugins.initialize(-1)') diff --git a/modules/pymol/pml_grpc.py b/modules/pymol/pml_grpc.py new file mode 100644 index 000000000..712313419 --- /dev/null +++ b/modules/pymol/pml_grpc.py @@ -0,0 +1,294 @@ +""" +A gRPC server to allow remote control of PyMol. + +Replaces the legacy XML-RPC implementation with a modern, +high-performance gRPC service. + +Author: Greg Landrum (original XML-RPC), Martin Urban (updated for gRPC) +Date: September 2025 +License: PyMOL +Requires: + - grpcio, grpcio-tools, protobuf + - Python with threading enabled +""" + +import os +import tempfile +from concurrent import futures + +import grpc +from pymol import cmd, cgo + +import pymol_rpc_pb2 +import pymol_rpc_pb2_grpc + +# --- Global state --- +cgoDict = {} # stores CGO objects by id +_server = None + + +# --- Helper functions --- + +def _color_obj(obj_name, color_scheme: str): + """Applies a color scheme to a molecular object.""" + if not color_scheme: + return + try: + if color_scheme == 'std': + cmd.color("magenta", f"({obj_name})", quiet=1) + cmd.color("oxygen", f"(elem O and {obj_name})", quiet=1) + cmd.color("nitrogen", f"(elem N and {obj_name})", quiet=1) + cmd.color("sulfur", f"(elem S and {obj_name})", quiet=1) + cmd.color("hydrogen", f"(elem H and {obj_name})", quiet=1) + cmd.color("gray", f"(elem C and {obj_name})", quiet=1) + else: + cmd.color(color_scheme, obj_name, quiet=1) + except Exception as e: + print(f"Error applying color scheme '{color_scheme}': {e}") + + +def _make_alpha_section(transparent: bool, transparency: float): + return [] if not transparent else [cgo.ALPHA, 1.0 - transparency] + + +# --- gRPC Servicer Implementation --- + +class PyMolRPCServicer(pymol_rpc_pb2_grpc.PyMolRPCServicer): + """Implements the PyMolRPC gRPC service.""" + + def Ping(self, request, context): + return pymol_rpc_pb2.StatusResponse(success=True, message="Pong") + + def Do(self, request, context): + try: + result = cmd.do(request.command) + return pymol_rpc_pb2.CommandResponse(result=str(result) if result else "") + except Exception as e: + return pymol_rpc_pb2.CommandResponse(result=f"Error: {e}") + + def Label(self, request, context): + try: + pos = (request.pos.x, request.pos.y, request.pos.z) + color = (request.color.r, request.color.g, request.color.b) + obj_id = request.id or 'lab1' + color_id = f"{obj_id}-color" + + cmd.pseudoatom(obj_id, label=repr(request.text), elem='C', pos=pos) + cmd.set_color(color_id, color) + cmd.color(color_id, obj_id) + return pymol_rpc_pb2.StatusResponse(success=True) + except Exception as e: + return pymol_rpc_pb2.StatusResponse(success=False, message=str(e)) + + def Sphere(self, request, context): + try: + pos = (request.pos.x, request.pos.y, request.pos.z) + color = (request.color.r, request.color.g, request.color.b) + obj_id = request.id or 'cgo' + + obj = cgoDict.get(obj_id, []).copy() if request.extend else [] + obj.extend(_make_alpha_section(request.transparent, request.transparency)) + obj.extend([cgo.COLOR, *color, cgo.SPHERE, *pos, request.radius]) + + cgoDict[obj_id] = obj + cmd.load_cgo(obj, obj_id, 1) + return pymol_rpc_pb2.StatusResponse(success=True) + except Exception as e: + return pymol_rpc_pb2.StatusResponse(success=False, message=str(e)) + + def Cylinder(self, request, context): + try: + p1 = (request.end1.x, request.end1.y, request.end1.z) + p2 = (request.end2.x, request.end2.y, request.end2.z) + c1 = (request.color1.r, request.color1.g, request.color1.b) + + if request.HasField("color2"): + c2 = (request.color2.r, request.color2.g, request.color2.b) + else: + c2 = c1 + + obj_id = request.id or 'cgo' + obj = cgoDict.get(obj_id, []).copy() if request.extend else [] + obj.extend(_make_alpha_section(request.transparent, request.transparency)) + obj.extend([cgo.CYLINDER, *p1, *p2, request.radius, *c1, *c2]) + + cgoDict[obj_id] = obj + cmd.load_cgo(obj, obj_id, 1) + return pymol_rpc_pb2.StatusResponse(success=True) + except Exception as e: + return pymol_rpc_pb2.StatusResponse(success=False, message=str(e)) + + def LoadPDB(self, request, context): + if request.replace: + cmd.delete(request.obj_name) + result = cmd.read_pdbstr(request.data, request.obj_name) + if request.HasField("color_scheme"): + _color_obj(request.obj_name, request.color_scheme) + return pymol_rpc_pb2.CommandResponse(result=str(result) if result else "") + + def LoadMolBlock(self, request, context): + if request.replace: + cmd.delete(request.obj_name) + result = cmd.read_molstr(request.data, request.obj_name) + if request.HasField("color_scheme"): + _color_obj(request.obj_name, request.color_scheme) + return pymol_rpc_pb2.CommandResponse(result=str(result) if result else "") + + def LoadFile(self, request, context): + obj_name = request.obj_name or os.path.splitext(os.path.basename(request.file_name))[0] + if request.replace: + cmd.delete(obj_name) + fmt = request.format if request.HasField("format") else '' + result = cmd.load(request.file_name, obj_name, format=fmt) + if request.HasField("color_scheme"): + _color_obj(obj_name, request.color_scheme) + return pymol_rpc_pb2.CommandResponse(result=str(result) if result else "") + + def LoadSurface(self, request, context): + grid_name = f"grid-{request.obj_name}" + file_to_load = None + + try: + if request.WhichOneof("source") == "data": + with tempfile.NamedTemporaryFile(delete=False, mode='w', suffix='.grd') as tmp: + tmp.write(request.data) + file_to_load = tmp.name + elif request.WhichOneof("source") == "file_name": + file_to_load = request.file_name + else: + return pymol_rpc_pb2.CommandResponse(result="Error: no source specified") + + fmt = request.format if request.HasField("format") else '' + result = cmd.load(file_to_load, grid_name, format=fmt) + cmd.isosurface(request.obj_name, grid_name, level=request.surface_level) + return pymol_rpc_pb2.CommandResponse(result=str(result) if result else "") + finally: + if file_to_load and file_to_load.endswith(".grd") and os.path.exists(file_to_load): + os.unlink(file_to_load) + + def GetNames(self, request, context): + names = cmd.get_names(request.what, enabled_only=request.enabled_only) + return pymol_rpc_pb2.GetNamesResponse(names=names) + + def GetAtomCoords(self, request, context): + coords = cmd.get_atom_coords(request.selection, state=request.state) + if coords is None: + return pymol_rpc_pb2.GetAtomCoordsResponse(coordinates=[]) + response_coords = [pymol_rpc_pb2.Vector3(x=c[0], y=c[1], z=c[2]) for c in coords] + return pymol_rpc_pb2.GetAtomCoordsResponse(coordinates=response_coords) + + def DeleteObject(self, request, context): + try: + cmd.delete(request.name) + return pymol_rpc_pb2.StatusResponse(success=True) + except Exception as e: + return pymol_rpc_pb2.StatusResponse(success=False, message=str(e)) + + def DeleteAll(self, request, context): + try: + cmd.delete("all") + return pymol_rpc_pb2.StatusResponse(success=True) + except Exception as e: + return pymol_rpc_pb2.StatusResponse(success=False, message=str(e)) + + def Center(self, request, context): + try: + cmd.center(request.selection, animate=int(request.animate)) + return pymol_rpc_pb2.StatusResponse(success=True) + except Exception as e: + return pymol_rpc_pb2.StatusResponse(success=False, message=str(e)) + + def Zoom(self, request, context): + try: + cmd.zoom(request.selection, buffer=request.buffer, + state=request.state, animate=int(request.animate)) + return pymol_rpc_pb2.StatusResponse(success=True) + except Exception as e: + return pymol_rpc_pb2.StatusResponse(success=False, message=str(e)) + + def Rotate(self, request, context): + try: + cmd.rotate(request.axis, request.angle, request.selection) + return pymol_rpc_pb2.StatusResponse(success=True) + except Exception as e: + return pymol_rpc_pb2.StatusResponse(success=False, message=str(e)) + + def Move(self, request, context): + try: + cmd.move(request.axis, request.distance, request.selection) + return pymol_rpc_pb2.StatusResponse(success=True) + except Exception as e: + return pymol_rpc_pb2.StatusResponse(success=False, message=str(e)) + + def Hide(self, request, context): + try: + cmd.hide(request.representation, request.selection) + return pymol_rpc_pb2.StatusResponse(success=True) + except Exception as e: + return pymol_rpc_pb2.StatusResponse(success=False, message=str(e)) + + def Show(self, request, context): + try: + cmd.show(request.representation, request.selection) + return pymol_rpc_pb2.StatusResponse(success=True) + except Exception as e: + return pymol_rpc_pb2.StatusResponse(success=False, message=str(e)) + + def Color(self, request, context): + try: + cmd.color(request.color, request.selection) + return pymol_rpc_pb2.StatusResponse(success=True) + except Exception as e: + return pymol_rpc_pb2.StatusResponse(success=False, message=str(e)) + + def SetTransparency(self, request, context): + try: + cmd.set("transparency", request.transparency, request.selection) + return pymol_rpc_pb2.StatusResponse(success=True) + except Exception as e: + return pymol_rpc_pb2.StatusResponse(success=False, message=str(e)) + + def Select(self, request, context): + try: + cmd.select("sele", request.selection) + return pymol_rpc_pb2.StatusResponse(success=True) + except Exception as e: + return pymol_rpc_pb2.StatusResponse(success=False, message=str(e)) + + def DeleteSelection(self, request, context): + try: + cmd.delete(request.selection) + return pymol_rpc_pb2.StatusResponse(success=True) + except Exception as e: + return pymol_rpc_pb2.StatusResponse(success=False, message=str(e)) + +# --- Server Launching Logic --- + +def launch_gRPC(hostname='', port=50051, n_to_try=5): + """Launches the gRPC server in a background thread.""" + global _server + if _server is not None: + print("gRPC server already running.") + return + + if not hostname: + hostname = os.environ.get('PYMOL_RPCHOST', 'localhost') + + server_port = None + for i in range(n_to_try): + current_port = port + i + server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) + pymol_rpc_pb2_grpc.add_PyMolRPCServicer_to_server(PyMolRPCServicer(), server) + bound = server.add_insecure_port(f"{hostname}:{current_port}") + if bound == 0: + print(f"Port {current_port} unavailable; trying next") + continue + server.start() + _server = server + server_port = current_port + break + + if _server: + print(f"gRPC server running on host {hostname}, port {server_port}") + else: + print("gRPC server could not be started") diff --git a/modules/pymol/pymol_rpc_pb2.py b/modules/pymol/pymol_rpc_pb2.py new file mode 100644 index 000000000..c07fdd739 --- /dev/null +++ b/modules/pymol/pymol_rpc_pb2.py @@ -0,0 +1,86 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: pymol_rpc.proto +# Protobuf Python Version: 6.31.1 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 31, + 1, + '', + 'pymol_rpc.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0fpymol_rpc.proto\"\x07\n\x05\x45mpty\"2\n\x0eStatusResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\x12\x0f\n\x07message\x18\x02 \x01(\t\"*\n\x07Vector3\x12\t\n\x01x\x18\x01 \x01(\x02\x12\t\n\x01y\x18\x02 \x01(\x02\x12\t\n\x01z\x18\x03 \x01(\x02\"+\n\x08\x43olorRGB\x12\t\n\x01r\x18\x01 \x01(\x02\x12\t\n\x01g\x18\x02 \x01(\x02\x12\t\n\x01\x62\x18\x03 \x01(\x02\"!\n\x0e\x43ommandRequest\x12\x0f\n\x07\x63ommand\x18\x01 \x01(\t\"!\n\x0f\x43ommandResponse\x12\x0e\n\x06result\x18\x01 \x01(\t\"Y\n\x0cLabelRequest\x12\x15\n\x03pos\x18\x01 \x01(\x0b\x32\x08.Vector3\x12\x0c\n\x04text\x18\x02 \x01(\t\x12\n\n\x02id\x18\x03 \x01(\t\x12\x18\n\x05\x63olor\x18\x04 \x01(\x0b\x32\t.ColorRGB\"\x97\x01\n\rSphereRequest\x12\x15\n\x03pos\x18\x01 \x01(\x0b\x32\x08.Vector3\x12\x0e\n\x06radius\x18\x02 \x01(\x02\x12\x18\n\x05\x63olor\x18\x03 \x01(\x0b\x32\t.ColorRGB\x12\n\n\x02id\x18\x04 \x01(\t\x12\x0e\n\x06\x65xtend\x18\x05 \x01(\x08\x12\x13\n\x0btransparent\x18\x06 \x01(\x08\x12\x14\n\x0ctransparency\x18\x07 \x01(\x02\"\xde\x01\n\x0f\x43ylinderRequest\x12\x16\n\x04\x65nd1\x18\x01 \x01(\x0b\x32\x08.Vector3\x12\x16\n\x04\x65nd2\x18\x02 \x01(\x0b\x32\x08.Vector3\x12\x0e\n\x06radius\x18\x03 \x01(\x02\x12\x19\n\x06\x63olor1\x18\x04 \x01(\x0b\x32\t.ColorRGB\x12\x1e\n\x06\x63olor2\x18\x05 \x01(\x0b\x32\t.ColorRGBH\x00\x88\x01\x01\x12\n\n\x02id\x18\x06 \x01(\t\x12\x0e\n\x06\x65xtend\x18\x07 \x01(\x08\x12\x13\n\x0btransparent\x18\x08 \x01(\x08\x12\x14\n\x0ctransparency\x18\t \x01(\x02\x42\t\n\x07_color2\"m\n\x0eLoadMolRequest\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\t\x12\x10\n\x08obj_name\x18\x02 \x01(\t\x12\x19\n\x0c\x63olor_scheme\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\x0f\n\x07replace\x18\x04 \x01(\x08\x42\x0f\n\r_color_scheme\"\x93\x01\n\x0fLoadFileRequest\x12\x11\n\tfile_name\x18\x01 \x01(\t\x12\x10\n\x08obj_name\x18\x02 \x01(\t\x12\x13\n\x06\x66ormat\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\x19\n\x0c\x63olor_scheme\x18\x04 \x01(\tH\x01\x88\x01\x01\x12\x0f\n\x07replace\x18\x05 \x01(\x08\x42\t\n\x07_formatB\x0f\n\r_color_scheme\"\x8c\x01\n\x12LoadSurfaceRequest\x12\x0e\n\x04\x64\x61ta\x18\x01 \x01(\tH\x00\x12\x13\n\tfile_name\x18\x02 \x01(\tH\x00\x12\x10\n\x08obj_name\x18\x03 \x01(\t\x12\x13\n\x06\x66ormat\x18\x04 \x01(\tH\x01\x88\x01\x01\x12\x15\n\rsurface_level\x18\x05 \x01(\x02\x42\x08\n\x06sourceB\t\n\x07_format\"5\n\x0fGetNamesRequest\x12\x0c\n\x04what\x18\x01 \x01(\t\x12\x14\n\x0c\x65nabled_only\x18\x02 \x01(\x08\"!\n\x10GetNamesResponse\x12\r\n\x05names\x18\x01 \x03(\t\"8\n\x14GetAtomCoordsRequest\x12\x11\n\tselection\x18\x01 \x01(\t\x12\r\n\x05state\x18\x02 \x01(\x05\"6\n\x15GetAtomCoordsResponse\x12\x1d\n\x0b\x63oordinates\x18\x01 \x03(\x0b\x32\x08.Vector3\"\x1d\n\rObjectRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"%\n\x10SelectionRequest\x12\x11\n\tselection\x18\x01 \x01(\t\"3\n\rCenterRequest\x12\x11\n\tselection\x18\x01 \x01(\t\x12\x0f\n\x07\x61nimate\x18\x02 \x01(\x08\"P\n\x0bZoomRequest\x12\x11\n\tselection\x18\x01 \x01(\t\x12\x0e\n\x06\x62uffer\x18\x02 \x01(\x02\x12\r\n\x05state\x18\x03 \x01(\x05\x12\x0f\n\x07\x61nimate\x18\x04 \x01(\x08\"?\n\rRotateRequest\x12\x0c\n\x04\x61xis\x18\x01 \x01(\t\x12\r\n\x05\x61ngle\x18\x02 \x01(\x02\x12\x11\n\tselection\x18\x03 \x01(\t\"@\n\x0bMoveRequest\x12\x0c\n\x04\x61xis\x18\x01 \x01(\t\x12\x10\n\x08\x64istance\x18\x02 \x01(\x02\x12\x11\n\tselection\x18\x03 \x01(\t\"<\n\x0fShowHideRequest\x12\x16\n\x0erepresentation\x18\x01 \x01(\t\x12\x11\n\tselection\x18\x02 \x01(\t\"0\n\x0c\x43olorRequest\x12\r\n\x05\x63olor\x18\x01 \x01(\t\x12\x11\n\tselection\x18\x02 \x01(\t\">\n\x13TransparencyRequest\x12\x14\n\x0ctransparency\x18\x01 \x01(\x02\x12\x11\n\tselection\x18\x02 \x01(\t2\xa8\x08\n\x08PyMolRPC\x12\x1f\n\x04Ping\x12\x06.Empty\x1a\x0f.StatusResponse\x12\'\n\x02\x44o\x12\x0f.CommandRequest\x1a\x10.CommandResponse\x12\'\n\x05Label\x12\r.LabelRequest\x1a\x0f.StatusResponse\x12)\n\x06Sphere\x12\x0e.SphereRequest\x1a\x0f.StatusResponse\x12-\n\x08\x43ylinder\x12\x10.CylinderRequest\x1a\x0f.StatusResponse\x12,\n\x07LoadPDB\x12\x0f.LoadMolRequest\x1a\x10.CommandResponse\x12\x31\n\x0cLoadMolBlock\x12\x0f.LoadMolRequest\x1a\x10.CommandResponse\x12.\n\x08LoadFile\x12\x10.LoadFileRequest\x1a\x10.CommandResponse\x12\x34\n\x0bLoadSurface\x12\x13.LoadSurfaceRequest\x1a\x10.CommandResponse\x12/\n\x08GetNames\x12\x10.GetNamesRequest\x1a\x11.GetNamesResponse\x12>\n\rGetAtomCoords\x12\x15.GetAtomCoordsRequest\x1a\x16.GetAtomCoordsResponse\x12/\n\x0c\x44\x65leteObject\x12\x0e.ObjectRequest\x1a\x0f.StatusResponse\x12$\n\tDeleteAll\x12\x06.Empty\x1a\x0f.StatusResponse\x12)\n\x06\x43\x65nter\x12\x0e.CenterRequest\x1a\x0f.StatusResponse\x12%\n\x04Zoom\x12\x0c.ZoomRequest\x1a\x0f.StatusResponse\x12)\n\x06Rotate\x12\x0e.RotateRequest\x1a\x0f.StatusResponse\x12%\n\x04Move\x12\x0c.MoveRequest\x1a\x0f.StatusResponse\x12)\n\x04Hide\x12\x10.ShowHideRequest\x1a\x0f.StatusResponse\x12)\n\x04Show\x12\x10.ShowHideRequest\x1a\x0f.StatusResponse\x12\'\n\x05\x43olor\x12\r.ColorRequest\x1a\x0f.StatusResponse\x12\x38\n\x0fSetTransparency\x12\x14.TransparencyRequest\x1a\x0f.StatusResponse\x12,\n\x06Select\x12\x11.SelectionRequest\x1a\x0f.StatusResponse\x12\x35\n\x0f\x44\x65leteSelection\x12\x11.SelectionRequest\x1a\x0f.StatusResponseb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'pymol_rpc_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + DESCRIPTOR._loaded_options = None + _globals['_EMPTY']._serialized_start=19 + _globals['_EMPTY']._serialized_end=26 + _globals['_STATUSRESPONSE']._serialized_start=28 + _globals['_STATUSRESPONSE']._serialized_end=78 + _globals['_VECTOR3']._serialized_start=80 + _globals['_VECTOR3']._serialized_end=122 + _globals['_COLORRGB']._serialized_start=124 + _globals['_COLORRGB']._serialized_end=167 + _globals['_COMMANDREQUEST']._serialized_start=169 + _globals['_COMMANDREQUEST']._serialized_end=202 + _globals['_COMMANDRESPONSE']._serialized_start=204 + _globals['_COMMANDRESPONSE']._serialized_end=237 + _globals['_LABELREQUEST']._serialized_start=239 + _globals['_LABELREQUEST']._serialized_end=328 + _globals['_SPHEREREQUEST']._serialized_start=331 + _globals['_SPHEREREQUEST']._serialized_end=482 + _globals['_CYLINDERREQUEST']._serialized_start=485 + _globals['_CYLINDERREQUEST']._serialized_end=707 + _globals['_LOADMOLREQUEST']._serialized_start=709 + _globals['_LOADMOLREQUEST']._serialized_end=818 + _globals['_LOADFILEREQUEST']._serialized_start=821 + _globals['_LOADFILEREQUEST']._serialized_end=968 + _globals['_LOADSURFACEREQUEST']._serialized_start=971 + _globals['_LOADSURFACEREQUEST']._serialized_end=1111 + _globals['_GETNAMESREQUEST']._serialized_start=1113 + _globals['_GETNAMESREQUEST']._serialized_end=1166 + _globals['_GETNAMESRESPONSE']._serialized_start=1168 + _globals['_GETNAMESRESPONSE']._serialized_end=1201 + _globals['_GETATOMCOORDSREQUEST']._serialized_start=1203 + _globals['_GETATOMCOORDSREQUEST']._serialized_end=1259 + _globals['_GETATOMCOORDSRESPONSE']._serialized_start=1261 + _globals['_GETATOMCOORDSRESPONSE']._serialized_end=1315 + _globals['_OBJECTREQUEST']._serialized_start=1317 + _globals['_OBJECTREQUEST']._serialized_end=1346 + _globals['_SELECTIONREQUEST']._serialized_start=1348 + _globals['_SELECTIONREQUEST']._serialized_end=1385 + _globals['_CENTERREQUEST']._serialized_start=1387 + _globals['_CENTERREQUEST']._serialized_end=1438 + _globals['_ZOOMREQUEST']._serialized_start=1440 + _globals['_ZOOMREQUEST']._serialized_end=1520 + _globals['_ROTATEREQUEST']._serialized_start=1522 + _globals['_ROTATEREQUEST']._serialized_end=1585 + _globals['_MOVEREQUEST']._serialized_start=1587 + _globals['_MOVEREQUEST']._serialized_end=1651 + _globals['_SHOWHIDEREQUEST']._serialized_start=1653 + _globals['_SHOWHIDEREQUEST']._serialized_end=1713 + _globals['_COLORREQUEST']._serialized_start=1715 + _globals['_COLORREQUEST']._serialized_end=1763 + _globals['_TRANSPARENCYREQUEST']._serialized_start=1765 + _globals['_TRANSPARENCYREQUEST']._serialized_end=1827 + _globals['_PYMOLRPC']._serialized_start=1830 + _globals['_PYMOLRPC']._serialized_end=2894 +# @@protoc_insertion_point(module_scope) diff --git a/modules/pymol/pymol_rpc_pb2_grpc.py b/modules/pymol/pymol_rpc_pb2_grpc.py new file mode 100644 index 000000000..ce2ca7054 --- /dev/null +++ b/modules/pymol/pymol_rpc_pb2_grpc.py @@ -0,0 +1,1044 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc +import warnings + +import pymol_rpc_pb2 as pymol__rpc__pb2 + +GRPC_GENERATED_VERSION = '1.74.0' +GRPC_VERSION = grpc.__version__ +_version_not_supported = False + +try: + from grpc._utilities import first_version_is_lower + _version_not_supported = first_version_is_lower(GRPC_VERSION, GRPC_GENERATED_VERSION) +except ImportError: + _version_not_supported = True + +if _version_not_supported: + raise RuntimeError( + f'The grpc package installed is at version {GRPC_VERSION},' + + f' but the generated code in pymol_rpc_pb2_grpc.py depends on' + + f' grpcio>={GRPC_GENERATED_VERSION}.' + + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' + ) + + +class PyMolRPCStub(object): + """Missing associated documentation comment in .proto file.""" + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.Ping = channel.unary_unary( + '/PyMolRPC/Ping', + request_serializer=pymol__rpc__pb2.Empty.SerializeToString, + response_deserializer=pymol__rpc__pb2.StatusResponse.FromString, + _registered_method=True) + self.Do = channel.unary_unary( + '/PyMolRPC/Do', + request_serializer=pymol__rpc__pb2.CommandRequest.SerializeToString, + response_deserializer=pymol__rpc__pb2.CommandResponse.FromString, + _registered_method=True) + self.Label = channel.unary_unary( + '/PyMolRPC/Label', + request_serializer=pymol__rpc__pb2.LabelRequest.SerializeToString, + response_deserializer=pymol__rpc__pb2.StatusResponse.FromString, + _registered_method=True) + self.Sphere = channel.unary_unary( + '/PyMolRPC/Sphere', + request_serializer=pymol__rpc__pb2.SphereRequest.SerializeToString, + response_deserializer=pymol__rpc__pb2.StatusResponse.FromString, + _registered_method=True) + self.Cylinder = channel.unary_unary( + '/PyMolRPC/Cylinder', + request_serializer=pymol__rpc__pb2.CylinderRequest.SerializeToString, + response_deserializer=pymol__rpc__pb2.StatusResponse.FromString, + _registered_method=True) + self.LoadPDB = channel.unary_unary( + '/PyMolRPC/LoadPDB', + request_serializer=pymol__rpc__pb2.LoadMolRequest.SerializeToString, + response_deserializer=pymol__rpc__pb2.CommandResponse.FromString, + _registered_method=True) + self.LoadMolBlock = channel.unary_unary( + '/PyMolRPC/LoadMolBlock', + request_serializer=pymol__rpc__pb2.LoadMolRequest.SerializeToString, + response_deserializer=pymol__rpc__pb2.CommandResponse.FromString, + _registered_method=True) + self.LoadFile = channel.unary_unary( + '/PyMolRPC/LoadFile', + request_serializer=pymol__rpc__pb2.LoadFileRequest.SerializeToString, + response_deserializer=pymol__rpc__pb2.CommandResponse.FromString, + _registered_method=True) + self.LoadSurface = channel.unary_unary( + '/PyMolRPC/LoadSurface', + request_serializer=pymol__rpc__pb2.LoadSurfaceRequest.SerializeToString, + response_deserializer=pymol__rpc__pb2.CommandResponse.FromString, + _registered_method=True) + self.GetNames = channel.unary_unary( + '/PyMolRPC/GetNames', + request_serializer=pymol__rpc__pb2.GetNamesRequest.SerializeToString, + response_deserializer=pymol__rpc__pb2.GetNamesResponse.FromString, + _registered_method=True) + self.GetAtomCoords = channel.unary_unary( + '/PyMolRPC/GetAtomCoords', + request_serializer=pymol__rpc__pb2.GetAtomCoordsRequest.SerializeToString, + response_deserializer=pymol__rpc__pb2.GetAtomCoordsResponse.FromString, + _registered_method=True) + self.DeleteObject = channel.unary_unary( + '/PyMolRPC/DeleteObject', + request_serializer=pymol__rpc__pb2.ObjectRequest.SerializeToString, + response_deserializer=pymol__rpc__pb2.StatusResponse.FromString, + _registered_method=True) + self.DeleteAll = channel.unary_unary( + '/PyMolRPC/DeleteAll', + request_serializer=pymol__rpc__pb2.Empty.SerializeToString, + response_deserializer=pymol__rpc__pb2.StatusResponse.FromString, + _registered_method=True) + self.Center = channel.unary_unary( + '/PyMolRPC/Center', + request_serializer=pymol__rpc__pb2.CenterRequest.SerializeToString, + response_deserializer=pymol__rpc__pb2.StatusResponse.FromString, + _registered_method=True) + self.Zoom = channel.unary_unary( + '/PyMolRPC/Zoom', + request_serializer=pymol__rpc__pb2.ZoomRequest.SerializeToString, + response_deserializer=pymol__rpc__pb2.StatusResponse.FromString, + _registered_method=True) + self.Rotate = channel.unary_unary( + '/PyMolRPC/Rotate', + request_serializer=pymol__rpc__pb2.RotateRequest.SerializeToString, + response_deserializer=pymol__rpc__pb2.StatusResponse.FromString, + _registered_method=True) + self.Move = channel.unary_unary( + '/PyMolRPC/Move', + request_serializer=pymol__rpc__pb2.MoveRequest.SerializeToString, + response_deserializer=pymol__rpc__pb2.StatusResponse.FromString, + _registered_method=True) + self.Hide = channel.unary_unary( + '/PyMolRPC/Hide', + request_serializer=pymol__rpc__pb2.ShowHideRequest.SerializeToString, + response_deserializer=pymol__rpc__pb2.StatusResponse.FromString, + _registered_method=True) + self.Show = channel.unary_unary( + '/PyMolRPC/Show', + request_serializer=pymol__rpc__pb2.ShowHideRequest.SerializeToString, + response_deserializer=pymol__rpc__pb2.StatusResponse.FromString, + _registered_method=True) + self.Color = channel.unary_unary( + '/PyMolRPC/Color', + request_serializer=pymol__rpc__pb2.ColorRequest.SerializeToString, + response_deserializer=pymol__rpc__pb2.StatusResponse.FromString, + _registered_method=True) + self.SetTransparency = channel.unary_unary( + '/PyMolRPC/SetTransparency', + request_serializer=pymol__rpc__pb2.TransparencyRequest.SerializeToString, + response_deserializer=pymol__rpc__pb2.StatusResponse.FromString, + _registered_method=True) + self.Select = channel.unary_unary( + '/PyMolRPC/Select', + request_serializer=pymol__rpc__pb2.SelectionRequest.SerializeToString, + response_deserializer=pymol__rpc__pb2.StatusResponse.FromString, + _registered_method=True) + self.DeleteSelection = channel.unary_unary( + '/PyMolRPC/DeleteSelection', + request_serializer=pymol__rpc__pb2.SelectionRequest.SerializeToString, + response_deserializer=pymol__rpc__pb2.StatusResponse.FromString, + _registered_method=True) + + +class PyMolRPCServicer(object): + """Missing associated documentation comment in .proto file.""" + + def Ping(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 Do(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 Label(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 Sphere(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 Cylinder(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 LoadPDB(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 LoadMolBlock(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 LoadFile(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 LoadSurface(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 GetNames(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 GetAtomCoords(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 DeleteObject(self, request, context): + """Backward compatibility methods + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def DeleteAll(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 Center(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 Zoom(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 Rotate(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 Move(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 Hide(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 Show(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 Color(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 SetTransparency(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 Select(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 DeleteSelection(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_PyMolRPCServicer_to_server(servicer, server): + rpc_method_handlers = { + 'Ping': grpc.unary_unary_rpc_method_handler( + servicer.Ping, + request_deserializer=pymol__rpc__pb2.Empty.FromString, + response_serializer=pymol__rpc__pb2.StatusResponse.SerializeToString, + ), + 'Do': grpc.unary_unary_rpc_method_handler( + servicer.Do, + request_deserializer=pymol__rpc__pb2.CommandRequest.FromString, + response_serializer=pymol__rpc__pb2.CommandResponse.SerializeToString, + ), + 'Label': grpc.unary_unary_rpc_method_handler( + servicer.Label, + request_deserializer=pymol__rpc__pb2.LabelRequest.FromString, + response_serializer=pymol__rpc__pb2.StatusResponse.SerializeToString, + ), + 'Sphere': grpc.unary_unary_rpc_method_handler( + servicer.Sphere, + request_deserializer=pymol__rpc__pb2.SphereRequest.FromString, + response_serializer=pymol__rpc__pb2.StatusResponse.SerializeToString, + ), + 'Cylinder': grpc.unary_unary_rpc_method_handler( + servicer.Cylinder, + request_deserializer=pymol__rpc__pb2.CylinderRequest.FromString, + response_serializer=pymol__rpc__pb2.StatusResponse.SerializeToString, + ), + 'LoadPDB': grpc.unary_unary_rpc_method_handler( + servicer.LoadPDB, + request_deserializer=pymol__rpc__pb2.LoadMolRequest.FromString, + response_serializer=pymol__rpc__pb2.CommandResponse.SerializeToString, + ), + 'LoadMolBlock': grpc.unary_unary_rpc_method_handler( + servicer.LoadMolBlock, + request_deserializer=pymol__rpc__pb2.LoadMolRequest.FromString, + response_serializer=pymol__rpc__pb2.CommandResponse.SerializeToString, + ), + 'LoadFile': grpc.unary_unary_rpc_method_handler( + servicer.LoadFile, + request_deserializer=pymol__rpc__pb2.LoadFileRequest.FromString, + response_serializer=pymol__rpc__pb2.CommandResponse.SerializeToString, + ), + 'LoadSurface': grpc.unary_unary_rpc_method_handler( + servicer.LoadSurface, + request_deserializer=pymol__rpc__pb2.LoadSurfaceRequest.FromString, + response_serializer=pymol__rpc__pb2.CommandResponse.SerializeToString, + ), + 'GetNames': grpc.unary_unary_rpc_method_handler( + servicer.GetNames, + request_deserializer=pymol__rpc__pb2.GetNamesRequest.FromString, + response_serializer=pymol__rpc__pb2.GetNamesResponse.SerializeToString, + ), + 'GetAtomCoords': grpc.unary_unary_rpc_method_handler( + servicer.GetAtomCoords, + request_deserializer=pymol__rpc__pb2.GetAtomCoordsRequest.FromString, + response_serializer=pymol__rpc__pb2.GetAtomCoordsResponse.SerializeToString, + ), + 'DeleteObject': grpc.unary_unary_rpc_method_handler( + servicer.DeleteObject, + request_deserializer=pymol__rpc__pb2.ObjectRequest.FromString, + response_serializer=pymol__rpc__pb2.StatusResponse.SerializeToString, + ), + 'DeleteAll': grpc.unary_unary_rpc_method_handler( + servicer.DeleteAll, + request_deserializer=pymol__rpc__pb2.Empty.FromString, + response_serializer=pymol__rpc__pb2.StatusResponse.SerializeToString, + ), + 'Center': grpc.unary_unary_rpc_method_handler( + servicer.Center, + request_deserializer=pymol__rpc__pb2.CenterRequest.FromString, + response_serializer=pymol__rpc__pb2.StatusResponse.SerializeToString, + ), + 'Zoom': grpc.unary_unary_rpc_method_handler( + servicer.Zoom, + request_deserializer=pymol__rpc__pb2.ZoomRequest.FromString, + response_serializer=pymol__rpc__pb2.StatusResponse.SerializeToString, + ), + 'Rotate': grpc.unary_unary_rpc_method_handler( + servicer.Rotate, + request_deserializer=pymol__rpc__pb2.RotateRequest.FromString, + response_serializer=pymol__rpc__pb2.StatusResponse.SerializeToString, + ), + 'Move': grpc.unary_unary_rpc_method_handler( + servicer.Move, + request_deserializer=pymol__rpc__pb2.MoveRequest.FromString, + response_serializer=pymol__rpc__pb2.StatusResponse.SerializeToString, + ), + 'Hide': grpc.unary_unary_rpc_method_handler( + servicer.Hide, + request_deserializer=pymol__rpc__pb2.ShowHideRequest.FromString, + response_serializer=pymol__rpc__pb2.StatusResponse.SerializeToString, + ), + 'Show': grpc.unary_unary_rpc_method_handler( + servicer.Show, + request_deserializer=pymol__rpc__pb2.ShowHideRequest.FromString, + response_serializer=pymol__rpc__pb2.StatusResponse.SerializeToString, + ), + 'Color': grpc.unary_unary_rpc_method_handler( + servicer.Color, + request_deserializer=pymol__rpc__pb2.ColorRequest.FromString, + response_serializer=pymol__rpc__pb2.StatusResponse.SerializeToString, + ), + 'SetTransparency': grpc.unary_unary_rpc_method_handler( + servicer.SetTransparency, + request_deserializer=pymol__rpc__pb2.TransparencyRequest.FromString, + response_serializer=pymol__rpc__pb2.StatusResponse.SerializeToString, + ), + 'Select': grpc.unary_unary_rpc_method_handler( + servicer.Select, + request_deserializer=pymol__rpc__pb2.SelectionRequest.FromString, + response_serializer=pymol__rpc__pb2.StatusResponse.SerializeToString, + ), + 'DeleteSelection': grpc.unary_unary_rpc_method_handler( + servicer.DeleteSelection, + request_deserializer=pymol__rpc__pb2.SelectionRequest.FromString, + response_serializer=pymol__rpc__pb2.StatusResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'PyMolRPC', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + server.add_registered_method_handlers('PyMolRPC', rpc_method_handlers) + + + # This class is part of an EXPERIMENTAL API. +class PyMolRPC(object): + """Missing associated documentation comment in .proto file.""" + + @staticmethod + def Ping(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, + '/PyMolRPC/Ping', + pymol__rpc__pb2.Empty.SerializeToString, + pymol__rpc__pb2.StatusResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def Do(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, + '/PyMolRPC/Do', + pymol__rpc__pb2.CommandRequest.SerializeToString, + pymol__rpc__pb2.CommandResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def Label(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, + '/PyMolRPC/Label', + pymol__rpc__pb2.LabelRequest.SerializeToString, + pymol__rpc__pb2.StatusResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def Sphere(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, + '/PyMolRPC/Sphere', + pymol__rpc__pb2.SphereRequest.SerializeToString, + pymol__rpc__pb2.StatusResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def Cylinder(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, + '/PyMolRPC/Cylinder', + pymol__rpc__pb2.CylinderRequest.SerializeToString, + pymol__rpc__pb2.StatusResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def LoadPDB(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, + '/PyMolRPC/LoadPDB', + pymol__rpc__pb2.LoadMolRequest.SerializeToString, + pymol__rpc__pb2.CommandResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def LoadMolBlock(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, + '/PyMolRPC/LoadMolBlock', + pymol__rpc__pb2.LoadMolRequest.SerializeToString, + pymol__rpc__pb2.CommandResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def LoadFile(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, + '/PyMolRPC/LoadFile', + pymol__rpc__pb2.LoadFileRequest.SerializeToString, + pymol__rpc__pb2.CommandResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def LoadSurface(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, + '/PyMolRPC/LoadSurface', + pymol__rpc__pb2.LoadSurfaceRequest.SerializeToString, + pymol__rpc__pb2.CommandResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def GetNames(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, + '/PyMolRPC/GetNames', + pymol__rpc__pb2.GetNamesRequest.SerializeToString, + pymol__rpc__pb2.GetNamesResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def GetAtomCoords(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, + '/PyMolRPC/GetAtomCoords', + pymol__rpc__pb2.GetAtomCoordsRequest.SerializeToString, + pymol__rpc__pb2.GetAtomCoordsResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def DeleteObject(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, + '/PyMolRPC/DeleteObject', + pymol__rpc__pb2.ObjectRequest.SerializeToString, + pymol__rpc__pb2.StatusResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def DeleteAll(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, + '/PyMolRPC/DeleteAll', + pymol__rpc__pb2.Empty.SerializeToString, + pymol__rpc__pb2.StatusResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def Center(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, + '/PyMolRPC/Center', + pymol__rpc__pb2.CenterRequest.SerializeToString, + pymol__rpc__pb2.StatusResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def Zoom(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, + '/PyMolRPC/Zoom', + pymol__rpc__pb2.ZoomRequest.SerializeToString, + pymol__rpc__pb2.StatusResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def Rotate(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, + '/PyMolRPC/Rotate', + pymol__rpc__pb2.RotateRequest.SerializeToString, + pymol__rpc__pb2.StatusResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def Move(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, + '/PyMolRPC/Move', + pymol__rpc__pb2.MoveRequest.SerializeToString, + pymol__rpc__pb2.StatusResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def Hide(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, + '/PyMolRPC/Hide', + pymol__rpc__pb2.ShowHideRequest.SerializeToString, + pymol__rpc__pb2.StatusResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def Show(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, + '/PyMolRPC/Show', + pymol__rpc__pb2.ShowHideRequest.SerializeToString, + pymol__rpc__pb2.StatusResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def Color(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, + '/PyMolRPC/Color', + pymol__rpc__pb2.ColorRequest.SerializeToString, + pymol__rpc__pb2.StatusResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def SetTransparency(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, + '/PyMolRPC/SetTransparency', + pymol__rpc__pb2.TransparencyRequest.SerializeToString, + pymol__rpc__pb2.StatusResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def Select(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, + '/PyMolRPC/Select', + pymol__rpc__pb2.SelectionRequest.SerializeToString, + pymol__rpc__pb2.StatusResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def DeleteSelection(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, + '/PyMolRPC/DeleteSelection', + pymol__rpc__pb2.SelectionRequest.SerializeToString, + pymol__rpc__pb2.StatusResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) diff --git a/proto/pymol_rpc.proto b/proto/pymol_rpc.proto new file mode 100644 index 000000000..e71dfb525 --- /dev/null +++ b/proto/pymol_rpc.proto @@ -0,0 +1,183 @@ +syntax = "proto3"; + +message Empty {} + +message StatusResponse { + bool success = 1; + string message = 2; +} + +message Vector3 { + float x = 1; + float y = 2; + float z = 3; +} + +message ColorRGB { + float r = 1; + float g = 2; + float b = 3; +} + +message CommandRequest { + string command = 1; +} + +message CommandResponse { + string result = 1; +} + +message LabelRequest { + Vector3 pos = 1; + string text = 2; + string id = 3; + ColorRGB color = 4; +} + +message SphereRequest { + Vector3 pos = 1; + float radius = 2; + ColorRGB color = 3; + string id = 4; + bool extend = 5; + bool transparent = 6; + float transparency = 7; +} + +message CylinderRequest { + Vector3 end1 = 1; + Vector3 end2 = 2; + float radius = 3; + ColorRGB color1 = 4; + optional ColorRGB color2 = 5; + string id = 6; + bool extend = 7; + bool transparent = 8; + float transparency = 9; +} + +message LoadMolRequest { + string data = 1; + string obj_name = 2; + optional string color_scheme = 3; + bool replace = 4; +} + +message LoadFileRequest { + string file_name = 1; + string obj_name = 2; + optional string format = 3; + optional string color_scheme = 4; + bool replace = 5; +} + +message LoadSurfaceRequest { + oneof source { + string data = 1; + string file_name = 2; + } + string obj_name = 3; + optional string format = 4; + float surface_level = 5; +} + +message GetNamesRequest { + string what = 1; + bool enabled_only = 2; +} + +message GetNamesResponse { + repeated string names = 1; +} + +message GetAtomCoordsRequest { + string selection = 1; + int32 state = 2; +} + +message GetAtomCoordsResponse { + repeated Vector3 coordinates = 1; +} + +/* --- Backward compatibility requests --- */ + +message ObjectRequest { + string name = 1; +} + +message SelectionRequest { + string selection = 1; +} + +message CenterRequest { + string selection = 1; + bool animate = 2; +} + +message ZoomRequest { + string selection = 1; + float buffer = 2; + int32 state = 3; + bool animate = 4; +} + +message RotateRequest { + string axis = 1; + float angle = 2; + string selection = 3; +} + +message MoveRequest { + string axis = 1; + float distance = 2; + string selection = 3; +} + +message ShowHideRequest { + string representation = 1; + string selection = 2; +} + +message ColorRequest { + string color = 1; + string selection = 2; +} + +message TransparencyRequest { + float transparency = 1; + string selection = 2; +} + +service PyMolRPC { + rpc Ping(Empty) returns (StatusResponse); + rpc Do(CommandRequest) returns (CommandResponse); + + rpc Label(LabelRequest) returns (StatusResponse); + rpc Sphere(SphereRequest) returns (StatusResponse); + rpc Cylinder(CylinderRequest) returns (StatusResponse); + + rpc LoadPDB(LoadMolRequest) returns (CommandResponse); + rpc LoadMolBlock(LoadMolRequest) returns (CommandResponse); + rpc LoadFile(LoadFileRequest) returns (CommandResponse); + rpc LoadSurface(LoadSurfaceRequest) returns (CommandResponse); + + rpc GetNames(GetNamesRequest) returns (GetNamesResponse); + rpc GetAtomCoords(GetAtomCoordsRequest) returns (GetAtomCoordsResponse); + + // Backward compatibility methods + rpc DeleteObject(ObjectRequest) returns (StatusResponse); + rpc DeleteAll(Empty) returns (StatusResponse); + + rpc Center(CenterRequest) returns (StatusResponse); + rpc Zoom(ZoomRequest) returns (StatusResponse); + rpc Rotate(RotateRequest) returns (StatusResponse); + rpc Move(MoveRequest) returns (StatusResponse); + + rpc Hide(ShowHideRequest) returns (StatusResponse); + rpc Show(ShowHideRequest) returns (StatusResponse); + rpc Color(ColorRequest) returns (StatusResponse); + rpc SetTransparency(TransparencyRequest) returns (StatusResponse); + + rpc Select(SelectionRequest) returns (StatusResponse); + rpc DeleteSelection(SelectionRequest) returns (StatusResponse); +}