A helper library in Python for authors of workflows for `Alfred 4 and 5`_.
Supports Alfred 4 and Alfred 5 on macOS 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.
http://www.xdevcloud.de/alfred-pyworkflow/
Features
========
* Auto-saves settings
* Super-simple data caching with expiry
* Fuzzy, Alfred-like search/filtering with 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
* Pre-configured logging
* Automatically check for workflow updates via GitHub releases
* Post notifications via Notification Center
* Advanced modifiers
* Set `workflow variables`_ from code
* Re-running Script Filters
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
-----------
1. Download the ``alfred-pyworkflow-X.X.X.zip`` file from the `GitHub releases page`_.
2. Extract the ZIP archive and place the `workflow` directory in the root folder of your workflow
(where ``info.plist`` is).
Your workflow directory should look something like this (where ``yourscript.py`` contains your
workflow code and ``info.plist`` is the workflow information file generated by Alfred)::
Your Workflow/
info.plist
icon.png
workflow/
__init__.py
background.py
notify.py
update.py
version
web.py
workflow.py
yourscript.py
etc.
Alternatively, you can clone/download the Alfred-PyWorkflow `GitHub repository`_ and copy the
``workflow`` subfolder to your workflow's root directory.
Usage
=============
A few examples of how to use Alfred-PyWorkflow.
Workflow script skeleton
------------------------
.. code-block:: python
#!/usr/bin/env python3
# encoding: utf-8
import sys
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 as normalized string.
# This is also necessary for "magic" arguments to work.
args = wf.args
# Do stuff here ...
# Add an item to Alfred feedback
wf.add_item('Item title', '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:
.. code-block:: python
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:
.. code-block:: python
data = web.get('http://www.example.com/api/1/stuff').json()
Post a form:
.. code-block:: python
r = web.post('http://www.example.com/',
data={'artist': 'Tom Jones', 'song': "It's not unusual"})
Upload a file:
.. code-block:: python
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)
Keychain access
---------------
Save password:
.. code-block:: python
wf = Workflow()
wf.save_password('name of account', 'password1lolz')
Retrieve password:
.. code-block:: python
wf = Workflow()
wf.get_password('name of account')
Documentation
=============
The full documentation, including API docs and a tutorial, can be found at `xdevcloud.de/alfred-pyworkflow`_.
.. _requests: http://docs.python-requests.org/en/latest/
.. _Alfred-PyWorkflow: https://github.com/harrtho/alfred-pyworkflow
.. _Alfred-Workflow: https://github.com/deanishe/alfred-workflow
.. _Alfred 4 and 5: http://www.alfredapp.com/
.. _GitHub releases page: https://github.com/harrtho/alfred-pyworkflow/releases
.. _the tutorial: https://xdevcloud.de/alfred-pyworkflow/tutorial.html
.. _GitHub repository: https://github.com/harrtho/alfred-pyworkflow
.. _Cheese Shop: https://pypi.org
.. _pip documentation: https://pip.pypa.io/en/latest/
.. _workflow variables: https://xdevcloud.de/alfred-pyworkflow/guide/variables.html#workflow-variables
.. _xdevcloud.de/alfred-pyworkflow: https://xdevcloud.de/alfred-pyworkflow/