Write custom extension scripts using the Code42 CLI and py42
While the Code42 CLI aims to provide an easy way to automate many common Code42 tasks, there will likely be times when you need to script something the CLI doesn’t have out-of-the-box.
To accommodate for those scenarios, the Code42 CLI exposes a few helper objects in the code42cli.extensions
module
that make it easy to write custom scripts with py42
that use features of the CLI (like profiles) to reduce the amount
of boilerplate needed to be productive.
Before you begin
The Code42 CLI is a python application written using the click framework,
and the exposed extension objects are custom click
classes. A basic knowledge of how to define click
commands,
arguments, and options is required.
The sdk_options
decorator
The most important extension object is the sdk_options
decorator. When you decorate a command you’ve defined in your
script with @sdk_options
, it will automatically add --profile
and --debug
options to your command. These work the
same as in the main CLI commands.
Decorating a command with @sdk_options
also causes the first argument to your command function to be the state
object, which contains the initialized py42 sdk. There’s no need to handle user credentials or login, the sdk_options
does all that for you using the CLI profiles.
The script
group
The script
object exposed in the extensions module is a click.Group
subclass, which allows you to add multiple
sub-commands and group functionality together. While not explicitly required when writing custom scripts, the script
group has logic to help handle and log any uncaught exceptions to the ~/.code42cli/log/code42_errors.log
file.
If only a single command is added to the script
group, the group will default to that command, so you don’t need to
explicitly provide the sub-command name.
An example command that just prints the username and ID that the sdk is authenticated with:
import click
from code42cli.extensions import script, sdk_options
@click.command()
@sdk_options
def my_command(state):
user = state.sdk.users.get_current()
print(user["username"], user["userId"])
if __name__ == "__main__":
script.add_command(my_command)
script()
Ensuring your script runs in the Code42 CLI python environment
The above example works as a standalone script, if it were named my_script.py
you could execute it by running:
python3 my_script.py
However, if the Code42 CLI is installed in a different python environment than your python3
command, it might fail to
import the extensions.
To workaround environment and path issues, the CLI has a --python
option that prints out the path to the python
executable the CLI uses, so you can execute your script with$(code42 --python) script.py
on Mac/Linux or
&$(code42 --python) script.py
on Windows to ensure it always uses the correct python path for the extension script to
work.
Installing your extension script as a Code42 CLI plugin
The above example works as a standalone script, but it’s also possible to install that same script as a plugin into the main CLI itself.
Assuming the above example code is in a file called my_script.py
, just add a file setup.py
in the same directory
with the following:
from distutils.core import setup
setup(
name="my_script",
version="0.1",
py_modules=["my_script"],
install_requires=["code42cli"],
entry_points="""
[code42cli.plugins]
my_command=my_script:my_command
""",
)
The entry_points
section tells the Code42 CLI where to look for the commands to add to its main group. If you have
multiple commands defined in your script you can add one per line in the entry_points
and they’ll all get installed
into the Code42 CLI.
Once your setup.py
is ready, install it with pip while in the directory of setup.py
:
$(code42 --python) -m pip install .
Then running code42 -h
should show my-command
as one of the available commands to run!