Package: minette
Minette for PythonMinette 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 available0.4.3 Sep 5, 2020Enable to give shared objects to dialogs from main logic 👉PR #38Add argumenttagger_max_lengthto constructor of Minette 👉PR #42Support returning generator from Tagger 👉PR #350.4.2 Aug 26, 2020SupportJanome 0.40.4.1 Aug 7, 2020SQLAlchemy is supported (experimental). See alsoexamples/todo.py🚀 Quick startRunning echo bot is extremely easy.fromminetteimportMinette,EchoDialogService# Create chatbot instance using EchoDialogServicebot=Minette(default_dialog_service=EchoDialogService)# Send and receive messageswhileTrue:req=input("user> ")res=bot.chat(req)formessageinres.messages:print("minette> "+message.text)$ python echo.py
user> hello
minette> You said: helloCreating LINE bot is also super easy.fromflaskimportFlask,requestfromminetteimportMinette,EchoDialogServicefromminette.adapter.lineadapterimportLineAdapter# Create chatbot wrapped by LINE adapterbot=LineAdapter(default_dialog_service=EchoDialogService)# Create web server and its request handlerapp=Flask(__name__)@app.route("/",methods=["POST"])defhandle_webhook():bot.handle_http_request(request.data,request.headers)return"ok"# Start web serverapp.run(port=12345)See alsoexamples.mdto get more examples.📦 Installation$ pip install minette✅ Supported PlatformsPython 3.5 or higher is supported. Mainly developed using Python 3.7.7 on Mac OSX.Messaging ServiceLINEClovaSymphonyYou can connect to other messaging services by extendingminette.Adapter.DatabaseSQLiteAzure SQL DatabaseAzure Table StorageMySQL (Tested on 8.0.13)You can use other databases you like by extending the classes inminette.datastorepackage. (Context / User / MessageLog)
Or, maybe you can use supported databases by SQLAlchemy by just setting connection string for it.TaggerMeCabJanomeYou can use other morphological engines including cloud services and for other languages by extendingminette.Tagger.
To setup and use MeCab and Janome Tagger, see the Appendix at the bottom of this page.📚 Dependencies(Required)pytz >= 2018.9schedule >= 0.6.0(Optional)line-bot-sdk >= 1.12.1 (for LINE)clova-cek-sdk >= 1.1.1sym-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)✨ FeaturesTo create a bot, developers just implementDialogService(s)andDialogRouter.DialogService: process the application logic and compose the response message to the userDialogRouter: extract intents and entities from request message to route the proper DialogServiceAny other common operations (e.g. context management) are done by framework.Context managementMinette 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 DialogServicecontext.data["pizza_name"]="Seafood Pizza"context.topic.keep_on=TrueGet datapizza_name=context.data["pizza_name"]User managementUsers 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 themrequest.user.nickname="uezo"request.user.data["horoscope"]="cancer"Natural language analyzingTaggers 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.$pipinstalljanomeCheck tagger like below.>>>fromminette.tagger.janometaggerimportJanomeTagger>>>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 inDialogServiceis here.# bot = Minette(tagger=JanomeTagger) <- Note: create bot with JanomeTaggerdefprocess_request(self,request,context,connection):# result of parsing morph is set in `request.words` automaticallynouns=[w.surfaceforwinrequest.wordsifw.part=="名詞"]Task schedulerBuilt-in task scheduler is ready-to-use. Your chatbot can run periodic jobs without cron.classMyTask(Task):# implement periodic task in `do` methoddefdo(self,arg1,arg2):# The Logger of scheduler is available in each tasksself.logger.info("Task started!:{}/{}".format(arg1,arg2))# Create Scheculersc=Scheduler()# Register the task. This task runs every 3 secondssc.every_seconds(MyTask,seconds=3,arg1="val1",arg2="val2")# Start the schedulersc.start()Message LogRequest, 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 DialogsMinette provides a helper to test dialogs. This is an example usingpytest.channel_user_idfor each test cases(functions) is set to request automatically.chatmethod takes arguments forMessage. This enables youbot.chat("hello", intent="HelloIntent")instead ofbot.chat(Message(text="hello", intent="HelloIntent"))to make your test code simple.Response fromchathastextattribute that equals toresponse.messages[0].text.importpytestfromminetteimportMessage,DialogService,Priority,Payloadfromminette.test.helperimportMinetteForTest# dialogs to testclassFooDialog(DialogService):defcompose_response(self,request,context,connetion):return"foo:"+request.textclassBarDialog(DialogService):defcompose_response(self,request,context,connetion):context.topic.keep_on=Truereturn"bar:"+request.textclassPayloadDialog(DialogService):defcompose_response(self,request,context,connetion):return"payload:"+str(request.payloads[0].content)# bot created for each test functions@pytest.fixture(scope="function")defbot():# use MinetteForTest instead of MinettereturnMinetteForTest(intent_resolver={"FooIntent":FooDialog,"BarIntent":BarDialog,"PayloadIntent":PayloadDialog},)# test cases function using botdeftest_example(bot):# trigger intentassertbot.chat("hello",intent="FooIntent").text=="foo:hello"# empty response without intentassertbot.chat("hello").text==""# trigger other intentassertbot.chat("hello",intent="BarIntent").text=="bar:hello"# context and topic is kept by dialog serviceassertbot.chat("hi",intent="FooIntent").text=="bar:hi"assertbot.chat("yo").text=="bar:yo"# update topic by higher priority requestassertbot.chat("hello",intent="FooIntent",intent_priority=Priority.High).text=="foo:hello"deftest_payload(bot):# use Message to test your dialog with payloads, channel_message and so onassertbot.chat(Message(intent="PayloadIntent",type="data",text="hello",payloads=[Payload(content={"key1":"value1"})])).text=="payload:"+str({"key1":"value1"})💝 ContributionSee theContribution Guideline⚖️ LicenseThis software is licensed under the Apache v2 License.Appendix1. Setup MeCab TaggerInstalling MeCabUbuntu 16.04$ sudo apt-get install mecab libmecab-dev mecab-ipadic
$ sudo apt-get install mecab-ipadic-utf8Mac OSX$ brew install mecab mecab-ipadic git curl xzInstalling python binding$ pip install mecab-python3==1.0.1Version 0.996.1 has a bug(?) so we strongly recommend to use version 0.7.Fixed at current versionUsasefromminette.tagger.mecabtaggerimportMeCabTaggerbot=Minette(tagger=MeCabTagger)Appendix2. Migration from version 0.3Some packages are deprecated. All standard classes can be imported fromminette.The way to create instance ofMinetteis changed. (just call constructor)Sessionis renamed toContext. The arguments namedsessionis also changed.minette.user.User#save()is deleted. CreateUserStoreand callsave(user)instead.SessionStore->ContextStore,UserRepository->UserStore,MessageLogger->MessageLogStoreHTTP request handler method ofLineAdapteris changed tohandle_http_request.If you need version 0.3 install from github.$ pip install git+https://github.com/uezo/minette-python.git@v0.3