import
Ansible allows unchecked imports of some libraries from specific directories. Importing any other Python library requires handling import errors. This enables support for sanity tests such as validate-modules and provides better error messages to the user.
Handling import errors
In modules
Instead of using import another_library
:
import traceback
from ansible.module_utils.basic import missing_required_lib
try:
import another_library
except ImportError:
HAS_ANOTHER_LIBRARY = False
ANOTHER_LIBRARY_IMPORT_ERROR = traceback.format_exc()
else:
HAS_ANOTHER_LIBRARY = True
ANOTHER_LIBRARY_IMPORT_ERROR = None
Note
The missing_required_lib
import above will be used below.
Then in the module code:
module = AnsibleModule(...)
if not HAS_ANOTHER_LIBRARY:
module.fail_json(
msg=missing_required_lib('another_library'),
exception=ANOTHER_LIBRARY_IMPORT_ERROR)
In plugins
Instead of using import another_library
:
try:
import another_library
except ImportError as imp_exc:
ANOTHER_LIBRARY_IMPORT_ERROR = imp_exc
else:
ANOTHER_LIBRARY_IMPORT_ERROR = None
Then in the plugin code, for example in __init__
of the plugin:
if ANOTHER_LIBRARY_IMPORT_ERROR:
raise AnsibleError('another_library must be installed to use this plugin') from ANOTHER_LIBRARY_IMPORT_ERROR
When used as base classes
Important
This solution builds on the previous two examples. Make sure to pick the appropriate one before continuing with this solution.
Sometimes an import is used in a base class, for example:
from another_library import UsefulThing
class CustomThing(UsefulThing):
pass
One option is make the entire class definition conditional:
if not ANOTHER_LIBRARY_IMPORT_ERROR:
class CustomThing(UsefulThing):
pass
Another option is to define a substitute base class by modifying the exception handler:
try:
from another_library import UsefulThing
except ImportError:
class UsefulThing:
pass
...
Allowed unchecked imports
Ansible allows the following unchecked imports from these specific directories:
ansible-core:
For
lib/ansible/modules/
andlib/ansible/module_utils/
, unchecked imports are only allowed from the Python standard library;For
lib/ansible/plugins/
, unchecked imports are only allowed from the Python standard library, from public dependencies of ansible-core, and from ansible-core itself;
collections:
For
plugins/modules/
andplugins/module_utils/
, unchecked imports are only allowed from the Python standard library;For other directories in
plugins/
(see the community collection requirements for a list), unchecked imports are only allowed from the Python standard library, from public dependencies of ansible-core, and from ansible-core itself.
Public dependencies of ansible-core are:
Jinja2
PyYAML
MarkupSafe (as a dependency of Jinja2)