Dragonfly - a Python library extending NatLink
Dragonfly - a Python library which extends NatLink
Hello Speech Computing readers,
I would like to introduce Dragonfly, a Python library which
extends NatLink. It provides a language object model which
takes care of all the nitty-gritty details required to
interface with NatLink and Dragon NaturallySpeaking. Dragonfly
allows Python programmers to use high-level pythonic objects
to specify grammars and rules, and to process recognition
results.
Dragonfly is hosted here: http://code.google.com/p/dragonfly/
Features of the Dragonfly library:
- High-level language object model; offers dynamic and
flexible control of command grammars. - Integrated recognition parsing; gives easy and language-
independent access to recognized data. - Extensible activity contexts; allows precise control of
when grammars and rules are active. - Built-in action framework; simplifies the modular
definition of actions, such as keyboard events, to be
executed when a command is recognized.
Instead of telling you how Dragonfly works, I'd like you to
see for yourself. Below I've included a code snippet from an
example Python module demonstrating Dragonfly usage. Anybody
who's ever written a NatLink macro will see how Dragonfly can
make life easier.
spec = "(I ate <food> <time> | <time> I ate <food>) [and thought it was <opinion>]"
time = {
"(two days ago | day before yesterday)": 2,
"yesterday": 1,
"today": 0,
}
food = {
"(a Granny Smith | an) apple": "fruit",
"an orange": "fruit",
"a hamburger": "meat",
"a [juicy] steak": "meat",
}
extras = [
Choice("time", time),
Choice("food", food),
Dictation("opinion"),
]
def _process_recognition(self, node, extras):
days_ago = extras["time"]
foodgroup = extras["food"]
day_word = (days_ago == 1 and "day" or "days")
print "You ate %s %d %s ago." % (foodgroup, days_ago, day_word)
if "opinion" in extras:
print "You thought it was %s." % (extras["opinion"])
I say: "I ate an orange yesterday"
Module prints: "You ate fruit 1 day ago."
I say: "day before yesterday I ate a hamburger"
Module prints: "You ate meat 2 days ago."
I say: "I ate an apple today and thought ..."
"... it was Cap delicious exclamation-mark"
Module prints: "You ate fruit 0 days ago."
Module prints: "You thought it was Delicious!."
Complete code for this module is available here:
(browsable repository)
Q: who is the target audience of Dragonfly?
A: people interested in speech recognition and Python.
Users of Dragonfly generally have at least a little
experience with programming in Python. Although, you
don't have to be very skilled at all to use it,
because the library is fairly intuitive and easy-to-use.
Q: why not just use NatLink's GrammarBase class?
A: because that requires a lot of unnecessary work. It
involves defining a grammar in the form of one big static
string, and then manually extracting relevant
information from the raw sequence of literal words
recognized.
A significant disadvantage of using NatLink directly is
that it makes it very difficult to write multi-language
command grammars, because literal words are used both in
the grammar definition and in the recognition parsing
logic.
Q: why not just use an existing framework, such as vocola?
A: because all existing frameworks I could get my hands on
use their own scripting language. This simplifies
defining new commands, but limits their power.
Dragonfly is a Python library. Developers can therefore
do everything that Python can do when a command is
recognized: keyboard & mouse events, Win32 API calls, COM
interfacing, and everything else the developer's
imagination can come up with.
I'm putting Dragonfly out into the world in the hopes that
other people will benefit from it. I use it every day. It
has enriched my speech-recognition experience. It allows
me to rapidly develop new application modules to control
all kinds of software. I believe that other people, if
they take the time to look at Dragonfly, will also see its
potential and will be able to increase their productivity
by using it.
As I pointed out above, the Dragonfly project is
hosted here: http://code.google.com/p/dragonfly/
Have fun and let me know what you think of Dragonfly,
-- Christo.

Dragonfly has got the
Dragonfly has got the "right" kind of name, and it sounds powerful to a non-programmer like me. I have a "classic" Python text, which currently serves to elevate books I do use off the floor, but I guess I could always try to learn something new to commemorate my entry to Medicare
More practically, could Dragonfly help to develop scripts to control Java-based applications, like Adobe stuff?
Could Dragonfly help to control applications that don't have keyboard access to some of its operations -- for example, linking tags to photos in Adobe Photoshop Elements 7, which apparently can only be done with mouse-type actions?
That exhausts my knowledge, but I wish you good luck with this new language and congratulate for sharing it with the community!
Bruce
Hello Christo, Compliments
Hello Christo,
Compliments for your work, but nevertheless: I am sorry to say, but Dragonfly, while it looks very smart, does not offer more possibilities than there already are.
1. Vocola offers commands without doing anything in Python.
2. Unimacro offers all the things you want in python, including the possibility to translate grammars (without interfering in the python grammar file!).
3. The structure of natlink grammars is not the bottleneck for developing things, neither is the callback structure. For doing easy things you can use vocola, or have a bit of boilerplate. For doing more difficult things this layer will not add things really.
So a nice effort, but useless at present.
My 10 cents, Quintijn
Useless? Or maybe not...
In reply to Quintijn,
Quintijn, thanks for your $.10. But I must disagree.
Here are the points you're trying to make:
Quintijn: Vocola offers commands without doing anything in
Python.
Christo: yes, I agree with you, Vocola is great! We
needed Vocola because working with NatLink directly was
difficult and inefficient. However, Vocola doesn't offer
the power and flexibility that Python does. And now with
Dragonfly we have the advantages of Python combined with
ease of use, similar to Vocola.
Dragonfly is not an attempt to replace Vocola. Not at
all! As I said, Vocola is great. Dragonfly targets a
different user group: people who need the flexibility of
Python.
Quintijn: Unimacro offers all the things you want in
python, including the possibility to translate grammars
(without interfering in the python grammar file!).
Christo: I'm glad there's somebody who knows "all the
things" I want in Python. Alas, even after a review of
unimacro's source code, I couldn't figure out how Unimacro
would help me rapidly develop new application control
modules.
Unimacro has some good features, I agree with that.
However, it isn't something other people can easily build
upon to create custom extensions. That's what Dragonfly
is good at.
Quintijn: The structure of natlink grammars is not the
bottleneck for developing things, neither is the callback
structure. For doing easy things you can use vocola, or
have a bit of boilerplate. For doing more difficult things
this layer will not add things really.
Christo: anybody who wants to voice-enable an application
has to face two challenges: how to control the
application, and how to interface with speech recognition.
Depending on which application you're trying to control,
the first of those challenges might be easy or might be
difficult. That all depends on the application itself.
But, the interface with speech recognition can be improved
and made easier. Depending on how complex the speech
grammar is, this can be a huge benefit. The "food groups"
example I gave in my post above is a clear example of
this. It looks straightforward, but to anybody who's ever
worked with NatLink itself, this example's simplicity and
directness is a huge relief. (And this example is
purposefully kept very simple for the casual reader.
Dragonfly can actually do much more.)
Dragonfly makes it possible for even a novice Python
programmer to quickly roll their own script which
interfaces with speech recognition.
Sorry Quintijn, but in your first post you seemed to have
missed the point of the Dragonfly library. I hope I have
explained this project more clearly now.
-- Christo.
Controlling Applications
In reply to BruceCyr:
Dragonfly is designed to help Python programmers harness the power of speech recognition. If it is possible to control an application from Python, then Dragonfly makes it very easy to control that application using voice commands.
Your question about Adobe Photoshop Elements 7 isn't so much about Dragonfly, as it is about Adobe Photoshop Elements and Python. Many Windows programs, such as Adobe Photoshop and Microsoft office, can be controlled very well using COM interfaces. I've used these successfully to Dragonfly-enable various programs such as Word and Outlook. Approaching the programs in this way gives a lot more power and flexibility above static keyboard shortcuts and mouse clicks.
So my answer to your question is: yes, Dragonfly can help develop scripts to control all kinds of applications, like some of the Adobe suite.
But my question for you is: do you know if Adobe Photoshop Elements 7 offers a COM interface to control it? I know that Photoshop itself does (see http://techarttiki.blogspot.com/2008/08/photoshop-...).
If you'd like to check whether your software does offer a COM interface, you can do so using Pythonwin's "COM browser" under the "tools" menu. (Pythonwin is a free and popular Python editor for Windows)
-- Christo.
Do you know offhand if the
Do you know offhand if the Open Office Suite includes a COM interface?
OpenOffice interface from Python
I don't use OpenOffice myself, so I can't test this for you right now. But, controlling OpenOffice from Python seems possible using, for example, the odfpy package:
http://opendocumentfellowship.com/development/proj...
If you can use that package to control OpenOffice the way you want, then I'll help you wrap it up with Dragonfly so that it becomes voice-enabled.
-- Christo.
Christo, Thanks, but all
Christo,
Thanks, but all this is flying over my head, so I guess I'm out of this game
Bruce
Python...
Hi Bruce,
It all starts with Python. That's one of the more user-friendly languages out there. And I remember you saying you had a book on Python somewhere in a pile on the floor.
If you do find the motivation to open that book, I'm sure you'll be amazed at how easy Python makes it to do cool stuff. And Dragonfly will make it easy to do cool stuff with your voice!
-- Christo.
Christo, Thanks for the
Christo,
Thanks for the encouragement. Its not learning a new language that's daunting, but rather figuring out how to use it, for example that COM stuff. There is something similar in Dragon Pro scripting involving the libraries (?) of applications, and of course object-oriented programming, etc. But maybe when I tire of refilling my own dentures I'll get around to something new
In the meantime, I hope to see other folks make use of your new tool -- maybe I'll get into the spirit that way. It really sounds like a tool that would help people speech-adapting applications for, say, a company or other organization. Its really a shame that a market hasn't developed for applets for speech-controlling applications. I suppose one of the problems is that most of the scripting tools available are essentially open-source, which makes it hard for a developer to make a profit from an ultra-niche market like speech-adapting a specific application, say Adobe Photoshop Elements 7
Bruce
Bruce
Dragonfly = great!
Hi guys,
I'm very new to speechrecognition, actually just bought DNS 10 last week. Being a newbie at speechrecognition, doesn't mean that I don't have specific requests though. I am myself able to read and interpet simple scripts, but writing them is not an option without asking for help. So I was reliefed to find out about Dragonfly! Let me explain why:
I have to send in several documents per week for school in Dutch. I therefore had to buy the Dutch version of DNS. As I am on a limited budget I was forced to choose Standard. It was a hard choice as it lacks some of the options I really wanted. Dragonfly however, brought those options back in an amazing way. Not only can I myself make DNS do exactly what I want, the options seem neverending
A few examples:
I had some Dragonfly example files for Outlook and Word. I use Office 2007 on Vista. Dragon does the basic commands in both, but after installing Dragonfly I can tell my computer to do everything I can think of. Within minutes I was able to say: "Send message to mom" and a new message, with her address already put in, was opened. The cool thing is, DNS doesn't do this for you in the Standard edition.
It was as simple as translating the English command from the example into my preferred Dutch words, hit 'save' and it works! In the script it looks like this:
people = {
"joost|liefje":"Joost",
"joyce|mama":"joyce",
}
static_rule = MappingRule(
name="static",
mapping={
"nieuwe mail <persoon>": Key("cs-m/100")
+ Text("%(persoon)s")
+ Key("enter, tab, tab"),
}
extras=[
Choice("persoon", people),
]
In Word I can now edit the styles in a document with one simple short sentence, without the command being visible on screen. I can move through my open programmes in a few words (just saying 'open task 2') will do the trick.
I have just started using Dragonfly today, so I'm still at the beginning of finding out all the possibilities. But after 4 or 5 hours of use I already can tell you, it's a wonderful tool to have! It's installed quickly, it's not hard to understand even if you're not a scripting wizard. The great thing is that the end-user interface is fairly simple, all the "magic" seems to be done backstage. I had never worked with Python or PythonWin before today, but it was not a problem at all.
I have seen other scripts that aim to do the same thing. As far as I could see, translating a word to Dutch had to be done in 5 or 6 different places. I think it would be too easy to miss one, which then would make finding your mistake rather hard. That's why I'm a very happy Dragonfly user! It's a clean, not cluttered, script to work in and so far it has been able to make my DNS software do everything I want it to.
If new wonderful things turn up I will post again
Big thank you to Christo 
Biddy
Creating a collection of Dragonfly scripts?
Christo, this looks like a really cool tool! There are a number of little problems this might overcome, such as the way Internet Explorer freezes up when you try to maximize or minimize a window using voice command/Vocola.
Are you going to try to create a collection of scripts? I may get a chance to play this week or next, so if I come up with anything useful, it be nice to know where to put/send them.
Thanks,
Anders
Should you wish to place the
Should you wish to place the scripts on here, I've added a DragonFly section to the Macro tracker area. You create the entries by "create a" then Macro in the menu area on the right.
Command modules
Thank you admin,
I'll start placing various Dragonfly macros (a.k.a. command modules, because that's their Python name) here shortly.
-- Christo
Excellent work!
Christo:
Thank you for this incredible contribution! Working on some voice projects recently reminded me how difficult, error prone, and just plain tedious it can be to write "pure" NatLink modules. It has always bothered me that grammar updates had to be made in two places: the grammar specification string and the implementation code. Dragonfly provides an elegant solution that leverages the power of the Python programming language.
Well done!
dan
Are there any limitations on
Are there any limitations on the supported grammars beyond what can be expressed in SAPI 4?
In particular, can you make modular lists?
e.g., x :== (1 | 2 | a [2..3]) defined in 1 file with a maping to keystrokes, imported and used in another file?
If so, I'm wondering if dragonfly would be a good compilation target for Vocola.
Importing between files: yes you can!
Hi Mdl,
Short answer to your question: yes, you can import something like a list/mapping from one file and use it in another.
Long answer: depending on exactly what you want to achieve, you have two choices.
The first and most powerful is the Python-way. When using Dragonfly, things like lists and mappings (of things you can say to keystrokes) are first-class Python objects. This means that you can treat them like standard Python things: share them between files, pass them back and forth, etc. This gives you total control and freedom.
The second option would be to share stuff through the speech recognition engine. Exporting the rule from one grammar, loading that grammar, and then importing that rule into a second grammar. This option I have not yet explored myself yet. Do you know if this is possible in NatLink? I know there are special importable rules such as "<dgndictation>", but is it also possible to import rules you yourself export in a separate NatLink grammar? If this is possible, then Dragonfly implicitly also supports it.
Let me know what you'd like to do, and I can give you an instant introduction into the power of Dragonfly.
-- Christo
mdl,Would it be possible to
********* Moved to a new thread *************
mdl,
Would it be possible to know what the future holds for Vocola on your side ? As Rick is going Vocola for WSR, do you plan to continue supporting Vocola for DNS ? What do you want to add in the future versions of Vocola ?
thanks,
John