Skip to main content

Minette for Python

Downloads

Minette is a minimal and extensible chatbot framework. It is extremely easy to develop and the architecture preventing to be spaghetti code enables you to scale up to complex chatbot.

🇯🇵日本語のREADMEはこちら

🎉 version 0.4.2 is available

  • 0.4.3 Sep 5, 2020

    • Enable to give shared objects to dialogs from main logic 👉 PR #38
    • Add argument tagger_max_length to constructor of Minette 👉 PR #42
    • Support returning generator from Tagger 👉 PR #35
  • 0.4.2 Aug 26, 2020

  • 0.4.1 Aug 7, 2020

🚀 Quick start

Running echo bot is extremely easy.

from minette import Minette, EchoDialogService

# Create chatbot instance using EchoDialogService
bot = Minette(default_dialog_service=EchoDialogService)

# Send and receive messages
while True:
    req = input("user> ")
    res = bot.chat(req)
    for message in res.messages:
        print("minette> " + message.text)
$ python echo.py
user> hello
minette> You said: hello

Creating LINE bot is also super easy.

from flask import Flask, request
from minette import Minette, EchoDialogService
from minette.adapter.lineadapter import LineAdapter

# Create chatbot wrapped by LINE adapter
bot = LineAdapter(default_dialog_service=EchoDialogService)

# Create web server and its request handler
app = Flask(__name__)

@app.route("/", methods=["POST"])
def handle_webhook():
    bot.handle_http_request(request.data, request.headers)
    return "ok"

# Start web server
app.run(port=12345)

See also examples.md to get more examples.

📦 Installation

$ pip install minette

✅ Supported Platforms

Python 3.5 or higher is supported. Mainly developed using Python 3.7.7 on Mac OSX.

Messaging Service

  • LINE
  • Clova
  • Symphony

You can connect to other messaging services by extending minette.Adapter.

Database

  • SQLite
  • Azure SQL Database
  • Azure Table Storage
  • MySQL (Tested on 8.0.13)

You can use other databases you like by extending the classes in minette.datastore package. (Context / User / MessageLog) Or, maybe you can use supported databases by SQLAlchemy by just setting connection string for it.

Tagger

  • MeCab
  • Janome

You can use other morphological engines including cloud services and for other languages by extending minette.Tagger. To setup and use MeCab and Janome Tagger, see the Appendix at the bottom of this page.

📚 Dependencies

(Required)

  • pytz >= 2018.9
  • schedule >= 0.6.0

(Optional)

  • line-bot-sdk >= 1.12.1 (for LINE)
  • clova-cek-sdk >= 1.1.1
  • sym-api-client-python >= 0.1.16 (for Symphony)
  • pyodbc >= 4.0.26 (for Azure SQL Databsae)
  • azure-cosmosdb-table >= 1.0.5 (for Azure Table Storage)
  • MySQLdb (for MySQL)
  • SQLAlchemy (for SQLAlchemyStores)
  • mecab-python3 >= 1.0.1 (for MeCabTagger)
  • Janome >= 0.3.8 (for Janome Tagger)

✨ Features

To create a bot, developers just implement DialogService(s) and DialogRouter.

  • DialogService: process the application logic and compose the response message to the user
  • DialogRouter: extract intents and entities from request message to route the proper DialogService

Architecture

Any other common operations (e.g. context management) are done by framework.

Context management

Minette provides a data store that enables your bot to continue conversasion accross the requests like HTTP Session.

Set data

# to use context data at the next request, set `True` to `context.topic.keep_on` in DialogService
context.data["pizza_name"] = "Seafood Pizza"
context.topic.keep_on = True

Get data

pizza_name = context.data["pizza_name"]

User management

Users are identified by the Channel (e.g LINE, FB Messanger etc) and the UserID for the Channel. Each users are automatically registered at the first access and each changes for user is saved automatically.

# framework saves the updated user info automatically and keep them until the app delete them
request.user.nickname = "uezo"
request.user.data["horoscope"] = "cancer"

Natural language analyzing

Taggers are the components for analyzing the text of request and the result will be automatically set to request object. Minette has 2 built-in taggers for Japanese - MeCabTagger and JanomeTagger.

To use JanomeTagger, at first install Janome: a pure python Japanese morphological analyzer.

$ pip install janome

Check tagger like below.

>>> from minette.tagger.janometagger import JanomeTagger
>>> tagger = JanomeTagger()
>>> words = tagger.parse("今日は良い天気です")
>>> words[0].to_dict()
{'surface': '今日', 'part': '名詞', 'part_detail1': '副詞可能', 'part_detail2': '', 'part_detail3': '', 'stem_type': '', 'stem_form': '', 'word': '今日', 'kana': 'キョウ', 'pronunciation': 'キョー'}

Sample usage in DialogService is here.

# bot = Minette(tagger=JanomeTagger) <- Note: create bot with JanomeTagger

def process_request(self, request, context, connection):
    # result of parsing morph is set in `request.words` automatically
    nouns = [w.surface for w in request.words if w.part == "名詞"]

Task scheduler

Built-in task scheduler is ready-to-use. Your chatbot can run periodic jobs without cron.

class MyTask(Task):
    # implement periodic task in `do` method
    def do(self, arg1, arg2):
        # The Logger of scheduler is available in each tasks
        self.logger.info("Task started!: {} / {}".format(arg1, arg2))

# Create Scheculer
sc = Scheduler()
# Register the task. This task runs every 3 seconds
sc.every_seconds(MyTask, seconds=3, arg1="val1", arg2="val2")
# Start the scheduler
sc.start()

Message Log

Request, response and context at each turns are stored as Message Log. It provides you the very useful information to debug and improve your chatbot.

Testing Dialogs

Minette provides a helper to test dialogs. This is an example using pytest.

  • channel_user_id for each test cases(functions) is set to request automatically.
  • chat method takes arguments for Message. This enables you bot.chat("hello", intent="HelloIntent") instead of bot.chat(Message(text="hello", intent="HelloIntent")) to make your test code simple.
  • Response from chat has text attribute that equals to response.messages[0].text.
import pytest
from minette import Message, DialogService, Priority, Payload
from minette.test.helper import MinetteForTest

# dialogs to test
class FooDialog(DialogService):
    def compose_response(self, request, context, connetion):
        return "foo:" + request.text

class BarDialog(DialogService):
    def compose_response(self, request, context, connetion):
        context.topic.keep_on = True
        return "bar:" + request.text

class PayloadDialog(DialogService):
    def compose_response(self, request, context, connetion):
        return "payload:" + str(request.payloads[0].content)

# bot created for each test functions
@pytest.fixture(scope="function")
def bot():
    # use MinetteForTest instead of Minette
    return MinetteForTest(
        intent_resolver={
            "FooIntent": FooDialog,
            "BarIntent": BarDialog,
            "PayloadIntent": PayloadDialog
        },
    )

# test cases function using bot
def test_example(bot):
    # trigger intent
    assert bot.chat("hello", intent="FooIntent").text == "foo:hello"
    # empty response without intent
    assert bot.chat("hello").text == ""
    # trigger other intent
    assert bot.chat("hello", intent="BarIntent").text == "bar:hello"
    # context and topic is kept by dialog service
    assert bot.chat("hi", intent="FooIntent").text == "bar:hi"
    assert bot.chat("yo").text == "bar:yo"
    # update topic by higher priority request
    assert bot.chat("hello", intent="FooIntent", intent_priority=Priority.High).text == "foo:hello"

def test_payload(bot):
    # use Message to test your dialog with payloads, channel_message and so on
    assert bot.chat(Message(
        intent="PayloadIntent",
        type="data",
        text="hello",
        payloads=[Payload(content={"key1": "value1"})]
    )).text == "payload:" + str({"key1": "value1"})

💝 Contribution

See the Contribution Guideline

⚖️ License

This software is licensed under the Apache v2 License.

Appendix1. Setup MeCab Tagger

Installing MeCab

  • Ubuntu 16.04
$ sudo apt-get install mecab libmecab-dev mecab-ipadic
$ sudo apt-get install mecab-ipadic-utf8
  • Mac OSX
$ brew install mecab mecab-ipadic git curl xz

Installing python binding

$ pip install mecab-python3==1.0.1

Version 0.996.1 has a bug(?) so we strongly recommend to use version 0.7. Fixed at current version

Usase

from minette.tagger.mecabtagger import MeCabTagger
bot = Minette(
    tagger=MeCabTagger
)

Appendix2. Migration from version 0.3

  • Some packages are deprecated. All standard classes can be imported from minette.
  • The way to create instance of Minette is changed. (just call constructor)
  • Session is renamed to Context. The arguments named session is also changed.
  • minette.user.User#save() is deleted. Create UserStore and call save(user) instead.
  • SessionStore -> ContextStore, UserRepository -> UserStore, MessageLogger -> MessageLogStore
  • HTTP request handler method of LineAdapter is changed to handle_http_request.

If you need version 0.3 install from github.

$ pip install git+https://github.com/uezo/minette-python.git@v0.3

Metadata

Release files for minette 0.4.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for minette 0.4.3
File Size Uploaded
minette-0.4.3.tar.gz 36.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for minette 0.4.3
File Interpreter ABI Platform
minette-0.4.3-py3-none-any.whl Python 3 none any Details

Total release size: 88.6 kB

Release files / minette-0.4.3.tar.gz

Download URL minette-0.4.3.tar.gz
Size 36.7 kB
Tags Source
SHA-256 checksum
How to use checksums
cdf10d05d47ce074b25bec619ebbc76713f9578ace9f7a3ca834ce2ebccc1f3e
BLAKE2b-256 checksum
How to use checksums
67c4c1e3b4043c53c3b2b1efe9405cc44a89704166957d1df49fb5efe557a957
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.48.2 CPython/3.7.7

Release files / minette-0.4.3-py3-none-any.whl

Download URL minette-0.4.3-py3-none-any.whl
Size 51.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b74ac66c3f9e6040957def3d5cc028810915ac44fa778f2ce612691c44f6d507
BLAKE2b-256 checksum
How to use checksums
9122f0c96e6e1fc8a050356ac7f364adc1b096dce67262870c6f1b200611ee0a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.48.2 CPython/3.7.7

Release history Release notifications | RSS feed

This release

0.4.3 This release

2 release files

0.4.2

2 release files

0.4.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page