Classes, Constraints, Events and more in v0.14
There have been some big changes under the hood in this latest release. These changes should result in more powerfull and flexible skill development. We’ve also seen the Matrix and GitHub connectors and Redis database make their way into the core library.
Classes
After much consideration and debate we’ve decided to start moving skills from bare functions to classes. When I started working on opsdroid in 2016 I wanted to make the bar for creating skills as low as possible. I wanted people who had never written python before to be able to get started simply and easily. Therefore I decided to implement skills are bare functions with a decorator, similar to the getting started examples in flask. However it has become aparent that this is becoming a problem when trying to build complex skills. Therefore we have created a new Skill
class which you can import and subclass to create your skills. All the same matchers work but methods now only need to take the message
as an argument as the opsdroid
and config
arguments are passed into the __init__
of the class. You can override __init__
instead of using the setup
function to run some code on startup.
from opsdroid.matchers import match_regex
from opsdroid.skill import Skill
_LOGGER = logging.getLogger(__name__)
class TestSkill(Skill): def __init__(self, opsdroid, config):
super(TestSkill, self).__init__(opsdroid, config)
# You can put your setup code in here. @match_regex(r'Hello')
async def describe_project(self, message):
await message.respond('world.')
Constraints
This release makes an excellent start on adding new ways to control how skills are matched to messages. You can now add constraints to your skills, this is a way of limiting when skills are matched. For example you may want to match a regex phrase but only from a specific user or in a certain room.
from opsdroid.skill import Skill
from opsdroid.matchers import match_regex
from opsdroid.constraints import constrain_rooms
class MySkill(Skill):
@match_regex(r'hi')
@constrain_rooms(['#general', '#random'])
async def hello(self, message):
await message.respond('Hey')
This example will respond to “hi” with “Hey” but only in the #general or #random rooms.
The old style of skills will continue being supported but will now raise deprecation warnings when you use them.
Events
We are also moving to a new event class system. Until now when a message comes from a chat service it gets turned into a Message
object in opsdroid which is matched and parsed and then when it makes its way to your skill it has useful helper methods for responding and reacting to it.
We’ve now added a higher level Event
class which Message
now inherits from. It has also moved from the message
subpackage to the events
package so you will need to import from opsdroid.events import Message
in connector classes and other places where you need to construct a message.
The plan going forwards is to introduce new event types which we can match and handle in different ways. For example we might want to match GitHub events like Pull Requests and notify in Slack. In the future we can do this with the GitHub and Slack connectors matching on the Pull Request event.
Python module skills
We can now configure skills to use modules from the Python path. This will allow people to package and install their skills separately to the opsdroid packaging system and import them directly.
skills:
- name: mymoduleskill
module: somepackage.someskill
Setuptools entry points
When looking for builtin connectors, databases and skills opsdroid will now check for entrypoints in third party libraries. This means you can create your own connectors, database modules and skills, publish them to PyPI and when a user installs them they can configure them as they would a builtin module.
You just need to add the following section to your setup.py
to register the entrypoint in the right place (opsdroid_databases
, opsdroid_skills
or opsdroid_connectors
).
setup(
...
entry_points = {
'opsdroid_databases': [
'customdatabase = mypackage.mydatabasemodule'
]
},
...
)
You can then configure customdatabase
like it was a built in module.
databases:
- name: customdatabase
# Some config
Slack reactions
The last enhancement I want to highlight is the addition of reactions for Slack. We’ve supported reactions in opsdroid for a while but each connector needs to add support for them in themselves. This release adds support to the Slack connector so you can now react to messages.
from opsdroid.skill import Skill
from opsdroid.matchers import match_regexclass ReactSkill(Skill): @match_regex(r'Hello')
async def wave_back(self, message):
await message.react('👋')
Full Release Notes
Enhancements
Add basic constraints to opsdroid(#745)
First pass at Event
s (#721)
Make it possible to create class-based skills (#734)
Add Matrix connector to opsdroid (#731)
Support custom webhook response (replacement for #793) (#807)
Add Redis database to core (#785)
Refactor connector opsdroid pointer (#749)
setuptools entry points support for loading contributed extensions (issue #767) (#771)
load module from pythonpath (#755)
Add reactions to slack connector (#742)
Merge github connector into core (#741)
Bug fixes
Workaround for pip no cache bug (#816)
Bump Pyyaml to avoid CVE-2017–18342 (#803)
Cancel pending tasks on unload (#729)
Remove unused dependency requests_mock (#778)
Remove self from disconnect() method when unload is called (#775)
Fix slack error on connect by calling disconnect if exception is raised (#754)
Refactoring tests — replaces logmock for self.assertLogs (#752)
Make shell connector optional (#747)
Fix the signature of Database.disconnect (#737)
Add config_lang() to tests setup (#730)
Call skills correctly depending on function or class skills (#820)
Fix broken websocket handler (#819)
Breaking changes
None 🎉
Documentation updates
Update version number info (#818)
fixed typos and grammatical errors in the docs (#814)
Add tweet button with text below the badges (#812)
Fix markdown format error (#809)
Update example_configuration.yaml database connectors reference (#788)
fixed some grammatical errors (#787)
fixed typos in the docs and added syntax highlighting (#786)
Fix code annotation created in #779
Removing a line of dead code in the tests (#753)
add Google style docstring to web.py (#746)
Fix a typo in the skills documentation (#736)
v0.14.1
Docker Hub builds were not triggering correctly. This next release should build now. There are no actual changes to opsdroid.
v0.14.2
Bug Fixes
Fix _constrain_skills method (#902)