Skip to main content

Requesting Help in Structuring JSON in the action "CSV_Save Json To CSV"

  • October 15, 2024
  • 2 replies
  • 10 views

Aravind3
Forum|alt.badge.img+8

Hello Everyone,

I'm developing/testing a block which summarizes the results from multiple TIs like AbuseIPDB, Virustotal etc from a playbook and prints the result in CSV file in case wall.

I'm getting this error from when I'm testing the playbook with this block and if I try to structure JSON I'm not getting the expected result. Could anyone please let me know what am I doing wrong here?

Result:

Please ignore the domain data.


Thanks a bunch in advance,
Aravind Sreekumar

2 replies

Forum|alt.badge.img+12

As a troubleshooting step you could take you above combined JSON Object and just try writing it to a JSON widget in a simulated case to verify if valid JSON is being generated or not. 

You can then also try doing one TI JSON result at a time to see if it's a specific result that is causing the error.


AnimSparrow
Forum|alt.badge.img+4
  • Bronze 1
  • February 21, 2026

You can adjust or write your IDE to be able to create tables based on json intput or create something that will check if json got valid structure. Example code for generating csv based on json input. Code might not  be perfect but show a glance of it.

 

import json
import base64
import requests
import csv
from io import StringIO
from SiemplifyAction import SiemplifyAction
from SiemplifyUtils import output_handler
from ScriptResult import EXECUTION_STATE_COMPLETED, EXECUTION_STATE_FAILED

def create_attachment(siemplify, file_content, file_name):
"""Adds the generated CSV as evidence to the case."""
conf = siemplify.get_configuration("FileUtilities")
verify_ssl = True if conf.get("Verify SSL", "False").casefold() == "true" else False

# Encode content to base64 for the API request
base64_blob = base64.b64encode(file_content.encode("utf-8")).decode("utf-8")
case_id = int(siemplify.case.identifier)

headers = {"AppKey": siemplify.api_key, "Content-Type": "application/json"}
body = {
"CaseIdentifier": case_id,
"Base64Blob": base64_blob,
"Name": file_name,
"Description": "CSV report generated from JSON data.",
"Type": ".csv",
"IsImportant": False,
}

response = requests.post(
f"{siemplify.API_ROOT}/external/v1/cases/AddEvidence/",
json=body,
headers=headers,
verify=verify_ssl,
)
return response

@output_handler
def main():
siemplify = SiemplifyAction()
siemplify.script_name = "CSV Report Generator"

raw_json_input = siemplify.extract_action_param("JSON Result", is_mandatory=True)
report_title = siemplify.extract_action_param("Report Title", default_value="Report")

try:
# Parse input data
data = json.loads(raw_json_input) if isinstance(raw_json_input, str) else raw_json_input

if not isinstance(data, list) or len(data) == 0:
siemplify.end("No data found to generate CSV.", "false", EXECUTION_STATE_FAILED)

# Extract headers dynamically from the first JSON object
headers = list(data[0].keys())

# Generate CSV content in memory
output = StringIO()
writer = csv.DictWriter(output, fieldnames=headers, quoting=csv.QUOTE_ALL)

writer.writeheader()
for row in data:
# Flatten dictionaries or lists to strings to maintain CSV integrity
cleaned_row = {
k: (json.dumps(v) if isinstance(v, (dict, list)) else v)
for k, v in row.items()
}
writer.writerow(cleaned_row)

csv_content = output.getvalue()

# Attach the CSV to the case
file_name = f"{report_title.replace(' ', '_')}.csv"
response = create_attachment(siemplify, csv_content, file_name)

if response.status_code != 200:
raise Exception(f"Failed to attach file: {response.text}")

output_message = f"Successfully generated CSV with {len(data)} rows."
siemplify.end(output_message, "true", EXECUTION_STATE_COMPLETED)

except Exception as e:
output_message = f"Error: {str(e)}"
siemplify.LOGGER.error(output_message)
siemplify.end(output_message, "false", EXECUTION_STATE_FAILED)

if __name__ == "__main__":
main()