-
Notifications
You must be signed in to change notification settings - Fork 0
Introduction to Droit v1.1
python-droit can be used to build any kind of bot. It's up to you to connect droit to some sort of input and output which could be just the console, a graphical user-interface, a telegram bot or a text-to-speech engine. python-droit will be the base of your bot which generates a text-output from a text-input. Instead of hardcoding question-to-answer conditions you can use this library. It uses the Droit Database Script to simply create advanced question-to-answer rules.
There is a detailed documentation of the Droit Database Script. However I'll try to explain how it works in short. Example:
TEXT!i:TEXT!like,love:TEXT!you:NOTX!not,dont->TEXT!I like you too...
A Droit Database using Droit Database Script consists of many rules like this. Each line of the file is a new rule. Each rule is divided into input and output using ->. Input and outputs themselves are divided into sub-rules. Input-sub-rules are conditions that have to be met for the rule to be used. If all conditions are met it will be returned as a DroitSearchHit. The example above has the following conditions:
- The input string contains the word "i"
- The input string contains the word "like" or "love"
- The input string doesn't contain the word "not" or "dont"
If the rule will be chosen to be used to produce an output string, the output-sub-rule will generate the string "I like you too...".
However there are far more possibilities. More advanced example:
TEXT!my:TEXT!name:TEXT!is:INP*name!->TEXT!Hello :VAR!inp.name
The conditions of this rule are:
- The input string contains the following words: "my", "name" and "is"
- The word "is" follows another word (or words)
Those other words or this other word will be stored into the variable inp.name. This variable can be used in output-sub-rules. The output-sub-rule VAR returns the value of a variable as seen in this example. If the user enters "my name is max" it will produce the output "Hello max". One more example:
SIMT*90!whats the time please,what time is it->TEXT!It's :VAR!global.time
The SIMT input-sub-rule accepts strings that are similar up to a given percentage (90% in this case). The condition will be true with slightly different inputs and typos like "what is the time please" or "wha time iis it". The variable global.time stores the current time.
SESSION*isNotActive!:TEXT!i:TEXT!am:INP*name!->EVAL!session.activateByUsername(*inp.name):TEXT!Hello :VAR!inp.name
Conditions:
- There is no active session
- The input string contains "i", "am" another string Output:
- Activate the session by a username that is stored within the varible
inp.name(no output) - Print "hello "
- Print the content of
inp.name
This example uses sessions. They are used to make it possible to use one instance of droit for multiple users. The best way to learn more about Droit Database Script is to look at these examples or to read the documentation of Droit Database Script. Please note that droit is not case sensitive. This makes it a lot easier to define rules.
python-droit can parse and use Droit Database Script files. If you don't want to create your own databases you can start with one of the default databases stored within the sample folder.
Let's parse a database:
import droit
db = droit.Database()
db.loadPlugins()
db.parseScript("path/to/database.dda")The first thing we do with every bot that uses droit is creating a database object. After that we'll have to load the plugins. They can optionally be loaded from a custom folder if you aren't using the default plugins. Plugins are input-sub-rules or output-sub-rules like TEXT, SIMT or VAR. You can easily create your own! However, let's start with the plugins that come with droit by default.
Now that we have parsed some rules we need some input from the user.
rawInput = input("Please enter some text: ")
userinput = droit.models.DroitUserinput(rawInput)
hits = db.useRules(userinput)What happens here is the creation of an DroitUserinput object that is required by the useRules() method. This useRules() method compares the userinput to the rules that we parsed earlier. If all conditions are met it will be appended as a DroitSeachHit to the list that will be returned.
if(len(hits) > 0):
hit = hits[0]
output = db.formatOut(hit, userinput)
print(output)
else:
print("Sorry, I don't know what to answer...")If there are rules that meet all conditions we will use the first rule because droit sorts them by relevance. The method formatOut() generates an output string from the output-sub-rules.
If you are writing a bot you will most likely use a loop to repeat asking for a user-input.
As mentioned earlier droit supports multiple users if needed. Therefore we will use sessions.
import droit
db = droit.Database()
db.loadPlugins()
db.parseScript("path/to/database.dda")
db.sessions.path = "path/to/sessions.json"
db.sessions.loadSessions() # when running the first time you may create sessions.json using saveSessions() firstSessions are stored within a json file. If you're using sessions for the first time make sure to create this file using db.sessions.saveSessions(). The path has to be defined before running this function.
You can add new sessions/users.
user = droit.models.DroitSession("Max Mustermann")
db.sessions.sessions.append(user)By default there is no active session. You can activate a user by its username or id.
db.sessions.activateByUsername("Max Mustermann")
db.sessions.activateById(USER_ID)You may want to access and store data within a session.
user = db.sessions.getActive() # get active DroitSession
if(user):
user.username = "new username"
user.id = 12345
user.userData["customProp"] = "some data" # userData stores a map that can be filled with custom user-data
db.sessions.setActive(user) # overwrite active session with "user"
db.sessions.saveSession() # save sessions to json fileYou can use Droit Database Script to access sessions. Example:
SESSION*isUsername!Max Mustermann:TEXT!hi->TEXT!Hi Max
SESSION*isActive!:TEXT!hi->TEXT!Hi :EVAL!session.getUsername()
SESSION*isNotActive!:TEXT!i:TEXT!am:INP*name!->EVAL!session.activateByUsername(*inp.name):TEXT!Hello :VAR!inp.name
If you want to store recent inputs and outputs you can do so by using the history functionality.
db.history.newEntry(userinput, hit.rule, output, userId=db.sessions.getActive().id)Wiki for python-droit
Copyright 2020-2021 Jakob Stolze