Skip to content

Commit

Permalink
Add grpc python code
Browse files Browse the repository at this point in the history
  • Loading branch information
radovanZRasa committed Jun 13, 2024
1 parent 939d4b1 commit dc988a2
Show file tree
Hide file tree
Showing 11 changed files with 458 additions and 15 deletions.
11 changes: 10 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ install:
poetry run python -m pip install -U pip
poetry install


clean:
find . -name '*.pyc' -exec rm -f {} +
find . -name '*.pyo' -exec rm -f {} +
Expand Down Expand Up @@ -62,3 +61,13 @@ cleanup-generated-changelog:
release:
poetry run python scripts/release.py

download-protoc-compiler:
curl -0L https://github.com/protocolbuffers/protobuf/releases/download/v25.0/protoc-25.0-osx-aarch_64.zip --output protoc-25.0-osx-aarch_64.zip

generate-grpc:
python -m grpc_tools.protoc \
-Irasa_sdk/grpc_py=./proto \
--python_out=. \
--grpc_python_out=. \
--pyi_out=. \
proto/action_webhook.proto
13 changes: 12 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,4 @@ asyncio_mode = "auto"
[tool.poetry.group.dev.dependencies]
ruff = ">=0.0.256,<0.0.286"
pytest-asyncio = "^0.21.0"
types-protobuf = "4.25.0.20240417"
50 changes: 40 additions & 10 deletions rasa_sdk/__main__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
import logging
import asyncio
import signal

from rasa_sdk import utils
from rasa_sdk.endpoint import create_argument_parser, run
from rasa_sdk.constants import APPLICATION_ROOT_LOGGER_NAME
from rasa_sdk.grpc_server import run_grpc

logger = logging.getLogger(__name__)


def initialise_interrupts() -> None:
"""Initialise handlers for kernel signal interrupts."""

def handle_sigint(signum, frame):
logger.info("Received SIGINT, exiting")
asyncio.get_event_loop().stop()

signal.signal(signal.SIGINT, handle_sigint)
signal.signal(signal.SIGTERM, handle_sigint)


def main_from_args(args):
Expand All @@ -18,16 +34,30 @@ def main_from_args(args):
)
utils.update_sanic_log_level()

run(
args.actions,
args.port,
args.cors,
args.ssl_certificate,
args.ssl_keyfile,
args.ssl_password,
args.auto_reload,
args.endpoints,
)
initialise_interrupts()

if args.grpc:
asyncio.run(
run_grpc(
args.actions,
args.port,
args.ssl_certificate,
args.ssl_keyfile,
args.ssl_password,
args.endpoints,
)
)
else:
run(
args.actions,
args.port,
args.cors,
args.ssl_certificate,
args.ssl_keyfile,
args.ssl_password,
args.auto_reload,
args.endpoints,
)


def main():
Expand Down
5 changes: 5 additions & 0 deletions rasa_sdk/cli/arguments.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,8 @@ def add_endpoint_arguments(parser):
default=DEFAULT_ENDPOINTS_PATH,
help="Configuration file for the assistant as a yml file.",
)
parser.add_argument(
"--grpc",
help="Starts grpc server instead of http",
action="store_true"
)
Empty file added rasa_sdk/grpc_py/__init__.py
Empty file.
71 changes: 71 additions & 0 deletions rasa_sdk/grpc_py/action_webhook_pb2.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

138 changes: 138 additions & 0 deletions rasa_sdk/grpc_py/action_webhook_pb2.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
from google.protobuf import any_pb2 as _any_pb2
from google.protobuf.internal import containers as _containers
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union

DESCRIPTOR: _descriptor.FileDescriptor

class Tracker(_message.Message):
__slots__ = ["conversation_id", "slots", "latest_message", "latest_event_time", "followup_action", "paused", "events", "latest_input_channel", "active_loop", "latest_action"]
class SlotsEntry(_message.Message):
__slots__ = ["key", "value"]
KEY_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
key: str
value: str
def __init__(self, key: _Optional[str] = ..., value: _Optional[str] = ...) -> None: ...
class LatestMessageEntry(_message.Message):
__slots__ = ["key", "value"]
KEY_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
key: str
value: str
def __init__(self, key: _Optional[str] = ..., value: _Optional[str] = ...) -> None: ...
class ActiveLoopEntry(_message.Message):
__slots__ = ["key", "value"]
KEY_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
key: str
value: str
def __init__(self, key: _Optional[str] = ..., value: _Optional[str] = ...) -> None: ...
class LatestActionEntry(_message.Message):
__slots__ = ["key", "value"]
KEY_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
key: str
value: str
def __init__(self, key: _Optional[str] = ..., value: _Optional[str] = ...) -> None: ...
CONVERSATION_ID_FIELD_NUMBER: _ClassVar[int]
SLOTS_FIELD_NUMBER: _ClassVar[int]
LATEST_MESSAGE_FIELD_NUMBER: _ClassVar[int]
LATEST_EVENT_TIME_FIELD_NUMBER: _ClassVar[int]
FOLLOWUP_ACTION_FIELD_NUMBER: _ClassVar[int]
PAUSED_FIELD_NUMBER: _ClassVar[int]
EVENTS_FIELD_NUMBER: _ClassVar[int]
LATEST_INPUT_CHANNEL_FIELD_NUMBER: _ClassVar[int]
ACTIVE_LOOP_FIELD_NUMBER: _ClassVar[int]
LATEST_ACTION_FIELD_NUMBER: _ClassVar[int]
conversation_id: str
slots: _containers.ScalarMap[str, str]
latest_message: _containers.ScalarMap[str, str]
latest_event_time: float
followup_action: str
paused: bool
events: _containers.RepeatedScalarFieldContainer[str]
latest_input_channel: str
active_loop: _containers.ScalarMap[str, str]
latest_action: _containers.ScalarMap[str, str]
def __init__(self, conversation_id: _Optional[str] = ..., slots: _Optional[_Mapping[str, str]] = ..., latest_message: _Optional[_Mapping[str, str]] = ..., latest_event_time: _Optional[float] = ..., followup_action: _Optional[str] = ..., paused: bool = ..., events: _Optional[_Iterable[str]] = ..., latest_input_channel: _Optional[str] = ..., active_loop: _Optional[_Mapping[str, str]] = ..., latest_action: _Optional[_Mapping[str, str]] = ...) -> None: ...

class Domain(_message.Message):
__slots__ = ["config", "session_config", "intents", "entities", "slots", "responses", "actions", "forms", "e2e_actions"]
class ConfigEntry(_message.Message):
__slots__ = ["key", "value"]
KEY_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
key: str
value: str
def __init__(self, key: _Optional[str] = ..., value: _Optional[str] = ...) -> None: ...
class SessionConfigEntry(_message.Message):
__slots__ = ["key", "value"]
KEY_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
key: str
value: str
def __init__(self, key: _Optional[str] = ..., value: _Optional[str] = ...) -> None: ...
class SlotsEntry(_message.Message):
__slots__ = ["key", "value"]
KEY_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
key: str
value: str
def __init__(self, key: _Optional[str] = ..., value: _Optional[str] = ...) -> None: ...
class ResponsesEntry(_message.Message):
__slots__ = ["key", "value"]
KEY_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
key: str
value: str
def __init__(self, key: _Optional[str] = ..., value: _Optional[str] = ...) -> None: ...
class FormsEntry(_message.Message):
__slots__ = ["key", "value"]
KEY_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
key: str
value: str
def __init__(self, key: _Optional[str] = ..., value: _Optional[str] = ...) -> None: ...
CONFIG_FIELD_NUMBER: _ClassVar[int]
SESSION_CONFIG_FIELD_NUMBER: _ClassVar[int]
INTENTS_FIELD_NUMBER: _ClassVar[int]
ENTITIES_FIELD_NUMBER: _ClassVar[int]
SLOTS_FIELD_NUMBER: _ClassVar[int]
RESPONSES_FIELD_NUMBER: _ClassVar[int]
ACTIONS_FIELD_NUMBER: _ClassVar[int]
FORMS_FIELD_NUMBER: _ClassVar[int]
E2E_ACTIONS_FIELD_NUMBER: _ClassVar[int]
config: _containers.ScalarMap[str, str]
session_config: _containers.ScalarMap[str, str]
intents: _containers.RepeatedScalarFieldContainer[str]
entities: _containers.RepeatedScalarFieldContainer[str]
slots: _containers.ScalarMap[str, str]
responses: _containers.ScalarMap[str, str]
actions: _containers.RepeatedScalarFieldContainer[str]
forms: _containers.ScalarMap[str, str]
e2e_actions: _containers.RepeatedScalarFieldContainer[str]
def __init__(self, config: _Optional[_Mapping[str, str]] = ..., session_config: _Optional[_Mapping[str, str]] = ..., intents: _Optional[_Iterable[str]] = ..., entities: _Optional[_Iterable[str]] = ..., slots: _Optional[_Mapping[str, str]] = ..., responses: _Optional[_Mapping[str, str]] = ..., actions: _Optional[_Iterable[str]] = ..., forms: _Optional[_Mapping[str, str]] = ..., e2e_actions: _Optional[_Iterable[str]] = ...) -> None: ...

class WebhookRequest(_message.Message):
__slots__ = ["next_action", "sender_id", "tracker", "domain", "version"]
NEXT_ACTION_FIELD_NUMBER: _ClassVar[int]
SENDER_ID_FIELD_NUMBER: _ClassVar[int]
TRACKER_FIELD_NUMBER: _ClassVar[int]
DOMAIN_FIELD_NUMBER: _ClassVar[int]
VERSION_FIELD_NUMBER: _ClassVar[int]
next_action: str
sender_id: str
tracker: Tracker
domain: Domain
version: str
def __init__(self, next_action: _Optional[str] = ..., sender_id: _Optional[str] = ..., tracker: _Optional[_Union[Tracker, _Mapping]] = ..., domain: _Optional[_Union[Domain, _Mapping]] = ..., version: _Optional[str] = ...) -> None: ...

class WebhookResponse(_message.Message):
__slots__ = ["events", "responses"]
EVENTS_FIELD_NUMBER: _ClassVar[int]
RESPONSES_FIELD_NUMBER: _ClassVar[int]
events: _containers.RepeatedCompositeFieldContainer[_any_pb2.Any]
responses: _containers.RepeatedCompositeFieldContainer[_any_pb2.Any]
def __init__(self, events: _Optional[_Iterable[_Union[_any_pb2.Any, _Mapping]]] = ..., responses: _Optional[_Iterable[_Union[_any_pb2.Any, _Mapping]]] = ...) -> None: ...
Loading

0 comments on commit dc988a2

Please sign in to comment.