Developing Custom Processors
Custom processors are Python files with some specific boilerplate templates. You can run any Python code inside a custom processor, which means you can do just about anything in one.
All processors are structured the same basic way:
- A custom processor class that inherits from
Processor
orURLGetter
- The class defines
input_variables
andoutput_variables
, which determines what input is expected/required and what output is provided - The class must have a
main()
function - If you want to be able to execute a processor standalone (and not just within the context of running a recipe), you need to run
execute_shell()
at the bottom of the file
Look at the Sample Custom Processor, which is a good example of the boilerplate:
from autopkglib import Processor, ProcessorError
__all__ = ["SampleSharedProcessor"]
class SampleSharedProcessor(Processor):
"""This processor doesn't do anything useful. It is a demonstration of using
a shared processor via a recipe repo."""
description = __doc__
input_variables = {
"shared_processor_input_var": {
"required": True,
"description": "Test the use of an input variable in a shared processor.",
}
}
output_variables = {
"module_file_path": {"description": "Outputs this module's file path."}
}
def main(self):
// do stuff here
print("My custom processor!")
if __name__ == "__main__":
PROCESSOR = SampleSharedProcessor()
PROCESSOR.execute_shell()
You could copy and paste this boilerplate and just put your code into main()
, and replace the input/output variables, and run it.
If your custom processor needs to download anything from the internet, use URLGetter
as your base class. Otherwise, use Processor
.
All processors must be within AutoPkg's search paths to be found. Generally speaking, any custom processor needs to be in one of two places:
- Within the same folder as the recipes that use it (most common)
- In a shared folder with a stub recipe so it can located by identifier (see Shared Processors)
If the custom processor is in the same folder as the recipe, you can just use class name directly in your recipe. Note that the .py
source file name must match the class name exactly.
Example: recipes/Mozilla Firefox.download uses a custom processor MozillaURLProvider. The processor invocation within the recipe looks like this:
<dict>
<key>Arguments</key>
<dict>
<key>product_name</key>
<string>firefox</string>
<key>release</key>
<string>%RELEASE%</string>
<key>locale</key>
<string>%LOCALE%</string>
</dict>
<key>Processor</key>
<string>MozillaURLProvider</string>
</dict>
The Processor
key simply calls MozillaURLProvider
, which is also the name of the custom processor class.
See Processor Locations for more details.
The Processor class comes with the convenience function execute_shell()
. This function allows you to run a processor as a standalone script via the command line, which is helpful when developing, testing, or debugging a custom processor.
# Set processor required variables in the plist
defaults write /tmp/processor.plist ARTICLE_NUMBER '1888'
# Enable SSJ3 verbose
defaults write /tmp/processor.plist verbose -int 3
# Ensure the plist is in XML format (as of writing this, the code only expects XML format, not binary [or json])
plutil -convert xml1 /tmp/processor.plist
# Ensure your PYTHONPATH includes the AutoPkg libraries
export PYTHONPATH=/Library/AutoPkg
# Run your custom processor
/Library/AutoPkg/Python3/Python.framework/Versions/Current/bin/python3 ${HOME}/src/autopkg/n8felton-recipes/SharedProcessors/AppleSupportDownloadInfoProvider.py < /tmp/processor.plist
# Ensure your PYTHONPATH includes the AutoPkg libraries
export PYTHONPATH=/Library/AutoPkg
# Run your custom processor
/Library/AutoPkg/Python3/Python.framework/Versions/Current/bin/python3 ${HOME}/src/autopkg/n8felton-recipes/SharedProcessors/AppleSupportDownloadInfoProvider.py ARTICLE_NUMBER=1888 verbose=3
# Press CTRL-D to send EOF to Python waiting for stdin input. (Improvement for later).
AppleSupportDownloadInfoProvider: Article URL: https://support.apple.com/kb/DL1888
AppleSupportDownloadInfoProvider: Download URL: https://support.apple.com/downloads/DL1888/en_US/&
AppleSupportDownloadInfoProvider: Full URL: https://updates.cdn-apple.com/2019/cert/041-88763-20191011-6e70f498-9d39-420c-b11b-b252b17233e2/HewlettPackardPrinterDrivers.dmg
AppleSupportDownloadInfoProvider: Article title: HP Printer Drivers v5.1 for OS X
AppleSupportDownloadInfoProvider: Version: 5.1
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>ARTICLE_NUMBER</key>
<string>1888</string>
<key>article_url</key>
<string>https://support.apple.com/kb/DL1888</string>
<key>url</key>
<string>https://updates.cdn-apple.com/2019/cert/041-88763-20191011-6e70f498-9d39-420c-b11b-b252b17233e2/HewlettPackardPrinterDrivers.dmg</string>
<key>verbose</key>
<integer>3</integer>
<key>version</key>
<string>5.1</string>
</dict>
</plist>
- Introduction
- Getting Started
- Overview of Using AutoPkg
- FAQ
- More Resources
- Removing AutoPkg
-
AutoPkg Reference
- Preferences
- Recipes
- Processors
-
Processor Reference
- AppDmgVersioner
- AppPkgCreator
- BrewCaskInfoProvider
- CodeSignatureVerifier
- Copier
- CURLDownloader
- CURLTextSearcher
- DeprecationWarning
- DmgCreator
- DmgMounter
- EndOfCheckPhase
- FileCreator
- FileFinder
- FileMover
- FlatPkgPacker
- FlatPkgUnpacker
- GitHubReleasesInfoProvider
- Installer
- InstallFromDMG
- MunkiCatalogBuilder
- MunkiImporter
- MunkiInfoCreator
- MunkiInstallsItemsCreator
- MunkiOptionalReceiptEditor
- MunkiPkginfoMerger
- MunkiSetDefaultCatalog
- PackageRequired
- PathDeleter
- PkgCopier
- PkgCreator
- PkgExtractor
- PkgInfoCreator
- PkgPayloadUnpacker
- PkgRootCreator
- PlistEditor
- PlistReader
- SparkleUpdateInfoProvider
- StopProcessingIf
- Symlinker
- Unarchiver
- URLDownloader
- URLDownloaderPython
- URLGetter
- URLTextSearcher
- Versioner
- Development