# RiveScript-Python
#
# This code is released under the MIT License.
# See the "LICENSE" file for more information.
#
# https://www.rivescript.com/
# Python3 compat
from __future__ import print_function, unicode_literals
from six import text_type
[docs]class PyRiveObjects(object):
"""A RiveScript object handler for Python code.
This class provides built-in support for your RiveScript documents to
include and execute object macros written in Python. For example::
> object base64 python
import base64 as b64
return b64.b64encode(" ".join(args))
< object
+ encode * in base64
- OK: <call>base64 <star></call>
Python object macros receive these two parameters:
* ``rs`` (RiveScript): The reference to the parent RiveScript instance.
* ``args`` ([]str): A list of argument words passed to your object.
Python support is on by default. To turn it off, just unset the Python
language handler on your RiveScript object::
rs.set_handler("python", None)
"""
_objects = {} # The cache of objects loaded
def __init__(self):
pass
[docs] def load(self, name, code):
"""Prepare a Python code object given by the RiveScript interpreter.
:param str name: The name of the Python object macro.
:param []str code: The Python source code for the object macro.
"""
# We need to make a dynamic Python method.
source = "def RSOBJ(rs, args):\n"
for line in code:
source = source + "\t" + line + "\n"
source += "self._objects[name] = RSOBJ\n"
try:
exec(source)
# self._objects[name] = RSOBJ
except Exception as e:
print("Failed to load code from object", name)
print("The error given was: ", e)
[docs] def call(self, rs, name, user, fields):
"""Invoke a previously loaded object.
:param RiveScript rs: the parent RiveScript instance.
:param str name: The name of the object macro to be called.
:param str user: The user ID invoking the object macro.
:param []str fields: Array of words sent as the object's arguments.
:return str: The output of the object macro.
"""
# Call the dynamic method.
if name not in self._objects:
return '[ERR: Object Not Found]'
func = self._objects[name]
reply = ''
try:
reply = func(rs, fields)
if reply is None:
reply = ''
except Exception as e:
raise PythonObjectError("Error executing Python object: " + str(e))
return text_type(reply)
[docs]class PythonObjectError(Exception):
pass