Skip to content
This repository has been archived by the owner on Aug 22, 2019. It is now read-only.

Commit

Permalink
Merge pull request #645 from RasaHQ/model-pull
Browse files Browse the repository at this point in the history
Model server queries
  • Loading branch information
tmbo committed Jul 31, 2018
2 parents bba07d4 + 348a84c commit a08e150
Show file tree
Hide file tree
Showing 12 changed files with 489 additions and 91 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ Added
- new default action ActionDefaultFallback
- event streaming to a ``RabbitMQ`` message broker using ``Pika``
- docs section on event brokers
- ``Agent()`` class supports a ``model_server`` ``EndpointConfig``, which it regularly queries to fetch dialogue models
- this can be used with ``rasa_core.server`` with the ``--endpoint`` option (the key for this the model server config is ``model``)
- docs on model fetching from a URL

Changed
-------
Expand Down
1 change: 1 addition & 0 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pytest-cov==2.5.1
pytest_localserver==0.4.1
treq==17.8.0
freezegun==0.3.10
responses==0.9.0

# other
matplotlib==2.2.2
Expand Down
210 changes: 210 additions & 0 deletions docs/http.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,216 @@
HTTP API
========

.. note::

Before you can use the server, you need to define a domain, create training
data, and train a model. You can then use the trained model for remote code
execution! See :ref:`tutorial_basics` for an introduction.


The HTTP api exists to make it easy for non-python projects to use Rasa Core.

Overview
--------
The general idea is to run the actions within your code (arbitrary language),
instead of python. To do this, Rasa Core will start up a web server where you
need to pass the user messages to. Rasa Core on the other side will tell you
which actions you need to run. After running these actions, you need to notify
the framework that you executed them and tell the model about any update of the
internal dialogue state for that user. All of these interactions are done using
a HTTP REST interface.

You can also use a single, simpler endpoint called `/respond`, which just returns
all of the messages your bot should send back to the user. In general, this only
works if all of your actions are simple utterances (messages sent to the user).
It can make use of custom actions, but then these *have* to be implemented in
python and executed on the machine that runs the server.

To activate the remote mode, include

.. code-block:: yaml
action_factory: remote
within your ``domain.yml`` (you can find an example in
``examples/remote/concert_domain_remote.yml``).

.. note::

If started as a HTTP server, Rasa Core will not handle output or input
channels for you. That means you need to retrieve messages from the input
channel (e.g. facebook messenger) and send messages to the user on your end.

Hence, you also do not need to define any utterances in your domain yaml.
Just list all the actions you need.

Running the server
------------------
You can run a simple http server that handles requests using your
models with

.. code-block:: bash
$ python -m rasa_core.server -d examples/babi/models/policy/current -u examples/babi/models/nlu/current_py2 -o out.log
The different parameters are:

- ``-d``, which is the path to the Rasa Core model.
- ``-u``, which is the path to the Rasa NLU model.
- ``-o``, which is the path to the log file.

Fetching models from a server
-----------------------------
You can also configure the http server to fetch models from another URL:

.. code-block:: bash
$ python -m rasa_core.server -d examples/babi/models/policy/current -u examples/babi/models/nlu/current_py2 --endpoints my_endpoints.yaml -o out.log
The model server is specified in an ``EndpointConfig`` file (``my_endpoints
.yaml``), where you specify the server URL Rasa Core regularly queries for
zipped Rasa Core models

.. code-block:: yaml
model:
url: http://my-server.com/models/default_core@latest
.. note::

Your model server must provide zipped Rasa Core models, and have
``{"ETag": <model_hash_string>}`` as one of its headers.

Rasa Core sends requests to your model server with an ``If-None-Match``
header that contains the current model hash. If your model server can
provide a model with a different hash from the one you sent, it should send it
in as a zip file with an ``ETag`` header containing the new hash. If not, Rasa
Core expects an empty response with a ``204`` status code.

An example request Rasa Core might make to your model server looks like this

.. code-block:: bash
$ curl --header "If-None-Match: d41d8cd98f00b204e9800998ecf8427e" http://my-server.com/models/default_core@latest
.. _http_start_conversation:

Starting a conversation
-----------------------
You need to do a ``POST`` to the ``/conversation/<sender_id>/parse`` endpoint.
``<sender_id>`` is the conversation id (e.g. ``default`` if you just have one
user, or the facebook user id or any other identifier).

.. code-block:: bash
$ curl -XPOST localhost:5005/conversations/default/parse -d '{"query":"hello there"}'
The server will respond with the next action you should take:

.. code-block:: javascript
{
"next_action": "utter_ask_howcanhelp",
"tracker": {
"slots": {
"info": null,
"cuisine": null,
"people": null,
"matches": null,
"price": null,
"location": null
},
"sender_id": "default",
"latest_message": {
...
}
}
}
You now need to execute the action ``utter_ask_howcanhelp`` on your end. This
might include sending a message to the output channel (e.g. back to facebook).

After you finished running the mentioned action, you need to notify Rasa Core
about that:

.. code-block:: bash
$ curl -XPOST http://localhost:5005/conversations/default/continue -d \
'{"executed_action": "utter_ask_howcanhelp", "events": []}'
Here the API should respond with:

.. code-block:: javascript
{
"next_action":"action_listen",
"tracker": {
"slots": {
"info": null,
"cuisine": null,
"people": null,
"matches": null,
"price": null,
"location": null
},
"sender_id": "default",
"latest_message": {
...
}
}
}
This response tells you to wait for the next user message. You should not call
the continue endpoint after you received a response containing ``action_listen``
as the next action. Instead, wait for the next user message and call
``/conversations/default/parse`` again followed by subsequent
calls to ``/conversations/default/continue`` until you get ``action_listen``
again.

Events
------
Events allow you to modify the internal state of the dialogue. This information
will be used to predict the next action. E.g. you can set slots (to store
information about the user) or restart the conversation.

You can return multiple events as part of your query, e.g.:

.. code-block:: bash
$ curl -XPOST http://localhost:5005/conversations/default/continue -d \
'{"executed_action": "search_restaurants", "events": [{"event": "slot", "name": "cuisine", "value": "mexican"}, {"event": "slot", "name": "people", "value": 5}]}'
Here is a list of all available events you can append to the ``events`` array in
your call to ``/conversation/<sender_id>/continue``.

Set a slot
::::::::::

:name: ``slot``
:Examples: ``"events": [{"event": "slot", "name": "cuisine", "value": "mexican"}]``
:Description:
Will set the value of the slot to the passed one. The value you set should
be reasonable given the :ref:`slots type <slot_types>`.

Restart
:::::::

:name: ``restart``
:Examples: ``"events": [{"event": "restart"}]``
:Description:
Restarts the conversation and resets all slots and past actions.

Reset Slots
:::::::::::

:name: ``reset_slots``
:Examples: ``"events": [{"event": "reset_slots"}]``
:Description:
Resets all slots to their initial value.


Endpoints
---------

.. http:post:: /conversations/(str:sender_id)/parse
:synopsis: Returns posts by the specified tag for the user
Expand Down
Loading

0 comments on commit a08e150

Please sign in to comment.