Python Script

This guide demonstrates the basic concepts around creating and executing a Python script service within torero.

Prerequisites

It is a prerequisite that a Git repository be setup with a Python script within it. Review the Create Repository command to understand on how to create a repository.

Create

torero create servuce python-script will perform a creation of the Python script service. A more detailed guide of all creation options is available there but this guide should help get you started.

The command shown below creates a Python script service within the torero called simple-python. We are leveraging a repository that would have been previously configured called torero-resources.

>_ torero create service python-script simple-python --repository torero-resources --working-dir pythonscripts --filename main.py

It is important to stop and understand the structure of torero-resources before moving further.

torero-resources (git repo)

├── README.md
├── ansibleplaybooks
├── pythonscripts
│   ├── main.py
│   └── requirements.txt
└── opentofuplans

We specified that we want to use torero-resources via the --repository flag.

Notice that our Python script exist in a directory called pythonscripts. We denoted this using the --working-dir flag.

Inside the pythonscripts directory, we have an actual script called main.py. We denoted this with the --filename flag.

If your Python script requires external libraries you can place a requirements.txt file within the working directory. torero will automatically manage the dependencies for you.


Verify Creation

We can view details about the previously created Python script service by running the describe service command.

>_ torero describe simple-python
Output:

Name:        simple-python
Repo Name:   torero-resources
Working Dir: pythonscripts
FileName:    main.py
Decorator:   
Description: 
Tags:

Execution

Executing a Python script is simple from torero by utilizing the run python-script command.

Consider the contents of our main.py Python script shown below

# main.py
from netmiko import ConnectHandler
import argparse

def main():
    parser = argparse.ArgumentParser(description="Netmiko Command Service")
    parser.add_argument('--command', required=True, help="Command to run")
    parser.add_argument('--host', required=True, help="Host to connect to")
    args = parser.parse_args()
    # YOUR EXECUTION CODE GOES BELOW THIS LINE    

    cisco1 = {
        "device_type": "cisco_ios",
        "host": args.host
    }
    with ConnectHandler(**cisco1) as net_connect:
        output = net_connect.send_command(args.command)

    print(output)

if __name__ == "__main__":
    main()

Our script requires the netmiko library. This is specified in the requirements.txt file located in the services working-dir. Let's look at the contents of our requirements.txt file below.

netmiko==4.3.0

When executing a Python script using the run command, torero will automatically look for a requirements.txt file in the working directory that was specified during the service's creation. torero will then create the virtual environment with all the dependencies specified in the requirements.txt and execute the script within that virtual environment. This is a very powerful feature that allows for easy management of Python dependencies.

We can observe that oru script takes in two inputs: command abd host. They can be specified using the --set flag.

>_ torero run python-script simple-python --set host=10.0.0.1 --set command="show version"
Output:

Start Time:   2024-01-01T12:00:00Z
End Time:     2024-01-01T12:00:01Z
Elapsed Time: 1.372672s
Return Code: 0
================================================================================
                           System Version Information
================================================================================

...truncated for document

Stderr:

In the backend, torero will take they key=values defined via the --set command on the run command and pass it to the Python service. In our example, the following command would be run by torero in the backend: <python-executable> main.py --host=10.0.0.1 --command="show version".

Barebones Script With Inputs

The most important part of working with a Python script is how to get the arguments into the script. The contract between torero and a Python service is the ability to read key=value from the command line. Every Python script that is written will have something that looks like the following Python code. You can follow the barebones example to get started with accepting input arguments.

# main.py
import argparse


def main():
    parser = argparse.ArgumentParser(description="torero example")
    parser.add_argument('--name', required=True, help="Name to greet")
    args = parser.parse_args()
    name = args.name
    # YOUR EXECUTION CODE GOES BELOW THIS LINE    

    print(f"Hello, {name}")

if __name__ == "__main__":
    main()

Behind The Scenes

Below is a flowchart depicting the steps torero moves through as it manages the dependencies for a Python based service. You do not need to understand this to use torero, but it can be an interesting reference.

flowchart TD A[Start Python Service] --> B{"Does requirements.txt exist?"} B -- No --> K[Find Python Interpreter] B -- Yes --> C[Get contents of requirements.txt] C --> D{"Does venv with this content?"} D -- No --> E[Find Python Interpreter] E --> F[Create Virtualenv] F --> G[Install Requirements] D -- Yes --> I[Use existing venv] G --> I I --> J[Run Python Script with venv] K --> L[Create Virtualenv] L --> J

Decorators

It is possible to put restrictions around the inputs that are accepted by a Python script by utilizing decorators. For more information on decorators in general, please refer to this guide.

CLI Reference

Python Script Create

Python Script Run

Services Get

Service Describe

Service Delete