Integrate custom Python code [WIP]

How to create custom tasks using pure Python code without external commands.

The PythonRunner class allows you to create custom Secator tasks using pure Python code, without needing to integrate external command-line tools. This is useful when you want to:

  • Process data using Python libraries

  • Implement custom logic that doesn't require external commands

  • Create lightweight tasks that perform transformations or analysis

  • Build tasks that interact with APIs or databases


Overview

To create a custom Python task, you need to:

  1. Create a Python file in ~/.secator/templates/ (for user tasks) or secator/tasks/ (for development)

  2. Inherit from the PythonRunner class

  3. Decorate your class with the @task() decorator

  4. Define input_types and output_types

  5. Implement the yielder() method to yield results


Basic structure

Here's the minimal structure of a Python task:

Important notes:

  • The class name must match the filename (without .py)

  • The @task() decorator is required

  • You must inherit from PythonRunner

  • The yielder() method is where your task logic goes

  • Use yield to return results as output types


Available input types

You can specify which input types your task accepts using input_types. Available input types include:

  • HOST - Hostnames or domains

  • URL - URLs

  • IP - IP addresses

  • CIDR_RANGE - CIDR ranges

  • EMAIL - Email addresses

  • PATH - File paths

  • STRING - Generic strings

  • None - Accept any input type

Example:


Available output types

Your task can yield various output types. Common ones include:

  • Info - Informational messages

  • Url - URLs

  • Ip - IP addresses

  • Port - Network ports

  • Subdomain - Subdomains

  • Vulnerability - Security vulnerabilities

  • Tag - Tags/metadata

  • Domain - Domains

  • Record - DNS records

  • Certificate - SSL certificates

  • UserAccount - User accounts

  • Warning - Warning messages

  • Error - Error messages

Example:


Example: Simple URL processor

This example processes URLs and extracts information:

Usage:


Example: Vulnerability scanner

This example demonstrates yielding vulnerabilities:


Example: Task with custom options

You can define custom options that users can pass to your task:

Usage:


Example: Task without inputs

Some tasks don't require inputs. Use default_inputs to make inputs optional:

Usage:


Accessing runner properties

In your yielder() method, you have access to several useful properties:

  • self.inputs - List of input values

  • self.run_opts - Dictionary of run options (including custom opts)

  • self.name - Task name

  • self.config - Task configuration

  • self.context - Runner context

Example:


Advanced: Multiple output types

You can yield different output types based on your logic:


Task discovery

Secator automatically discovers tasks from:

  • User tasks: ~/.secator/templates/*.py

  • Development tasks: secator/tasks/*.py (when developing Secator itself)

The task class name must match the filename (case-sensitive). For example:

  • File: ~/.secator/templates/mytask.py → Class: mytask

  • File: secator/tasks/urlparser.py → Class: urlparser

After creating your task file, Secator will automatically discover it on the next run.


Best practices

  1. Use descriptive class names: Choose names that clearly indicate what the task does

  2. Add docstrings: Document what your task does in the class docstring

  3. Set appropriate tags: Use tags to categorize your task for better discoverability

  4. Handle errors gracefully: Use Warning or Error output types for error conditions

  5. Yield progress information: Use Info messages to provide feedback during long-running tasks

  6. Validate inputs: Check input validity before processing

  7. Use appropriate output types: Choose the most specific output type for your results


Testing your task

You can test your task from the command line:

Or use it programmatically:


Common patterns

Pattern: Processing with external libraries

Pattern: API integration

Pattern: Data transformation


Troubleshooting

Task not discovered

  • Ensure the filename matches the class name exactly

  • Check that the file is in ~/.secator/templates/ or secator/tasks/

  • Verify the @task() decorator is present

  • Make sure the class inherits from PythonRunner

Validation errors

  • If you get "Input is empty" errors, set default_inputs = '' for tasks that don't need inputs

  • For tasks that accept multiple inputs, ensure you're running with a worker (multiple inputs aren't supported in non-worker mode)

Import errors

  • Ensure all required Python packages are installed

  • Check that imports are correct and available in your environment

Last updated