Rasa 3.0 error socket.io

I’m trouble to run the service in version 3.0

image

of the original file I added only to the lines below

image image

below is the file socketChannel.py

import logging import warnings import uuid from sanic import Blueprint, response from sanic.request import Request from sanic.response import HTTPResponse from socketio import AsyncServer from typing import Optional, Text, Any, List, Dict, Iterable, Callable, Awaitable

from rasa.core.channels.channel import InputChannel from rasa.core.channels.channel import UserMessage, OutputChannel

logger = logging.getLogger(name)

class SocketBlueprint(Blueprint): def init(self, sio: AsyncServer, socketio_path, *args, **kwargs): self.sio = sio self.socketio_path = socketio_path super().init(*args, **kwargs)

def register(self, app, options) -> None:
    self.sio.attach(app, self.socketio_path)
    super().register(app, options)

class SocketIOOutput(OutputChannel): @classmethod def name(cls) → Text: return “socketio”

def __init__(self, sio, sid, bot_message_evt) -> None:
    self.sio = sio
    self.sid = sid
    self.bot_message_evt = bot_message_evt

async def _send_message(self, socket_id: Text, response: Any) -> None:
    """Sends a message to the recipient using the bot event."""

    await self.sio.emit(self.bot_message_evt, response, room=socket_id)

async def send_text_message(
    self, recipient_id: Text, text: Text, **kwargs: Any
) -> None:
    """Send a message through this channel."""

    await self._send_message(self.sid, {
        "text": text#, "metadata": {"linkTarget": "_self"}
    })

async def send_image_url(
    self, recipient_id: Text, image: Text, **kwargs: Any
) -> None:
    """Sends an image to the output"""

    message = {"attachment": {"type": "image", "payload": {"src": image}}}
    await self._send_message(self.sid, message)

async def send_text_with_buttons(
    self,
    recipient_id: Text,
    text: Text,
    buttons: List[Dict[Text, Any]],
    **kwargs: Any,
) -> None:
    """Sends buttons to the output."""

    message = {"text": text, "metadata": {"linkTarget": "_self"},
               "quick_replies": []}

    for button in buttons:
        b = {
                "content_type": "text",
                "title": button["title"]
            }

        if "metadata" in button:
            b["metadata"] = button["metadata"]

        if "type" in button:
            b["type"] = button["type"]

        if "payload" in button:
            b["payload"] = button["payload"]

        if "url" in button:
            b["url"] = button["url"]

        message["quick_replies"].append(b)

    await self._send_message(self.sid, message)

async def send_elements(
    self, recipient_id: Text, elements: Iterable[Dict[Text, Any]], **kwargs: Any
) -> None:
    """Sends elements to the output."""

    for element in elements:
        message = {
            "attachment": {
                "type": "template",
                "payload": {"template_type": "generic", "elements": element},
            }
        }

        await self._send_message(self.sid, message)

async def send_custom_json(
    self, recipient_id: Text, json_message: Dict[Text, Any], **kwargs: Any
) -> None:
    """Sends custom json to the output"""

    json_message.setdefault("room", self.sid)

    await self.sio.emit(self.bot_message_evt, **json_message)

async def send_attachment(
    self, recipient_id: Text, attachment: Dict[Text, Any], **kwargs: Any
) -> None:
    """Sends an attachment to the user."""
    await self._send_message(self.sid, {"attachment": attachment})

class SocketIOInput(InputChannel): “”“A socket.io input channel.”“”

@classmethod
def name(cls) -> Text:
    return "socketio"

@classmethod
def from_credentials(cls, credentials: Optional[Dict[Text, Any]]) -> InputChannel:
    credentials = credentials or {}
    return cls(
        credentials.get("user_message_evt", "user_uttered"),
        credentials.get("bot_message_evt", "bot_uttered"),
        credentials.get("namespace"),
        credentials.get("session_persistence", False),
        credentials.get("socketio_path", "/socket.io"),
    )

def __init__(
    self,
    user_message_evt: Text = "user_uttered",
    bot_message_evt: Text = "bot_uttered",
    namespace: Optional[Text] = None,
    session_persistence: bool = False,
    socketio_path: Optional[Text] = "/socket.io",
):
    self.bot_message_evt = bot_message_evt
    self.session_persistence = session_persistence
    self.user_message_evt = user_message_evt
    self.namespace = namespace
    self.socketio_path = socketio_path

def blueprint(
    self, on_new_message: Callable[[UserMessage], Awaitable[Any]]
) -> Blueprint:
    # Workaround so that socketio works with requests from other origins.
    # https://github.com/miguelgrinberg/python-socketio/issues/205#issuecomment-493769183
    sio = AsyncServer(async_mode="sanic", cors_allowed_origins=[])
    socketio_webhook = SocketBlueprint(
        sio, self.socketio_path, "socketio_webhook", __name__
    )

    @socketio_webhook.route("/", methods=["GET"])
    async def health(_: Request) -> HTTPResponse:
        return response.json({"status": "ok"})

    @sio.on("connect", namespace=self.namespace)
    async def connect(sid: Text, _) -> None:
        logger.debug(f"User {sid} connected to socketIO endpoint.")

    @sio.on("disconnect", namespace=self.namespace)
    async def disconnect(sid: Text) -> None:
        logger.debug(f"User {sid} disconnected from socketIO endpoint.")

    @sio.on("session_request", namespace=self.namespace)
    async def session_request(sid: Text, data: Optional[Dict]):
        if data is None:
            data = {}
        if "session_id" not in data or data["session_id"] is None:
            data["session_id"] = uuid.uuid4().hex
        await sio.emit("session_confirm", data["session_id"], room=sid)
        logger.debug(f"User {sid} connected to socketIO endpoint.")

    @sio.on(self.user_message_evt, namespace=self.namespace)
    async def handle_message(sid: Text, data: Dict) -> Any:
        output_channel = SocketIOOutput(sio, sid, self.bot_message_evt)
        
        if self.session_persistence:
            if not data.get("session_id"):
                warnings.warn(
                    "A message without a valid sender_id "
                    "was received. This message will be "
                    "ignored. Make sure to set a proper "
                    "session id using the "
                    "`session_request` socketIO event."
                )
                return

            sender_id = data["session_id"]
        else:
            sender_id = sid

        message = UserMessage(
            data["message"], output_channel,
            sender_id, input_channel=self.name(),
            metadata=data["customData"]
        )
        await on_new_message(message)

    return socketio_webhook

Can anyone help me

@Euler can you please check this post: Problem with websockets - #14 by nik202 and try to update the packages :slight_smile: . I hope this will solve your issue. If not please share the update and errors with me. Good Luck!

installing the 3 packages only changed the error description.

share python-enginio version?

I don’t know how to verify what you asked me for?

image

@Euler pip list and see the python-engineio ?

Is this is your current versions:

python-engineio==4.3.0
python-socketio==5.5.0

python-engineio==4.3.0 python-socketio==5.5.0 pytz==2021.3 PyYAML==6.0 rasa==3.0.2 rasa-sdk==3.0.2 redis==3.5.3 regex==2021.8.28 requests==2.25.1 requests-oauthlib==1.3.0 requests-toolbelt==0.9.1 rocketchat-API==1.16.0 rsa==4.8 ruamel.yaml==0.16.13 ruamel.yaml.clib==0.2.6 s3transfer==0.5.0 sanic==21.6.0 Sanic-Cors==1.0.0 sanic-jwt==1.7.0 sanic-plugin-toolkit==1.2.0 sanic-routing==0.7.0 scikit-learn==0.24.2 scipy==1.7.3 sentry-sdk==1.3.1 six==1.15.0 sklearn-crfsuite==0.3.6 slackclient==2.9.3 SQLAlchemy==1.4.28 tabulate==0.8.9 tarsafe==0.0.3 tensorboard==2.7.0 tensorboard-data-server==0.6.1 tensorboard-plugin-wit==1.8.0 tensorflow==2.6.1 tensorflow-addons==0.14.0 tensorflow-estimator==2.6.0 tensorflow-hub==0.12.0 tensorflow-probability==0.13.0 termcolor==1.1.0 terminaltables==3.1.10 threadpoolctl==3.0.0 toolz==0.11.2 tqdm==4.62.3 twilio==6.50.1 typeguard==2.13.3 typing-extensions==3.7.4.3 typing-utils==0.1.0 tzlocal==2.1 ujson==4.3.0 urllib3==1.26.7 wcwidth==0.2.5 webexteamssdk==1.6 websockets==10.1 Werkzeug==2.0.2 wrapt==1.12.1 yarl==1.7.2 zipp==3.6.0

@Euler strange ! did you see any other dependencies issues while downgrading these versions?

@Euler I am trying to run your version, and I will get back to you asap.

Thank you for your attention

@Euler

[Note: This proposed solution working on rasa and rasa-sdk 3.0.2 running on rasa/webchat [MacOS]]

python-engineio==4.3.0
python-socketio==5.5.0
rasa==3.0.2
rasa-sdk==3.0.2
sanic==21.6.0
Sanic-Cors==1.0.0
sanic-routing==0.7.0
sanic-jwt==1.7.0
sanic-plugin-toolkit==1.2.0
Sanic-Plugins-Framework==0.9.5
socketIO-client==0.7.2

I guess you need to install pip install sanic-plugins-framework==0.9.5

Do check this version or ref this requirementrequirements3.0.2.txt (3.0 KB)

@Euler I can confirm that it’s running on my machine:

Screenshot 2021-12-15 at 8.26.17 PM

@Euler I hope this will solve your issue and good luck!

@Euler check the version of Sanic-plugin-toolkit? is that matching with my suggested version? do check the dependencies issue please.

@Euler did you activate the environment?

sanic==20.12.4 Sanic-Cors==1.0.0 sanic-jwt==1.7.0 sanic-plugin-toolkit==1.2.0 Sanic-Plugins-Framework==0.9.5 sanic-routing==0.7.0 scikit-learn==0.24.2 scipy==1.7.3

image

@Euler check sanic version should be sanic==21.6.0, please take care of version and you will be able to run it with ease trust me or please ref the requirement3.0.2.txt file.

@Euler What is your front-end?, I have tested on using rasa/webchat.

@Euler command used: rasa run -m models --enable-api --cors "*" --debug

packages.txt (2.9 KB)

yes, I’m using webchat

@Euler check again the sanic version its should be sanic==21.6.0, in your packages.txt is showing sanic==20.12.4

@Euler you need to solve this dependence issue try use --use-deprecated=legacy-resolver after

pip install sanic==21.6.0 --use-deprecated=legacy-resolver