Skip to content

Commit 8274478

Browse files
committed
Updated readme
(cherry picked from commit 5e55892)
1 parent 05ca64a commit 8274478

File tree

1 file changed

+150
-6
lines changed

1 file changed

+150
-6
lines changed

README.md

Lines changed: 150 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,160 @@
1-
# Pyttman
1+
22
![Logo image](.github/cover.png)
33

44

5-
## The Python chatbot framework with batteries included
5+
# The Python chatbot framework with batteries included
66
[![PyPI version](https://badge.fury.io/py/Pyttman.svg)](https://badge.fury.io/py/Pyttman) [![CodeQL](https://github.com/dotchetter/Pyttman/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/dotchetter/Pyttman/actions/workflows/codeql-analysis.yml) [![Python package](https://github.com/dotchetter/Pyttman/actions/workflows/python-package.yml/badge.svg)](https://github.com/dotchetter/Pyttman/actions/workflows/python-package.yml)
77

8-
### About
8+
### If you've ever developed a chatbot or otherwise virtual assistant
9+
-how many times have you had to iterate over the message contents to route the
10+
message to the correct part of your code? Or even worse; How many hours have you spent on
11+
trying to decipher a message and its contents to find words of interest? Maybe the name of a song, or a phone number? Or a username?
12+
13+
### I had enough of that - so I wrote this framework.
14+
915
The Pyttman Framework aims to provide a similar experience as Django and Flask does for web, but for chatbots and digital assistants.
16+
It's large and full of features yet easy to use.
17+
18+
# Abiliy, Intent, Entity
19+
Pyttman apps are structured with inspiration from the MVC (Model View Controller)
20+
pattern, but things are named a bit differently. Here's a short rundown on what they're about.
21+
22+
23+
## Ability
24+
Chatbots can have many areas of capabilities; Anything from answering questions, searching the web,
25+
playing songs to playing games. I call these **Abilities**, which encapsulate responses to
26+
queries in the same domain. The **Ability** class **has** `Intent` classes, and acts like a hub for the Intent classes which
27+
correspond to the same domain of the application. *The ability to store expenses* may contain
28+
many components - saving new expenses, visualizing existing ones, searching for records, etcetera.
29+
30+
**Ability** classes also facilitate a session storage object accessible in the Ability as `self.storage` and in intent classes
31+
as `self.ability.storage`. This allows efficient and safe memory storage for intents to manipulate data in their respective
32+
domain, without global variables and risking exposing data to intents of another domain.
33+
34+
```python
35+
class MusicPlayer(Ability):
36+
"""
37+
This Ability class holds Intent classes which serve users
38+
ways to play music through the chatbot.
39+
"""
40+
41+
# Intent classes are added to this tuple for them to be available
42+
# to users when the application starts.
43+
intents = (PlaySong,
44+
RepeatSong,
45+
FindSongByLyrics)
46+
```
47+
48+
49+
## Intent
50+
The **Intent** class is the heart of the Pyttman development experience. They are classes, 1:1 to a message and a response.
51+
If you're a web developer, you see the similarity to a controller.
52+
Here, we tell which messages it should match and also how to respond with
53+
implementing the `respond` method.
54+
55+
**Consider a message like** `Play Last Train Home by John Mayer on Spotify`.
56+
57+
```python
58+
class PlaySong(Intent):
59+
"""
60+
Lets people play songs on either YouTube, Spotify or SoundCloud.
61+
"""
62+
lead = ("play",)
63+
exclude = ("on",) # These words will be excluded in all entities.
64+
65+
song = TextEntityField(span=5)
66+
artist = TextEntityField(prefixes=("by", "with"), span=10)
67+
shuffle_songs = BoolEntityField(message_contains=("shuffle",))
68+
platform = TextEntityField(as_list=True, valid_strings=(
69+
"Spotify", "SoundCloud", "YouTube")
70+
)
71+
72+
def respond(self, message: Message) -> Reply | ReplyStream:
73+
song = message.entities["song"]
74+
artist = message.entities["artist"]
75+
shuffle_songs = message.entities["shuffle_songs"]
76+
platform = message.entities["platform"]
77+
# Play the song...
78+
return Reply(f"Playing {song} by {artist} on {platform}!")
79+
```
80+
81+
## Entity
82+
*What are those `EntityField` classes in the example above?*
83+
84+
In Pyttman, the **Entity** is a word, or several words sought in a message. When writing chatbots
85+
it's very common to have to parse the message from humans to try and find words of
86+
interest. Maybe your chatbot registers purchases in a database. You'll need to parse
87+
the name of the purchased item as well as the price. But how do you know where to stop
88+
the name of the item? It could be one word, or several. The price could be mentioned
89+
first - or last - or in the middle of the message. Positioning won't help. Regex?
90+
This repetitive and complex process also won't scale. When you've invented the parser
91+
for one answer, you'll need to do it again for the next thing your chatbot can do.
92+
93+
### Let's take a closer look at the example code above.
94+
95+
This EntityField declared in the Intent class above tells Pyttman that you're looking for
96+
a text value in the message. The `span` argument defaults to 1, but in this case is set to 5.
97+
That means the value parsed here can be 5 words long, at the longest - after which Pyttman will
98+
stop adding words to the entity, should it be any longer than that.
99+
100+
```python
101+
song = TextEntityField(span=5)
102+
```
103+
104+
This EntityField is convenient for flags; it will set itself to `True` if a matching word was found in the message, otherwise `False`.
105+
```python
106+
shuffle_songs = BoolEntityField(message_contains=("shuffle",))
107+
```
108+
109+
For situations where a set of known valid choices are available, the `valid_strings` argument can be provided, rendering all other words ignored.
110+
In the example below, `message.entities["platform"]` can only ever be `Spotify, SoundCloud, YouTube` or its `default` which defaults to `None`.
111+
```python
112+
platform = TextEntityField(as_list=True, valid_strings=(
113+
"Spotify", "SoundCloud", "YouTube"))
114+
```
115+
116+
When the message has entered the `respond` method of the matching Intent, the entities are
117+
available on the `entities` property on the `Message` object.
118+
119+
Given the Intent above and the message `Play Last Train Home by John Mayer on Spotify`, the dictionary `message.entities` look like this:
120+
121+
```python
122+
{
123+
'song': 'Last Train Home',
124+
'artist': 'John Mayer',
125+
'shuffle_songs': False,
126+
'platform': 'Spotify'
127+
}
128+
```
129+
130+
131+
# Easy to get started with
132+
Pyttman ships with a CLI tool which is available after pip install. It helps creating
133+
and running your apps with simple commands.
134+
135+
```
136+
# Install it
137+
pip install pyttman
138+
139+
# Create an app from a template
140+
pyttman new app my_first_app
141+
142+
# Create an Ability module with files from a template
143+
pyttman new ability
144+
145+
# Run it in dev mode
146+
pyttman dev my_first_app
147+
148+
# Run it in shell mode, and interact with your objects through a console with Pyttman
149+
modules and objects loaded
150+
pyttman shell my_first_app
151+
152+
# Run it in production mode, for your platform of choice as set in settings.py
153+
pyttman runclient my_first_app
154+
```
155+
156+
## Find content in messages
10157

11-
With class based intents, abilities and entities - elements which are key in any chatbot environment; they are
12-
offered in a very easy way to work with if one is unfamiliar with them; or a very extensive and flexible framework
13-
with the ability to subclass and customize behavior of key parts of the framework.
14158

15159
**Pyttman aims to offer developers a platform-independent experience.**
16160
We're constantly developing support for more platforms. As of today, Pyttman offers built-in support for Discord through the [discord.py](https://github.com/Rapptz/discord.py) library, and we have more on the way.

0 commit comments

Comments
 (0)