Including 3rd party libraries

It’s a Very Bad Idea™ to install (or ask users to install) 3rd-party libraries in the macOS system Python. Alfred-PyWorkflow makes it easy to include them in your Workflow.

Simply create a libs subdirectory under your Workflow’s root directory and install your dependencies there. You can call the directory whatever you want, but in the following explanation, I’ll assume you used libs.

To install libraries in your dependencies directory, use:

pip install --target=path/to/my/workflow/libs python-lib-name

The path you pass as the --target argument should be the path to the directory under your Workflow’s root directory in which you want to install your libraries. python-lib-name should be the “pip name” (i.e. the name the library has on PyPI) of the library you want to install, e.g. requests or feedparser.

This name is usually, but not always, the same as the name you use with import.

For example, to install Alfred-PyWorkflow, you would run pip install Alfred-PyWorkflow but use import workflow to import it.

An example: You’re in a shell in Terminal.app in the Workflow’s root directory and you’re using libs as the directory for your Python libraries. You want to install requests. You would run:

pip install --target=libs requests

This will install the requests library into the libs subdirectory of the current working directory.

Then you instantiate Workflow with the libraries argument:

1from workflow import Workflow
2
3def main(wf):
4    import requests  # Imported from ./lib
5
6if __name__ == '__main__':
7    wf = Workflow(libraries=['./libs'])
8    sys.exit(wf.run(main))

When using this feature you do not need to create an __init__.py file in the libs subdirectory. Workflow(…, libraries=['./libs']) and creating ./libs/__init__.py are effectively equal alternatives.

Instead of using Workflow(…, libraries=['./libs']), you can add an empty __init__.py file to your libs subdirectory and import the libraries installed therein using:

from libs import requests

instead of simply:

import requests

If you encounter a ModuleNotFoundError error, e.g. due to sub-dependencies not being aware of the ./libs path, you can add it like this:

sys.path.append("libs")
from lib import requests