diff --git a/protos/ni/panels/v1/panel_service.proto b/protos/ni/panels/v1/panel_service.proto index a96acc0..2291346 100644 --- a/protos/ni/panels/v1/panel_service.proto +++ b/protos/ni/panels/v1/panel_service.proto @@ -18,17 +18,17 @@ option ruby_package = "NI::Panels::V1"; service PanelService { // Start a panel using the provided configuration (or connect to if it has already been started) // Status Codes for errors: - // - INVALID_ARGUMENT: - // - The panel identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. + // - INVALID_ARGUMENT: + // - The panel identifier contains invalid characters. // - The panel configuration has an invalid argument. - // - NOT_FOUND: + // - NOT_FOUND: // - The panel configuration includes a file that was not found. rpc StartPanel(StartPanelRequest) returns (StartPanelResponse); // Stop a panel // Status Codes for errors: // - INVALID_ARGUMENT: - // - The panel identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. + // - The panel identifier contains invalid characters. rpc StopPanel(StopPanelRequest) returns (StopPanelResponse); // Enumerate the panels available in the system, including information about the state of the panels and what values they have. @@ -37,43 +37,43 @@ service PanelService { // Get a value for a control on the panel // Status Codes for errors: - // - INVALID_ARGUMENT: - // - The panel identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. - // - The value identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. - // - NOT_FOUND: + // - INVALID_ARGUMENT: + // - The panel identifier contains invalid characters. + // - The value identifier contains invalid characters. + // - NOT_FOUND: // - The value with the specified identifier was not found. rpc GetValue(GetValueRequest) returns (GetValueResponse); // Try to get a value for a control on the panel // Status Codes for errors: - // - INVALID_ARGUMENT: - // - The panel identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. - // - The value identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. + // - INVALID_ARGUMENT: + // - The panel identifier contains invalid characters. + // - The value identifier contains invalid characters. rpc TryGetValue(TryGetValueRequest) returns (TryGetValueResponse); // Set a value for a control on the panel // Status Codes for errors: - // - INVALID_ARGUMENT: - // - The panel identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. - // - The value identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. + // - INVALID_ARGUMENT: + // - The panel identifier contains invalid characters. + // - The value identifier contains invalid characters. rpc SetValue(SetValueRequest) returns (SetValueResponse); } message StartPanelRequest { - // Unique ID of the panel + // Unique ID of the panel. Only alphanumeric characters and underscores are allowed. string panel_id = 1; - // Configuration for the panel, packed as Any + // Configuration for the panel, packed as a google.protobuf.Any google.protobuf.Any panel_configuration = 2; } message StartPanelResponse { - // Location of the panel - string panel_uri = 1; + // Location of the panel + string panel_url = 1; } message StopPanelRequest { - // Unique ID of the panel + // Unique ID of the panel. Only alphanumeric characters and underscores are allowed. string panel_id = 1; // Reset all storage associated with panel @@ -91,7 +91,7 @@ message PanelInformation { string panel_id = 1; // Location of the panel - string panel_uri = 2; + string panel_url = 2; // IDs of all of the values associated with the panel repeated string value_ids = 3; @@ -103,39 +103,42 @@ message EnumeratePanelsResponse { } message GetValueRequest { - // Unique ID of the panel + // Unique ID of the panel. Only alphanumeric characters and underscores are allowed. string panel_id = 1; - // Unique ID of value + // Unique ID of value. Only alphanumeric characters and underscores are allowed. string value_id = 2; } message GetValueResponse { - // The value + // The value, packed as a google.protobuf.Any. + // Only types from google/protobuf/wrappers.proto and the ni.protobuf.types package are allowed. google.protobuf.Any value = 1; } message TryGetValueRequest { - // Unique ID of the panel + // Unique ID of the panel. Only alphanumeric characters and underscores are allowed. string panel_id = 1; - // Unique ID of value + // Unique ID of value. Only alphanumeric characters and underscores are allowed. string value_id = 2; } message TryGetValueResponse { - // The value, if it was found - optional google.protobuf.Any value = 1; + // The value (if it was found), packed as a google.protobuf.Any. + // Only types from google/protobuf/wrappers.proto and the ni.protobuf.types package are allowed. + google.protobuf.Any value = 1; } message SetValueRequest { - // Unique ID of the panel + // Unique ID of the panel. Only alphanumeric characters and underscores are allowed. string panel_id = 1; - // Unique ID of the value + // Unique ID of the value. Only alphanumeric characters and underscores are allowed. string value_id = 2; - // The value + // The value, packed as a google.protobuf.Any. + // Only types from google/protobuf/wrappers.proto and the ni.protobuf.types package are allowed. google.protobuf.Any value = 3; // Notify other clients of this new value diff --git a/protos/ni/panels/v1/streamlit_panel_configuration.proto b/protos/ni/panels/v1/streamlit_panel_configuration.proto index 82e3abf..1d7c241 100644 --- a/protos/ni/panels/v1/streamlit_panel_configuration.proto +++ b/protos/ni/panels/v1/streamlit_panel_configuration.proto @@ -13,11 +13,11 @@ option php_namespace = "NI\\Panels\\V1"; option ruby_package = "NI::Panels::V1"; // Pack this into PanelService.StartPanelRequest.panel_configuration to start a Streamlit panel. -message StreamlitPanelConfiguration +message StreamlitPanelConfiguration { - // Absolute path of the streamlit script file on disk, or network path to the file. This must end in ".py". - string panel_script_path = 1; + // Location of the streamlit script file on disk, or network path to the file. This must end in ".py". + string panel_script_url = 1; - // Path to the python interpreter to use for running the streamlit script. - string python_path = 2; + // Location of the python interpreter to use for running the streamlit script. + string python_interpreter_url = 2; } \ No newline at end of file diff --git a/src/ni/panels/v1/panel_service_pb2.py b/src/ni/panels/v1/panel_service_pb2.py index fe0a80c..90d9b2b 100644 --- a/src/ni/panels/v1/panel_service_pb2.py +++ b/src/ni/panels/v1/panel_service_pb2.py @@ -14,7 +14,7 @@ from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n ni/panels/v1/panel_service.proto\x12\x0cni.panels.v1\x1a\x19google/protobuf/any.proto\"X\n\x11StartPanelRequest\x12\x10\n\x08panel_id\x18\x01 \x01(\t\x12\x31\n\x13panel_configuration\x18\x02 \x01(\x0b\x32\x14.google.protobuf.Any\"\'\n\x12StartPanelResponse\x12\x11\n\tpanel_uri\x18\x01 \x01(\t\"3\n\x10StopPanelRequest\x12\x10\n\x08panel_id\x18\x01 \x01(\t\x12\r\n\x05reset\x18\x02 \x01(\x08\"\x13\n\x11StopPanelResponse\"\x18\n\x16\x45numeratePanelsRequest\"J\n\x10PanelInformation\x12\x10\n\x08panel_id\x18\x01 \x01(\t\x12\x11\n\tpanel_uri\x18\x02 \x01(\t\x12\x11\n\tvalue_ids\x18\x03 \x03(\t\"I\n\x17\x45numeratePanelsResponse\x12.\n\x06panels\x18\x01 \x03(\x0b\x32\x1e.ni.panels.v1.PanelInformation\"5\n\x0fGetValueRequest\x12\x10\n\x08panel_id\x18\x01 \x01(\t\x12\x10\n\x08value_id\x18\x02 \x01(\t\"7\n\x10GetValueResponse\x12#\n\x05value\x18\x01 \x01(\x0b\x32\x14.google.protobuf.Any\"8\n\x12TryGetValueRequest\x12\x10\n\x08panel_id\x18\x01 \x01(\t\x12\x10\n\x08value_id\x18\x02 \x01(\t\"I\n\x13TryGetValueResponse\x12(\n\x05value\x18\x01 \x01(\x0b\x32\x14.google.protobuf.AnyH\x00\x88\x01\x01\x42\x08\n\x06_value\"j\n\x0fSetValueRequest\x12\x10\n\x08panel_id\x18\x01 \x01(\t\x12\x10\n\x08value_id\x18\x02 \x01(\t\x12#\n\x05value\x18\x03 \x01(\x0b\x32\x14.google.protobuf.Any\x12\x0e\n\x06notify\x18\x04 \x01(\x08\"\x12\n\x10SetValueResponse2\xf7\x03\n\x0cPanelService\x12O\n\nStartPanel\x12\x1f.ni.panels.v1.StartPanelRequest\x1a .ni.panels.v1.StartPanelResponse\x12L\n\tStopPanel\x12\x1e.ni.panels.v1.StopPanelRequest\x1a\x1f.ni.panels.v1.StopPanelResponse\x12^\n\x0f\x45numeratePanels\x12$.ni.panels.v1.EnumeratePanelsRequest\x1a%.ni.panels.v1.EnumeratePanelsResponse\x12I\n\x08GetValue\x12\x1d.ni.panels.v1.GetValueRequest\x1a\x1e.ni.panels.v1.GetValueResponse\x12R\n\x0bTryGetValue\x12 .ni.panels.v1.TryGetValueRequest\x1a!.ni.panels.v1.TryGetValueResponse\x12I\n\x08SetValue\x12\x1d.ni.panels.v1.SetValueRequest\x1a\x1e.ni.panels.v1.SetValueResponseBu\n\x10\x63om.ni.panels.v1B\x0bPanelsProtoP\x01Z\x08panelsv1\xf8\x01\x01\xa2\x02\x04NIPS\xaa\x02\x1dNationalInstruments.Panels.V1\xca\x02\x0cNI\\Panels\\V1\xea\x02\x0eNI::Panels::V1b\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n ni/panels/v1/panel_service.proto\x12\x0cni.panels.v1\x1a\x19google/protobuf/any.proto\"X\n\x11StartPanelRequest\x12\x10\n\x08panel_id\x18\x01 \x01(\t\x12\x31\n\x13panel_configuration\x18\x02 \x01(\x0b\x32\x14.google.protobuf.Any\"\'\n\x12StartPanelResponse\x12\x11\n\tpanel_url\x18\x01 \x01(\t\"3\n\x10StopPanelRequest\x12\x10\n\x08panel_id\x18\x01 \x01(\t\x12\r\n\x05reset\x18\x02 \x01(\x08\"\x13\n\x11StopPanelResponse\"\x18\n\x16\x45numeratePanelsRequest\"J\n\x10PanelInformation\x12\x10\n\x08panel_id\x18\x01 \x01(\t\x12\x11\n\tpanel_url\x18\x02 \x01(\t\x12\x11\n\tvalue_ids\x18\x03 \x03(\t\"I\n\x17\x45numeratePanelsResponse\x12.\n\x06panels\x18\x01 \x03(\x0b\x32\x1e.ni.panels.v1.PanelInformation\"5\n\x0fGetValueRequest\x12\x10\n\x08panel_id\x18\x01 \x01(\t\x12\x10\n\x08value_id\x18\x02 \x01(\t\"7\n\x10GetValueResponse\x12#\n\x05value\x18\x01 \x01(\x0b\x32\x14.google.protobuf.Any\"8\n\x12TryGetValueRequest\x12\x10\n\x08panel_id\x18\x01 \x01(\t\x12\x10\n\x08value_id\x18\x02 \x01(\t\":\n\x13TryGetValueResponse\x12#\n\x05value\x18\x01 \x01(\x0b\x32\x14.google.protobuf.Any\"j\n\x0fSetValueRequest\x12\x10\n\x08panel_id\x18\x01 \x01(\t\x12\x10\n\x08value_id\x18\x02 \x01(\t\x12#\n\x05value\x18\x03 \x01(\x0b\x32\x14.google.protobuf.Any\x12\x0e\n\x06notify\x18\x04 \x01(\x08\"\x12\n\x10SetValueResponse2\xf7\x03\n\x0cPanelService\x12O\n\nStartPanel\x12\x1f.ni.panels.v1.StartPanelRequest\x1a .ni.panels.v1.StartPanelResponse\x12L\n\tStopPanel\x12\x1e.ni.panels.v1.StopPanelRequest\x1a\x1f.ni.panels.v1.StopPanelResponse\x12^\n\x0f\x45numeratePanels\x12$.ni.panels.v1.EnumeratePanelsRequest\x1a%.ni.panels.v1.EnumeratePanelsResponse\x12I\n\x08GetValue\x12\x1d.ni.panels.v1.GetValueRequest\x1a\x1e.ni.panels.v1.GetValueResponse\x12R\n\x0bTryGetValue\x12 .ni.panels.v1.TryGetValueRequest\x1a!.ni.panels.v1.TryGetValueResponse\x12I\n\x08SetValue\x12\x1d.ni.panels.v1.SetValueRequest\x1a\x1e.ni.panels.v1.SetValueResponseBu\n\x10\x63om.ni.panels.v1B\x0bPanelsProtoP\x01Z\x08panelsv1\xf8\x01\x01\xa2\x02\x04NIPS\xaa\x02\x1dNationalInstruments.Panels.V1\xca\x02\x0cNI\\Panels\\V1\xea\x02\x0eNI::Panels::V1b\x06proto3') _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'ni.panels.v1.panel_service_pb2', globals()) @@ -43,11 +43,11 @@ _TRYGETVALUEREQUEST._serialized_start=571 _TRYGETVALUEREQUEST._serialized_end=627 _TRYGETVALUERESPONSE._serialized_start=629 - _TRYGETVALUERESPONSE._serialized_end=702 - _SETVALUEREQUEST._serialized_start=704 - _SETVALUEREQUEST._serialized_end=810 - _SETVALUERESPONSE._serialized_start=812 - _SETVALUERESPONSE._serialized_end=830 - _PANELSERVICE._serialized_start=833 - _PANELSERVICE._serialized_end=1336 + _TRYGETVALUERESPONSE._serialized_end=687 + _SETVALUEREQUEST._serialized_start=689 + _SETVALUEREQUEST._serialized_end=795 + _SETVALUERESPONSE._serialized_start=797 + _SETVALUERESPONSE._serialized_end=815 + _PANELSERVICE._serialized_start=818 + _PANELSERVICE._serialized_end=1321 # @@protoc_insertion_point(module_scope) diff --git a/src/ni/panels/v1/panel_service_pb2.pyi b/src/ni/panels/v1/panel_service_pb2.pyi index 538636b..5d64751 100644 --- a/src/ni/panels/v1/panel_service_pb2.pyi +++ b/src/ni/panels/v1/panel_service_pb2.pyi @@ -20,10 +20,10 @@ class StartPanelRequest(google.protobuf.message.Message): PANEL_ID_FIELD_NUMBER: builtins.int PANEL_CONFIGURATION_FIELD_NUMBER: builtins.int panel_id: builtins.str - """Unique ID of the panel""" + """Unique ID of the panel. Only alphanumeric characters and underscores are allowed.""" @property def panel_configuration(self) -> google.protobuf.any_pb2.Any: - """Configuration for the panel, packed as Any""" + """Configuration for the panel, packed as a google.protobuf.Any""" def __init__( self, @@ -40,15 +40,15 @@ global___StartPanelRequest = StartPanelRequest class StartPanelResponse(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor - PANEL_URI_FIELD_NUMBER: builtins.int - panel_uri: builtins.str + PANEL_URL_FIELD_NUMBER: builtins.int + panel_url: builtins.str """Location of the panel""" def __init__( self, *, - panel_uri: builtins.str = ..., + panel_url: builtins.str = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["panel_uri", b"panel_uri"]) -> None: ... + def ClearField(self, field_name: typing.Literal["panel_url", b"panel_url"]) -> None: ... global___StartPanelResponse = StartPanelResponse @@ -59,7 +59,7 @@ class StopPanelRequest(google.protobuf.message.Message): PANEL_ID_FIELD_NUMBER: builtins.int RESET_FIELD_NUMBER: builtins.int panel_id: builtins.str - """Unique ID of the panel""" + """Unique ID of the panel. Only alphanumeric characters and underscores are allowed.""" reset: builtins.bool """Reset all storage associated with panel""" def __init__( @@ -97,11 +97,11 @@ class PanelInformation(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor PANEL_ID_FIELD_NUMBER: builtins.int - PANEL_URI_FIELD_NUMBER: builtins.int + PANEL_URL_FIELD_NUMBER: builtins.int VALUE_IDS_FIELD_NUMBER: builtins.int panel_id: builtins.str """Unique ID of the panel""" - panel_uri: builtins.str + panel_url: builtins.str """Location of the panel""" @property def value_ids(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: @@ -111,10 +111,10 @@ class PanelInformation(google.protobuf.message.Message): self, *, panel_id: builtins.str = ..., - panel_uri: builtins.str = ..., + panel_url: builtins.str = ..., value_ids: collections.abc.Iterable[builtins.str] | None = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["panel_id", b"panel_id", "panel_uri", b"panel_uri", "value_ids", b"value_ids"]) -> None: ... + def ClearField(self, field_name: typing.Literal["panel_id", b"panel_id", "panel_url", b"panel_url", "value_ids", b"value_ids"]) -> None: ... global___PanelInformation = PanelInformation @@ -143,9 +143,9 @@ class GetValueRequest(google.protobuf.message.Message): PANEL_ID_FIELD_NUMBER: builtins.int VALUE_ID_FIELD_NUMBER: builtins.int panel_id: builtins.str - """Unique ID of the panel""" + """Unique ID of the panel. Only alphanumeric characters and underscores are allowed.""" value_id: builtins.str - """Unique ID of value""" + """Unique ID of value. Only alphanumeric characters and underscores are allowed.""" def __init__( self, *, @@ -163,7 +163,9 @@ class GetValueResponse(google.protobuf.message.Message): VALUE_FIELD_NUMBER: builtins.int @property def value(self) -> google.protobuf.any_pb2.Any: - """The value""" + """The value, packed as a google.protobuf.Any. + Only types from google/protobuf/wrappers.proto and the ni.protobuf.types package are allowed. + """ def __init__( self, @@ -182,9 +184,9 @@ class TryGetValueRequest(google.protobuf.message.Message): PANEL_ID_FIELD_NUMBER: builtins.int VALUE_ID_FIELD_NUMBER: builtins.int panel_id: builtins.str - """Unique ID of the panel""" + """Unique ID of the panel. Only alphanumeric characters and underscores are allowed.""" value_id: builtins.str - """Unique ID of value""" + """Unique ID of value. Only alphanumeric characters and underscores are allowed.""" def __init__( self, *, @@ -202,16 +204,17 @@ class TryGetValueResponse(google.protobuf.message.Message): VALUE_FIELD_NUMBER: builtins.int @property def value(self) -> google.protobuf.any_pb2.Any: - """The value, if it was found""" + """The value (if it was found), packed as a google.protobuf.Any. + Only types from google/protobuf/wrappers.proto and the ni.protobuf.types package are allowed. + """ def __init__( self, *, value: google.protobuf.any_pb2.Any | None = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["_value", b"_value", "value", b"value"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["_value", b"_value", "value", b"value"]) -> None: ... - def WhichOneof(self, oneof_group: typing.Literal["_value", b"_value"]) -> typing.Literal["value"] | None: ... + def HasField(self, field_name: typing.Literal["value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["value", b"value"]) -> None: ... global___TryGetValueResponse = TryGetValueResponse @@ -224,14 +227,16 @@ class SetValueRequest(google.protobuf.message.Message): VALUE_FIELD_NUMBER: builtins.int NOTIFY_FIELD_NUMBER: builtins.int panel_id: builtins.str - """Unique ID of the panel""" + """Unique ID of the panel. Only alphanumeric characters and underscores are allowed.""" value_id: builtins.str - """Unique ID of the value""" + """Unique ID of the value. Only alphanumeric characters and underscores are allowed.""" notify: builtins.bool """Notify other clients of this new value""" @property def value(self) -> google.protobuf.any_pb2.Any: - """The value""" + """The value, packed as a google.protobuf.Any. + Only types from google/protobuf/wrappers.proto and the ni.protobuf.types package are allowed. + """ def __init__( self, diff --git a/src/ni/panels/v1/panel_service_pb2_grpc.py b/src/ni/panels/v1/panel_service_pb2_grpc.py index ef44db2..dcc4d19 100644 --- a/src/ni/panels/v1/panel_service_pb2_grpc.py +++ b/src/ni/panels/v1/panel_service_pb2_grpc.py @@ -54,10 +54,10 @@ class PanelServiceServicer(object): def StartPanel(self, request, context): """Start a panel using the provided configuration (or connect to if it has already been started) Status Codes for errors: - - INVALID_ARGUMENT: - - The panel identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. + - INVALID_ARGUMENT: + - The panel identifier contains invalid characters. - The panel configuration has an invalid argument. - - NOT_FOUND: + - NOT_FOUND: - The panel configuration includes a file that was not found. """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) @@ -68,7 +68,7 @@ def StopPanel(self, request, context): """Stop a panel Status Codes for errors: - INVALID_ARGUMENT: - - The panel identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. + - The panel identifier contains invalid characters. """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') @@ -85,10 +85,10 @@ def EnumeratePanels(self, request, context): def GetValue(self, request, context): """Get a value for a control on the panel Status Codes for errors: - - INVALID_ARGUMENT: - - The panel identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. - - The value identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. - - NOT_FOUND: + - INVALID_ARGUMENT: + - The panel identifier contains invalid characters. + - The value identifier contains invalid characters. + - NOT_FOUND: - The value with the specified identifier was not found. """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) @@ -98,9 +98,9 @@ def GetValue(self, request, context): def TryGetValue(self, request, context): """Try to get a value for a control on the panel Status Codes for errors: - - INVALID_ARGUMENT: - - The panel identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. - - The value identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. + - INVALID_ARGUMENT: + - The panel identifier contains invalid characters. + - The value identifier contains invalid characters. """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') @@ -109,9 +109,9 @@ def TryGetValue(self, request, context): def SetValue(self, request, context): """Set a value for a control on the panel Status Codes for errors: - - INVALID_ARGUMENT: - - The panel identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. - - The value identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. + - INVALID_ARGUMENT: + - The panel identifier contains invalid characters. + - The value identifier contains invalid characters. """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') diff --git a/src/ni/panels/v1/panel_service_pb2_grpc.pyi b/src/ni/panels/v1/panel_service_pb2_grpc.pyi index 030c5a3..fadc03c 100644 --- a/src/ni/panels/v1/panel_service_pb2_grpc.pyi +++ b/src/ni/panels/v1/panel_service_pb2_grpc.pyi @@ -27,10 +27,10 @@ class PanelServiceStub: ] """Start a panel using the provided configuration (or connect to if it has already been started) Status Codes for errors: - - INVALID_ARGUMENT: - - The panel identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. + - INVALID_ARGUMENT: + - The panel identifier contains invalid characters. - The panel configuration has an invalid argument. - - NOT_FOUND: + - NOT_FOUND: - The panel configuration includes a file that was not found. """ @@ -41,7 +41,7 @@ class PanelServiceStub: """Stop a panel Status Codes for errors: - INVALID_ARGUMENT: - - The panel identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. + - The panel identifier contains invalid characters. """ EnumeratePanels: grpc.UnaryUnaryMultiCallable[ @@ -58,10 +58,10 @@ class PanelServiceStub: ] """Get a value for a control on the panel Status Codes for errors: - - INVALID_ARGUMENT: - - The panel identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. - - The value identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. - - NOT_FOUND: + - INVALID_ARGUMENT: + - The panel identifier contains invalid characters. + - The value identifier contains invalid characters. + - NOT_FOUND: - The value with the specified identifier was not found. """ @@ -71,9 +71,9 @@ class PanelServiceStub: ] """Try to get a value for a control on the panel Status Codes for errors: - - INVALID_ARGUMENT: - - The panel identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. - - The value identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. + - INVALID_ARGUMENT: + - The panel identifier contains invalid characters. + - The value identifier contains invalid characters. """ SetValue: grpc.UnaryUnaryMultiCallable[ @@ -82,9 +82,9 @@ class PanelServiceStub: ] """Set a value for a control on the panel Status Codes for errors: - - INVALID_ARGUMENT: - - The panel identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. - - The value identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. + - INVALID_ARGUMENT: + - The panel identifier contains invalid characters. + - The value identifier contains invalid characters. """ class PanelServiceAsyncStub: @@ -96,10 +96,10 @@ class PanelServiceAsyncStub: ] """Start a panel using the provided configuration (or connect to if it has already been started) Status Codes for errors: - - INVALID_ARGUMENT: - - The panel identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. + - INVALID_ARGUMENT: + - The panel identifier contains invalid characters. - The panel configuration has an invalid argument. - - NOT_FOUND: + - NOT_FOUND: - The panel configuration includes a file that was not found. """ @@ -110,7 +110,7 @@ class PanelServiceAsyncStub: """Stop a panel Status Codes for errors: - INVALID_ARGUMENT: - - The panel identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. + - The panel identifier contains invalid characters. """ EnumeratePanels: grpc.aio.UnaryUnaryMultiCallable[ @@ -127,10 +127,10 @@ class PanelServiceAsyncStub: ] """Get a value for a control on the panel Status Codes for errors: - - INVALID_ARGUMENT: - - The panel identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. - - The value identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. - - NOT_FOUND: + - INVALID_ARGUMENT: + - The panel identifier contains invalid characters. + - The value identifier contains invalid characters. + - NOT_FOUND: - The value with the specified identifier was not found. """ @@ -140,9 +140,9 @@ class PanelServiceAsyncStub: ] """Try to get a value for a control on the panel Status Codes for errors: - - INVALID_ARGUMENT: - - The panel identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. - - The value identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. + - INVALID_ARGUMENT: + - The panel identifier contains invalid characters. + - The value identifier contains invalid characters. """ SetValue: grpc.aio.UnaryUnaryMultiCallable[ @@ -151,9 +151,9 @@ class PanelServiceAsyncStub: ] """Set a value for a control on the panel Status Codes for errors: - - INVALID_ARGUMENT: - - The panel identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. - - The value identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. + - INVALID_ARGUMENT: + - The panel identifier contains invalid characters. + - The value identifier contains invalid characters. """ class PanelServiceServicer(metaclass=abc.ABCMeta): @@ -167,10 +167,10 @@ class PanelServiceServicer(metaclass=abc.ABCMeta): ) -> typing.Union[ni.panels.v1.panel_service_pb2.StartPanelResponse, collections.abc.Awaitable[ni.panels.v1.panel_service_pb2.StartPanelResponse]]: """Start a panel using the provided configuration (or connect to if it has already been started) Status Codes for errors: - - INVALID_ARGUMENT: - - The panel identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. + - INVALID_ARGUMENT: + - The panel identifier contains invalid characters. - The panel configuration has an invalid argument. - - NOT_FOUND: + - NOT_FOUND: - The panel configuration includes a file that was not found. """ @@ -183,7 +183,7 @@ class PanelServiceServicer(metaclass=abc.ABCMeta): """Stop a panel Status Codes for errors: - INVALID_ARGUMENT: - - The panel identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. + - The panel identifier contains invalid characters. """ @abc.abstractmethod @@ -204,10 +204,10 @@ class PanelServiceServicer(metaclass=abc.ABCMeta): ) -> typing.Union[ni.panels.v1.panel_service_pb2.GetValueResponse, collections.abc.Awaitable[ni.panels.v1.panel_service_pb2.GetValueResponse]]: """Get a value for a control on the panel Status Codes for errors: - - INVALID_ARGUMENT: - - The panel identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. - - The value identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. - - NOT_FOUND: + - INVALID_ARGUMENT: + - The panel identifier contains invalid characters. + - The value identifier contains invalid characters. + - NOT_FOUND: - The value with the specified identifier was not found. """ @@ -219,9 +219,9 @@ class PanelServiceServicer(metaclass=abc.ABCMeta): ) -> typing.Union[ni.panels.v1.panel_service_pb2.TryGetValueResponse, collections.abc.Awaitable[ni.panels.v1.panel_service_pb2.TryGetValueResponse]]: """Try to get a value for a control on the panel Status Codes for errors: - - INVALID_ARGUMENT: - - The panel identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. - - The value identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. + - INVALID_ARGUMENT: + - The panel identifier contains invalid characters. + - The value identifier contains invalid characters. """ @abc.abstractmethod @@ -232,9 +232,9 @@ class PanelServiceServicer(metaclass=abc.ABCMeta): ) -> typing.Union[ni.panels.v1.panel_service_pb2.SetValueResponse, collections.abc.Awaitable[ni.panels.v1.panel_service_pb2.SetValueResponse]]: """Set a value for a control on the panel Status Codes for errors: - - INVALID_ARGUMENT: - - The panel identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. - - The value identifier contains invalid characters. Only alphanumeric characters and underscores are allowed. + - INVALID_ARGUMENT: + - The panel identifier contains invalid characters. + - The value identifier contains invalid characters. """ def add_PanelServiceServicer_to_server(servicer: PanelServiceServicer, server: typing.Union[grpc.Server, grpc.aio.Server]) -> None: ... diff --git a/src/ni/panels/v1/streamlit_panel_configuration_pb2.py b/src/ni/panels/v1/streamlit_panel_configuration_pb2.py index 6e4f6eb..b50764d 100644 --- a/src/ni/panels/v1/streamlit_panel_configuration_pb2.py +++ b/src/ni/panels/v1/streamlit_panel_configuration_pb2.py @@ -13,7 +13,7 @@ -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n0ni/panels/v1/streamlit_panel_configuration.proto\x12\x0cni.panels.v1\"M\n\x1bStreamlitPanelConfiguration\x12\x19\n\x11panel_script_path\x18\x01 \x01(\t\x12\x13\n\x0bpython_path\x18\x02 \x01(\tB\x8a\x01\n\x10\x63om.ni.panels.v1B StreamlitPanelConfigurationProtoP\x01Z\x08panelsv1\xf8\x01\x01\xa2\x02\x04NIPS\xaa\x02\x1dNationalInstruments.Panels.V1\xca\x02\x0cNI\\Panels\\V1\xea\x02\x0eNI::Panels::V1b\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n0ni/panels/v1/streamlit_panel_configuration.proto\x12\x0cni.panels.v1\"W\n\x1bStreamlitPanelConfiguration\x12\x18\n\x10panel_script_url\x18\x01 \x01(\t\x12\x1e\n\x16python_interpreter_url\x18\x02 \x01(\tB\x8a\x01\n\x10\x63om.ni.panels.v1B StreamlitPanelConfigurationProtoP\x01Z\x08panelsv1\xf8\x01\x01\xa2\x02\x04NIPS\xaa\x02\x1dNationalInstruments.Panels.V1\xca\x02\x0cNI\\Panels\\V1\xea\x02\x0eNI::Panels::V1b\x06proto3') _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'ni.panels.v1.streamlit_panel_configuration_pb2', globals()) @@ -22,5 +22,5 @@ DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\020com.ni.panels.v1B StreamlitPanelConfigurationProtoP\001Z\010panelsv1\370\001\001\242\002\004NIPS\252\002\035NationalInstruments.Panels.V1\312\002\014NI\\Panels\\V1\352\002\016NI::Panels::V1' _STREAMLITPANELCONFIGURATION._serialized_start=66 - _STREAMLITPANELCONFIGURATION._serialized_end=143 + _STREAMLITPANELCONFIGURATION._serialized_end=153 # @@protoc_insertion_point(module_scope) diff --git a/src/ni/panels/v1/streamlit_panel_configuration_pb2.pyi b/src/ni/panels/v1/streamlit_panel_configuration_pb2.pyi index d62d0af..ec4a732 100644 --- a/src/ni/panels/v1/streamlit_panel_configuration_pb2.pyi +++ b/src/ni/panels/v1/streamlit_panel_configuration_pb2.pyi @@ -16,18 +16,18 @@ class StreamlitPanelConfiguration(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor - PANEL_SCRIPT_PATH_FIELD_NUMBER: builtins.int - PYTHON_PATH_FIELD_NUMBER: builtins.int - panel_script_path: builtins.str - """Absolute path of the streamlit script file on disk, or network path to the file. This must end in ".py".""" - python_path: builtins.str - """Path to the python interpreter to use for running the streamlit script.""" + PANEL_SCRIPT_URL_FIELD_NUMBER: builtins.int + PYTHON_INTERPRETER_URL_FIELD_NUMBER: builtins.int + panel_script_url: builtins.str + """Location of the streamlit script file on disk, or network path to the file. This must end in ".py".""" + python_interpreter_url: builtins.str + """Location of the python interpreter to use for running the streamlit script.""" def __init__( self, *, - panel_script_path: builtins.str = ..., - python_path: builtins.str = ..., + panel_script_url: builtins.str = ..., + python_interpreter_url: builtins.str = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["panel_script_path", b"panel_script_path", "python_path", b"python_path"]) -> None: ... + def ClearField(self, field_name: typing.Literal["panel_script_url", b"panel_script_url", "python_interpreter_url", b"python_interpreter_url"]) -> None: ... global___StreamlitPanelConfiguration = StreamlitPanelConfiguration diff --git a/src/nipanel/_panel_client.py b/src/nipanel/_panel_client.py index 8c284b0..5fae4d6 100644 --- a/src/nipanel/_panel_client.py +++ b/src/nipanel/_panel_client.py @@ -1,6 +1,7 @@ from __future__ import annotations import logging +import pathlib import threading from typing import Callable, TypeVar @@ -47,9 +48,14 @@ def __init__( self._grpc_channel = grpc_channel self._stub: PanelServiceStub | None = None - def start_streamlit_panel(self, panel_id: str, panel_script_path: str, python_path: str) -> str: + def start_streamlit_panel( + self, panel_id: str, panel_script_path: str, python_interpreter_path: str + ) -> str: + + panel_script_url = pathlib.Path(panel_script_path).absolute().as_uri() + python_interpreter_url = pathlib.Path(python_interpreter_path).absolute().as_uri() streamlit_panel_configuration = StreamlitPanelConfiguration( - panel_script_path=panel_script_path, python_path=python_path + panel_script_url=panel_script_url, python_interpreter_url=python_interpreter_url ) panel_configuration_any = Any() panel_configuration_any.Pack(streamlit_panel_configuration) @@ -57,7 +63,7 @@ def start_streamlit_panel(self, panel_id: str, panel_script_path: str, python_pa panel_id=panel_id, panel_configuration=panel_configuration_any ) response = self._invoke_with_retry(self._get_stub().StartPanel, start_panel_request) - return response.panel_uri + return response.panel_url def stop_panel(self, panel_id: str, reset: bool) -> None: stop_panel_request = StopPanelRequest(panel_id=panel_id, reset=reset) @@ -69,7 +75,7 @@ def enumerate_panels(self) -> dict[str, tuple[str, list[str]]]: self._get_stub().EnumeratePanels, enumerate_panels_request ) return { - panel.panel_id: (panel.panel_uri, list(panel.value_ids)) for panel in response.panels + panel.panel_id: (panel.panel_url, list(panel.value_ids)) for panel in response.panels } def set_value(self, panel_id: str, value_id: str, value: object, notify: bool) -> None: diff --git a/tests/unit/test_python_panel_service_stub.py b/tests/unit/test_python_panel_service_stub.py index e2521e2..6dd1843 100644 --- a/tests/unit/test_python_panel_service_stub.py +++ b/tests/unit/test_python_panel_service_stub.py @@ -14,19 +14,19 @@ def test___start_panel___gets_response(python_panel_service_stub: PanelServiceStub) -> None: - configuration = StreamlitPanelConfiguration(panel_script_path="path/to/panel.py") + configuration = StreamlitPanelConfiguration(panel_script_url="file:///path/to/panel.py") configuration_any = Any() configuration_any.Pack(configuration) request = StartPanelRequest(panel_id="test_panel", panel_configuration=configuration_any) response = python_panel_service_stub.StartPanel(request) - assert response.panel_uri == "http://localhost:50051/test_panel" + assert response.panel_url == "http://localhost:50051/test_panel" def test___start_panel___stop_panel___gets_response( python_panel_service_stub: PanelServiceStub, ) -> None: - configuration = StreamlitPanelConfiguration(panel_script_path="path/to/panel.py") + configuration = StreamlitPanelConfiguration(panel_script_url="file:///path/to/panel.py") configuration_any = Any() configuration_any.Pack(configuration) start_request = StartPanelRequest(panel_id="test_panel", panel_configuration=configuration_any) diff --git a/tests/unit/test_streamlit_panel.py b/tests/unit/test_streamlit_panel.py index 860bacf..f88ff67 100644 --- a/tests/unit/test_streamlit_panel.py +++ b/tests/unit/test_streamlit_panel.py @@ -509,13 +509,23 @@ def test___panel___panel_is_running_and_in_memory( assert is_panel_running(panel) -def test___panel___python_path_is_in_venv( +def test___panel___python_interpreter_url_is_in_venv( fake_python_panel_service: FakePythonPanelService, fake_panel_channel: grpc.Channel, ) -> None: StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) - assert ".venv" in fake_python_panel_service.servicer.python_path + assert fake_python_panel_service.servicer.python_interpreter_url.startswith("file:///") + assert ".venv" in fake_python_panel_service.servicer.python_interpreter_url + + +def test___panel___python_script_url_starts_with_file( + fake_python_panel_service: FakePythonPanelService, + fake_panel_channel: grpc.Channel, +) -> None: + StreamlitPanel("my_panel", "path/to/script", grpc_channel=fake_panel_channel) + + assert fake_python_panel_service.servicer.python_script_url.startswith("file:///") def is_panel_in_memory(panel: StreamlitPanel) -> bool: diff --git a/tests/utils/_fake_python_panel_servicer.py b/tests/utils/_fake_python_panel_servicer.py index d6d4c10..8fc8a37 100644 --- a/tests/utils/_fake_python_panel_servicer.py +++ b/tests/utils/_fake_python_panel_servicer.py @@ -31,7 +31,8 @@ def __init__(self) -> None: self._fail_next_start_panel = False self._set_count: int = 0 self._notification_count: int = 0 - self._python_path: str = "" + self._python_interpreter_url: str = "" + self._python_script_url: str = "" def StartPanel( # noqa: N802 self, request: StartPanelRequest, context: Any @@ -39,12 +40,13 @@ def StartPanel( # noqa: N802 """Trivial implementation for testing.""" streamlit_panel_configuration = StreamlitPanelConfiguration() request.panel_configuration.Unpack(streamlit_panel_configuration) - self._python_path = streamlit_panel_configuration.python_path + self._python_interpreter_url = streamlit_panel_configuration.python_interpreter_url + self._python_script_url = streamlit_panel_configuration.panel_script_url if self._fail_next_start_panel: self._fail_next_start_panel = False context.abort(grpc.StatusCode.UNAVAILABLE, "Simulated failure") self._start_panel(request.panel_id) - return StartPanelResponse(panel_uri=self._get_panel_uri(request.panel_id)) + return StartPanelResponse(panel_url=self._get_panel_uri(request.panel_id)) def StopPanel(self, request: StopPanelRequest, context: Any) -> StopPanelResponse: # noqa: N802 """Trivial implementation for testing.""" @@ -59,7 +61,7 @@ def EnumeratePanels( # noqa: N802 for panel_id in self._panel_ids: panel = PanelInformation( panel_id=panel_id, - panel_uri=self._get_panel_uri(panel_id), + panel_url=self._get_panel_uri(panel_id), value_ids=self._panel_value_ids[panel_id], ) response.panels.append(panel) @@ -105,9 +107,14 @@ def notification_count(self) -> int: return self._notification_count @property - def python_path(self) -> str: - """Get the Python path used to start the panel.""" - return self._python_path + def python_interpreter_url(self) -> str: + """Get the Python interpreter url.""" + return self._python_interpreter_url + + @property + def python_script_url(self) -> str: + """Get the Python script url.""" + return self._python_script_url def _init_panel(self, panel_id: str) -> None: if panel_id not in self._panel_ids: