Alfred-PyWorkflow
A helper library in Python for authors of workflows for Alfred 4 and 5.
Supports Alfred 4 and Alfred 5 on macOS Catalina or later with Python 3.7+.
Alfred-PyWorkflow is a Python 3 port of the original Alfred-Workflow.
Alfred-PyWorkflow takes the grunt work out of writing a workflow by giving you the tools to create a fast and featureful Alfred workflow from an API, application or library in minutes.
Always supports all current Alfred features.
Features
- Auto-saved settings API for your workflow
- Super-simple data caching with expiry
- Fuzzy filtering (with smart diacritic folding)
- Keychain support for secure storage of passwords, API keys etc.
- Lightweight web API with Requests-like interface
- Background tasks to keep your workflow responsive
- Simple generation of Alfred JSON feedback
- Full support of Alfred's AppleScript/JXA API
- Catches and logs workflow errors for easier development and support
- "Magic" arguments to help development/debugging
- Unicode support
- Pre-configured logging
- Automatically check for workflow updates via GitHub releases
- Post notifications via Notification Center
Alfred 4+ features
- Advanced modifiers
Contents
Installation
Note: If you're new to Alfred workflows, check out the tutorial in the docs.
With pip
You can install Alfred-PyWorkflow directly into your workflow with:
# from your workflow directory
pip install --target=. Alfred-PyWorkflow
You can install any other library available on the Cheese Shop the same way. See the pip documentation for more information.
It is highly advisable to bundle all your workflow's dependencies with your workflow in this way. That way, it will "just work".
From source
- Download the
alfred-pyworkflow-X.X.X.zip
from the GitHub releases page. - Extract the ZIP archive and place the
workflow
directory in the root folder of your workflow (whereinfo.plist
is).
Your workflow should look something like this:
Your Workflow/
info.plist
icon.png
workflow/
__init__.py
background.py
notify.py
Notify.tgz
update.py
version
web.py
workflow.py
yourscript.py
etc.
Alternatively, you can clone/download the Alfred-PyWorkflow GitHub repository and copy the
workflow
subdirectory to your workflow's root directory.
Usage
A few examples of how to use Alfred-PyWorkflow.
Workflow script skeleton
Set up your workflow scripts as follows (if you wish to use the built-in error handling or sys.path
modification):
#!/usr/bin/env python3
# encoding: utf-8
import sys
# Workflow supports Alfred 3's new features.
from workflow import Workflow
def main(wf):
# The Workflow instance will be passed to the function
# you call from `Workflow.run`.
# Not super useful, as the `wf` object created in
# the `if __name__ ...` clause below is global...
#
# Your imports go here if you want to catch import errors, which
# is not a bad idea, or if the modules/packages are in a directory
# added via `Workflow(libraries=...)`
import somemodule
import anothermodule
# Get args from Workflow, already in normalized Unicode.
# This is also necessary for "magic" arguments to work.
args = wf.args
# Do stuff here ...
# Add an item to Alfred feedback
wf.add_item(u'Item title', u'Item subtitle')
# Send output to Alfred. You can only call this once.
# Well, you *can* call it multiple times, but subsequent calls
# are ignored (otherwise the JSON sent to Alfred would be invalid).
wf.send_feedback()
if __name__ == '__main__':
# Create a global `Workflow` object
wf = Workflow()
# Call your entry function via `Workflow.run()` to enable its
# helper functions, like exception catching, ARGV normalization,
# magic arguments etc.
sys.exit(wf.run(main))
Examples
Cache data for 30 seconds:
def get_web_data():
return web.get('http://www.example.com').json()
def main(wf):
# Save data from `get_web_data` for 30 seconds under
# the key ``example``
data = wf.cached_data('example', get_web_data, max_age=30)
for datum in data:
wf.add_item(datum['title'], datum['author'])
wf.send_feedback()
Web
Grab data from a JSON web API:
data = web.get('http://www.example.com/api/1/stuff').json()
Post a form:
r = web.post('http://www.example.com/',
data={'artist': 'Tom Jones', 'song': "It's not unusual"})
Upload a file:
files = {'fieldname' : {'filename': "It's not unusual.mp3",
'content': open("It's not unusual.mp3", 'rb').read()}
}
r = web.post('http://www.example.com/upload/', files=files)
WARNING: As this module is based on Python 2's standard HTTP libraries, on old versions of OS X/Python, it does not validate SSL certificates when making HTTPS connections. If your workflow uses sensitive passwords/API keys, you should strongly consider using the requests library upon which the web.py
API is based.
Keychain access
Save password:
wf = Workflow()
wf.save_password('name of account', 'password1lolz')
Retrieve password:
wf = Workflow()
wf.get_password('name of account')
Documentation
The full documentation, including API docs and a tutorial, can be found at xdevcloud.de.
Dash docset
The documentation is also available as a Dash docset.
Licensing, thanks
The code and the documentation are released under the MIT and Creative Commons Attribution-NonCommercial licences respectively. See LICENCE.txt for details.
The documentation was generated using Sphinx and a modified version of the Alabaster theme by bitprophet.
Many of the cooler ideas in Alfred-PyWorkflow were inspired by Alfred2-Ruby-Template by Zhaocai.
The Keychain parser was based on Python-Keyring by Jason R. Coombs.
Contributing
Adding a workflow to the list
If you want to add a workflow to the list of workflows using Alfred-PyWorkflow, don't add it to the docs! The list is machine-generated from the library_workflows.tsv
file. Please add it to library_workflows.tsv
, and submit a corresponding pull request.
The list is not auto-updated, so if you've released a workflow and are keen to see it in this list, please open an issue asking me to update the list.
Bug reports, pull requests
Please see the documentation.
Contributors
Workflows using Alfred-PyWorkflow
Here is a list of some of the many workflows based on Alfred-PyWorkflow.