Alfred Workflow
Full-featured library for writing Alfred 3 & 4 workflows
Install / Use
npx skills add deanishe/alfred-workflowInstalls into whichever agent you are using.
README
Alfred-Workflow
A helper library in Python for authors of workflows for Alfred 3 and 4.
<!-- [![Build Status][shield-travis]][travis] -->[![Build Status][shield-github]][action-github] ![Coverage Status][shield-coveralls] [![Development Status][shield-status]][pypi] [![Latest Version][shield-version]][pypi] [![Supported Python Versions][shield-pyversions]][pypi]
<!-- [![Downloads][shield-download]][pypi] -->Supports Alfred 3 and Alfred 4 on macOS 10.7+ (Python 2.7).
Alfred-Workflow 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][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
- Alfred 4-only updates (won't break older Alfred installs)
Contents
<!-- MarkdownTOC autolink="true" bracket="round" depth="3" autoanchor="true" --> <!-- /MarkdownTOC --><a name="installation"></a> Installation
Note: If you're new to Alfred workflows, check out the tutorial in the docs.
<a name="with-pip"></a>
With pip
You can install Alfred-Workflow directly into your workflow with:
# from your workflow directory
pip install --target=. Alfred-Workflow
You can install any other library available on the [Cheese Shop][cheeseshop] the same way. See the [pip documentation][pip-docs] 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".
<a name="from-source"></a>
From source
- Download the
alfred-workflow-X.X.X.zipfrom the [GitHub releases page][releases]. - Extract the ZIP archive and place the
workflowdirectory in the root folder of your workflow (whereinfo.plistis).
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-Workflow [repository][repo] and copy the workflow subdirectory to your workflow's root directory.
<a name="usage"></a> Usage
A few examples of how to use Alfred-Workflow.
<a name="workflow-script-skeleton"></a>
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/python
# encoding: utf-8
import sys
# Workflow3 supports Alfred 3's new features. The `Workflow` class
# is also compatible with Alfred 2.
from workflow import Workflow3
def main(wf):
# The Workflow3 instance will be passed to the function
# you call from `Workflow3.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 `Workflow3(libraries=...)`
import somemodule
import anothermodule
# Get args from Workflow3, 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 `Workflow3` object
wf = Workflow3()
# Call your entry function via `Workflow3.run()` to enable its
# helper functions, like exception catching, ARGV normalization,
# magic arguments etc.
sys.exit(wf.run(main))
<a name="examples"></a>
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()
<a name="web"></a>
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][requests] library upon which the web.py API is based.
<a name="keychain-access"></a>
Keychain access
Save password:
wf = Workflow()
wf.save_password('name of account', 'password1lolz')
Retrieve password:
wf = Workflow()
wf.get_password('name of account')
<a name="documentation"></a> Documentation
The full documentation, including API docs and a tutorial, can be found at deanishe.net.
<a name="dash-docset"></a>
Dash docset
The documentation is also available as a Dash docset.
<a name="licensing-thanks"></a> 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][sphinx] and a modified version of the Alabaster theme by bitprophet.
Many of the cooler ideas in Alfred-Workflow were inspired by [Alfred2-Ruby-Template][ruby-template] by Zhaocai.
The Keychain parser was based on [Python-Keyring][python-keyring] by Jason R. Coombs.
<a name="contributing"></a> Contributing
<a name="adding-a-workflow-to-the-list"></a>
Adding a workflow to the list
If you want to add a workflow to the list of workflows using Alfred-Workflow, don't add it to the docs! The list is machine-generated from [Packal.org][packal] and the library_workflows.tsv file. If your workflow is available on [Packal][packal], it will be added on the next update. If not, 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.
<a name="bug-reports-pull-requests"></a>
Bug reports, pull requests
Please see the documentation.
<a name="contributors"></a>
Contributors
- Dean Jackson
- [Stephen Margheim][smargh]
- Fabio Niephaus
- Owen Min
<a name="workflows-using-alfred-workflow"></a> Workflows using Alfred-Workflow
Here is a list of some of the many workflows based on Alfred-Workflow.
Related Skills
python-debugpy
385.5kDebug Python with pdb, breakpoint(), post-mortem inspection, and debugpy remote attach.
skill-creator
385.5kCreate, edit, audit, tidy, validate, or restructure AgentSkills and SKILL.md files.
qqbot-channel
385.5kQQ channel management skill. Use qqbot_channel_api for explicit QQ channel-management requests; confirm write, delete, and bulk actions before calling authenticated QQ Open Platform endpoints.
claude-opus-4-5-migration
140.6kMigrate prompts and code from Claude Sonnet 4.0, Sonnet 4.5, or Opus 4.1 to Opus 4.5
