Python scripting allows you to incorporate familiar coding patterns directly into your workflows. You can write and execute your own Python logic to process data, apply conditions, or extend automation capabilities beyond built-in actions. This flexibility makes it easy to adapt workflows to complex or unique business requirements.
Torq offers four Python scripting steps to integrate seamlessly into your workflows, giving you the flexibility to reuse existing Python code or build custom logic to meet your automation needs.
All Python script steps come with:
Python Standard Library
pyOpenSSL
crcmod
requests
You can also use the optional REQUIREMENTS
variable to install additional packages as needed.
Available Script Steps
Run an inline Python Script: Ideal for general-purpose scripting and API interactions. Includes Python 3.13 with the standard set of pre-installed packages listed above.
Run a Python Data Processing Script: Best for data wrangling, transformation, and Excel file manipulation. Extends the base environment (Python 3.11) with the following additional packages:
pandas
numpy
openpyxl
Run a Python Script with Database Tools: Useful for querying, inserting, or analyzing data stored in external databases. Includes all packages from the Data Processing step, plus database connectivity tools:
psycopg
(PostgreSQL)PyMySQL
(MySQL)pymssql
(Microsoft SQL Server)
Run a Python IOC Extraction Script: Perfect for extracting Indicators of Compromise (IOCs) and structuring threat-related data. Specialized for security automation and threat intelligence parsing, pre-installed with Python 3.9 and the following packages:
ioc-finder
msticpy
pydantic
jinja2
ruamel.yaml
python-json-logger
Working with Python Scripts in Workflows
Python scripting in Torq workflows often involves passing data between steps, printing values for visibility, returning parameters for use downstream etc. To help you get started, this section includes practical script samples that show common patterns.
Passing Values from Previous Steps into a Python Script
To use a value from a previous step in your Python script, Torq supports the following templating syntax:
{{ $.<step_name>.<output_field> }}
When configuring your Python step, simply paste your script into the input field and reference variables using this format. A string can be enclosed in single quotes "..."
, but if it contains newlines, it must be wrapped in triple quotes """..."""
. JSON data doesn’t always need to be treated as a string, it depends on the script and how the input is being handled.
Examples
If you have a step named
get_data
and want to access itsresult
output, your script would look like:data = """{{ $.get_data.result }}"""
print(f"Data from previous step: {data}")If you have a previous step named "Get IP Information" and want to print its result, your Python script would look like this:
print("IP Information:", $.get_ip_information.result)
Use the autocomplete feature when typing {{ $...
to quickly locate and insert the correct variable path.
Returning a Parameter from a Python Script in Workflows
To pass a value from a Python script to subsequent steps in your Torq workflow, follow these steps:
Add a Python Step: Go to the Scripting category under Public steps, and drag the Python step into your workflow.
Write Your Script:
In the script editor, write your logic as needed.
Assign the value you want to pass to a variable.
Use the
print()
function to return that value. For example:
result = "Hello, Torq!" print(result)
Torq captures anything printed to
stdout
, making it accessible to later steps.Access the Output in the Next Step:
In any subsequent step, reference the Python step’s output using the
$.
notation.Use autocomplete to easily construct the correct path.
For example, if your Python step is named
"My Python Step"
, you can access its output like this:
$.my_python_step.stdout
Test Your Workflow: Run the workflow to ensure the Python script's output is correctly passed and available to the next step.
Pass Output Downstream with an Exit Operator (Optional):
Add or edit the Exit operator in your workflow.
Create an output schema:
Add parameters (e.g.,
summary
,score
,success_flag
).Choose the correct type: Text, Number, Boolean, etc.
Optionally add a short description for clarity.
Reference values from your Python step (e.g.,
{{ $.my_python_step.stdout }}
) in your Exit fields.
Make sure all Exit operators in your workflow are aligned in structure to ensure smooth output handling.
Throwing an Exception with a Successful Step Status in Inline Python
Sometimes you might want a Python step to raise an error but still exit with a successful status (code 1
) so that the workflow continues. This is useful for logging exceptions, skipping logic, or controlling flow without halting the automation.
Raise an exception in your inline Python code:
raise Exception("Something went wrong, but keep going.")
Set the step's execution to ignore failure:
In the step configuration, go to Execution Options.
Set Ignore failure to Yes.
By raising an exception and ignoring the failure, the step will complete with a status code of 1, which Torq interprets as a successful execution, even though the Python code encountered an issue. This lets the workflow proceed while still capturing the error event.
Making Inline Python Exit Gracefully in Workflows
When using inline Python in Torq workflows, it’s important to ensure your scripts exit cleanly and produce readable output. A graceful exit means no unnecessary errors, no cluttered logs, and consistent behavior for downstream steps. These practices help your Python code run smoothly within the workflow, exiting without unintended exceptions, outputting only the data you want, and maintaining clean, predictable logs that integrate seamlessly with subsequent steps.
Format Lists for Output
If you’re printing a list or multiple elements, consider joining them into a single string:
limited_usernames_str = ''.join(limited_usernames) print(limited_usernames_str)
This gives you a flat, clean output without Python list formatting artifacts like brackets or commas.
Set Variables and Output Readably
You can set variables within the script to structure your logic before outputting results. For example:
ADDRESSES = ["1600 Pennsylvania Avenue", "10 Downing Street", "75 Rue de Varenne"]
print(f"Got {len(ADDRESSES)} addresses")
for address in ADDRESSES:
print(address)
This approach helps you provide helpful context, control output structure, and keep logs clean, all while exiting without error.
Importing a Workspace Variable in a Python Step
You can use workspace variables in Python steps just like other dynamic inputs in a Torq workflow. This lets you reference shared, environment-specific values such as API tokens, org-wide configurations, or custom constants without hardcoding them.
This is useful for:
Keeping sensitive info centralized and reusable
Making workflows more portable across environments
How to Use a Workspace Variable
To access a workspace variable inside a Python script:
Use the syntax
{{ $.workspace_variables.VARIABLE_NAME }}
.Paste it directly into your Python code where the value is needed.
Example
Let’s say you have a workspace variable named API_KEY
. You can use it like this in your Python step:
api_key = "{{ $.workspace_variables.API_KEY }}"
print(f"My API key is: {api_key}")
Exporting a List from a Python Script
If you need to pass a list created in a Python script to other steps in your workflow, you can do so by using the Set a Variable step right after your Python step. This lets you easily reuse structured list data across your workflow, such as for loops, filtering, or sending notifications.
Create your list in a Python step: Write and print your list in the Python scripting step. For example:
usernames = ["alice", "bob", "carol"]
print(usernames)Add a “Set a Variable” step: Drag the Set a Variable step onto your canvas after the Python step.
Configure the variable:
Choose a name for the variable (e.g.,
user_list
).Set the data type to Array.
Use the Python step’s output (e.g.,
{{ $.python_step.stdout }}
) as the value.
Install packages if needed: If your Python script relies on additional packages, use the
REQUIREMENTS
variable to list them.
Checking the File Format of Python Step Output
When your Python script generates output that’s best handled as a file (e.g., CSV, PDF, or image), you can use the Return Response as File option in Torq to treat the output accordingly. For details on handling files in Torq workflows, refer to the relevant KB article.
Enable File Output: In your Python step’s Execution Options, set “Return Response as File” to Yes.
View the Output: After the step executes, the result will include a file URL, typically in one of the following formats:
Internal:
tqfile://steps/XXXXXXX
Shareable:
https://link.torq.io/***dEjnLCXnv7
Check File Metadata: Open the Execution Log to see the file’s metadata, including the
ContentType
(e.g.,application/pdf
,image/png
,text/csv
).Access File in Next Step: Use the following expression in downstream steps to work with the file:
{{ file $.step_name.api_object.url }}
Use the
file
function when working with internal links; it isn’t required for shareable links.
Use Cases
Exporting reports as Excel or CSV files
Generating PDFs with summaries or charts
Handling binary outputs like images or logs
This approach is ideal for workflows with large or structured data output, and ensures smooth file handling from generation to downstream usage.
Related Resources
Using Nested JSON in Python Scripts within Workflows
Using nested JSON in Torq’s Python scripting steps is straightforward if you apply the right formatting and escaping rules. Make sure to escape JSON only when there’s a risk that the structure could break (for example, if it contains special characters).
If your JSON is already valid and properly formatted, you don’t need to escape or unescape it, just parse it directly in your script.
Escape Your JSON String:
To prevent syntax errors or code injection, your JSON string must be properly escaped.
Use the
jsonEscape
function or the Escape JSON string step in the String Utils section to prepare your data.
Load JSON in Python: Once escaped, use
json.loads()
to convert the JSON string into a Python object for manipulation. For example:import json
json_data = json.loads('''{{ $.your_json_data }}''')
# Access nested values like:
# json_data['key']['nested_key']Replace Placeholder: Be sure to replace
your_json_data
with the actual path to your JSON data (e.g., another step’s output).
Once loaded, you can use standard Python operations to loop through arrays, extract keys, or transform the data into other formats such as CSV.
Related Resources
Triggering Torq Webhook with Authentication from Python
You can trigger a Torq Webhook directly from a Python script. This is useful for testing, integrating external systems, or extending workflow functionality. Torq Webhook authentication headers are fully configurable, allowing you to define any header key-value pair as your auth method.
The example below shows how to configure your Webhook URL, authentication headers, and JSON payload in Python. If your Webhook does not require authentication, simply remove the headers=headers
part of the requests.post()
line.
import requests import json
# Define the URL to which the JSON data will be sent
url = "{{ $.workflow_parameters.url_for_torq_webhook }}"
# Define the JSON payload you want to send
data = {{ $.workflow_parameters.json_to_send }}
# Define the Header Auth payload you want to send
headers = {
'{{ $.workflow_parameters.torq_auth_header_name }}':
'{{ $.workflow_parameters.torq_auth_header_secret }}'
}
# Send a POST request with the JSON data
response = requests.post(url, headers=headers, json=data)
# Capture and print the response status code
status_code = response.status_code
print(json.dumps({'Status Code': status_code}))
Resolving null
Reference Errors in Inline Python Scripts
If you encounter the error NameError: name 'null' is not defined
in an inline Python script step, it means Python is trying to interpret null
. Unlike JSON, Python doesn’t recognize null
, it uses None
to represent a null or empty value. Replacing null
with None
in your script will resolve the issue and allow the workflow to run correctly.
This error also occurs if you directly reference the output of a step inside a Python script to create a JSON variable. For example:
json_data = {{ $.collect_ip_reputation.result }} print(json.dumps(json_data), end=' ')
The following error message will be displayed: NameError: name 'null' is not defined
.
Fix
The simplest way to resolve this error when working with JSON data is to load the data into your Python script as a multi-line string, then parse it properly using Python’s json.loads()
. This makes sure JSON values like null
are properly converted into Python’s None
, ensuring clean, valid JSON parsing within your Torq workflow.
import json
string_json_data = '''
{{ $.collect_ip_reputation.result }}
'''
json_data = json.loads(string_json_data)
print(json.dumps(json_data), end='')
Handling the Unexpected Newline in Python Print Statements
When writing Python scripts in Torq workflows, you may sometimes notice an extra newline character (\\n
) appearing in your output. This happens because Python’s built-in print()
function automatically appends a newline at the end of its output. While this is convenient in many cases, it can disrupt formatting, especially if you build strings from multiple elements or need compact output.
Solution: Control Newlines with end
To prevent the default newline, you can use the end
argument in print()
. For example:
usernames = ["Alice", "Bob", "Charlie"]
# Default behavior (adds a newline)
print(usernames)
# Suppressing the newline
print(usernames, end='')
Here, end=''
overrides the default newline, so the output prints inline.
Alternative: Join Elements with join()
If you need to combine list elements into a single string, the join()
method is often a better choice. For example:
limited_usernames = ["David", "Emily", "Fred"]
# Join elements into a single string
limited_usernames_str = ''.join(limited_usernames) print(limited_usernames_str)
This approach gives you more control over separators (e.g., commas, spaces, or no separator at all) and avoids unwanted line breaks.
Extra Tip: Debugging with pprint
If your goal is debugging rather than formatting output, consider using Python’s pprint
library. It provides a more detailed representation of data structures, though it may not be ideal for final output formatting.