Skip to content

Commit

Permalink
2.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
orlnub123 committed Mar 20, 2018
1 parent e761187 commit a1d29a3
Show file tree
Hide file tree
Showing 16 changed files with 920 additions and 142 deletions.
2 changes: 1 addition & 1 deletion LICENSE.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2017 orlnub123
Copyright (c) 2017-2018 orlnub123

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
104 changes: 82 additions & 22 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ First import the package:
import cleverbot
If you have the asynchronous dependencies and want to use Cleverbot
asynchronously import it as below instead:

.. code:: py
from cleverbot import async_ as cleverbot
Then initialize Cleverbot with your API key and optionally a cleverbot state
and or timeout:

Expand All @@ -72,48 +79,59 @@ and or timeout:
The cleverbot state is the encoded state of the conversation that you get from
talking to Cleverbot and includes the whole conversation history.

If you have the asynchronous dependencies and want to use Cleverbot
asynchronously import ``cleverbot.async_`` and initialize Cleverbot from
``cleverbot.async_.Cleverbot`` instead. The only differences are that ``say``
is a coroutine and that you can pass an event loop to Cleverbot with a ``loop``
keyword argument.
If you're using Cleverbot asynchronously you can also give an event loop to
Cleverbot with a ``loop`` keyword argument

--------------

You can now start talking to Cleverbot.

Get the reply from the request:
Talk straight to Cleverbot:

.. code:: py
reply = cb.say("Hello")
Or alternatively get it later:

.. code:: py
cb.say("Hello")
reply = cb.output
You can also pass in keyword arguments such as ``cs`` to change the
You can pass in keyword arguments to ``say`` such as ``cs`` to change the
conversation, ``vtext`` to change the current conversation's history, or even
``cb_settings_tweak`` to change Cleverbot's mood. Read the "Parameters" section
of `the official Cleverbot API docs <https://www.cleverbot.com/api/howto/>`_
for more information.

Alternatively, start a new conversation and talk from it:

.. code:: py
convo = cb.conversation()
reply = convo.say("Hello")
Conversations are like mini Cleverbots so you can pass in anything that
Cleverbot takes as keyword arguments including ``key``. The values you don't
pass in excluding the cleverbot state will be taken from the originating
Cleverbot.

Normally conversations get saved in ``cb.conversations`` as a list but if you
want to manage them more easily you can pass in a name as the first argument to
every conversation you create which will turn ``cb.conversations`` into a
dictionary with the name as the key and the conversation as the value. Trying
to mix both named and nameless conversations will result in an error.

``say`` is a coroutine for both Cleverbot and its conversations if you're
running asynchronously.

--------------

If something goes wrong with the request, such as an invalid API key, an
``APIError`` will be raised containing the error message or, if you've defined
a timeout and you don't get a reply within the defined amount of seconds you'll
If something goes wrong with the request such as an invalid API key an
``APIError`` will be raised containing the error message or if you've defined
a timeout and don't get a reply within the defined amount of seconds you'll
get a ``Timeout``.

As an example:

``cleverbot.errors.APIError: Missing or invalid API key or POST request, please
visit www.cleverbot.com/api``

You can get the error message and additionally the HTTP status from the error
You can get the error message and the HTTP status from the error
like so:

.. code:: py
Expand All @@ -131,26 +149,68 @@ it to catch every Cleverbot related error.

--------------

To access the data gained from the conversations you can either get them from
an attribute as shown previously or directly get them from ``cb.data``:
To access the data gained from talking straight to Cleverbot or from talking in
a conversation you can either get it from an attribute as shown previously or
directly get it from the ``data`` dictionary:

.. code:: py
cb.conversation_id == cb.data['conversation_id']
convo.conversation_id == convo.data['conversation_id']
Note that every attribute except for cs (i.e., the cleverbot state) is
Note that every attribute except for ``cs`` (i.e. the cleverbot state) is
read-only and will get shadowed if you set it to something.

For a list of all of the data and their descriptions go to the "JSON Reply"
section in `the official Cleverbot API docs
<https://www.cleverbot.com/api/howto/>`_.

To reset the data you can simply do the following:
To reset Cleverbot's and all of its conversations' data you can simply do the
following:

.. code:: py
cb.reset()
To only reset a single conversation's data use ``reset`` on the conversation
instead:

.. code:: py
convo.reset()
Resetting won't delete any conversations so you'll be able to reuse them.

--------------

If you want to save the current state of Cleverbot and all of its conversations
you can use ``cb.save``:

.. code:: py
with open('cleverbot.txt', 'wb') as file:
cb.save(file)
This saves the key and timeout you've given to Cleverbot and its conversations
and also the current cleverbot state of each.

In order to load and recreate the previously saved state as a new Cleverbot
instance use ``cleverbot.load``:

.. code:: py
with open('cleverbot.txt', 'rb') as file:
cb = cleverbot.load(file)
To only load the conversations use ``cb.load``:

.. code:: py
with open('cleverbot.txt', 'rb') as file:
cb.load(file)
Loading conversations will delete the old ones.

--------------

When you're done with the current instance of Cleverbot, close Cleverbot's
Expand Down
4 changes: 2 additions & 2 deletions cleverbot/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = '2.0.1'
__version__ = '2.1.0'

from .cleverbot import Cleverbot
from .cleverbot import Cleverbot, load
from .errors import CleverbotError, APIError, DecodeError, Timeout
37 changes: 0 additions & 37 deletions cleverbot/abc.py

This file was deleted.

3 changes: 2 additions & 1 deletion cleverbot/async_/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
from .cleverbot import Cleverbot
from .cleverbot import Cleverbot, load
from .. import __version__, CleverbotError, APIError, DecodeError, Timeout
96 changes: 63 additions & 33 deletions cleverbot/async_/cleverbot.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,14 @@
import asyncio
import pickle

import aiohttp

from .. import __version__
from ..abc import CleverbotBase
from ..base import CleverbotBase, ConversationBase
from ..errors import APIError, DecodeError, Timeout


class Cleverbot(CleverbotBase):
"""An asynchronous Cleverbot API wrapper."""

def __init__(self, key, *, cs=None, timeout=None, loop=None):
"""Initialize Cleverbot with the given arguments.
Arguments:
key: The key argument is always required. It is your API key.
cs: The cs argument stands for "cleverbot state". It is the encoded
state of the conversation so far and includes the whole
conversation history up to that point.
timeout: How many seconds to wait for the API to send data before
giving up and raising an error.
loop: The event loop used for the asynchronous requests.
"""
self.key = key
self.data = {}
if cs is not None:
self.data['cs'] = cs
self.timeout = timeout
loop = asyncio.get_event_loop() if loop is None else loop
self.session = aiohttp.ClientSession(loop=loop)
class SayMixin:

@asyncio.coroutine
def say(self, input=None, **kwargs):
Expand All @@ -44,13 +24,6 @@ def say(self, input=None, **kwargs):
Raises:
APIError: A Cleverbot API error occurred.
Status codes:
401: Unauthorised due to invalid API key.
404: API not found.
413: Request too large if you send a request over 64Kb.
502 or 504: Unable to get reply from API server, please
contact us.
503: Too many requests from a single IP address or API key.
DecodeError: An error occurred while reading the reply.
Timeout: The request timed out.
"""
Expand Down Expand Up @@ -86,10 +59,67 @@ def say(self, input=None, **kwargs):
else:
if reply.status == 200:
self.data = data
return data['output']
return data.get('output')
else:
raise APIError(data['error'], data['status'])
raise APIError(data.get('error'), data.get('status'))


class Cleverbot(SayMixin, CleverbotBase):
"""An asynchronous Cleverbot API wrapper."""

def __init__(self, *args, loop=None, **kwargs):
"""Initialize Cleverbot with the given arguments.
Arguments:
key: The key argument is always required. It is your API key.
cs: The cs argument stands for "cleverbot state". It is the encoded
state of the conversation so far and includes the whole
conversation history up to that point.
timeout: How many seconds to wait for the API to respond before
giving up and raising an error.
loop: The event loop used for the asynchronous requests.
"""
super().__init__(*args, **kwargs)
loop = asyncio.get_event_loop() if loop is None else loop
self.session = aiohttp.ClientSession(loop=loop)

def conversation(self, name=None, **kwargs):
"""Make a new conversation.
Arguments:
name: The key for the dictionary the conversation will be stored as
in conversations. If None the conversation will be stored as a
list instead. Mixing both types results in an error.
**kwargs: Keyword arguments to pass into the new conversation.
These accept the same arguments as Cleverbot.
Returns:
The new conversation.
"""
convo = Conversation(self, **kwargs)
super().conversation(name, convo)
return convo

def close(self):
"""Close the connection to the API."""
"""Close Cleverbot's connection to the API."""
self.session.close()


class Conversation(SayMixin, ConversationBase):
pass


def load(file):
"""Load and return the previously saved Cleverbot with its conversations.
Arguments:
file: The file object to load Cleverbot and its conversations from.
Returns:
A new Cleverbot instance.
"""
cleverbot_kwargs, convos = pickle.load(file)
cleverbot = Cleverbot(**cleverbot_kwargs)
for convo_kwargs in convos:
cleverbot.conversation(**convo_kwargs)
return cleverbot
Loading

0 comments on commit a1d29a3

Please sign in to comment.