HelloWorldV2

Use the Hello World v2 integration to learn how to build and configure Cortex integrations.

Utilities · HelloWorld

Details

IDHelloWorldV2
ProviderOpen Source
CategoryUtilities
From Version6.8.0
Docker Imagedemisto/fastapi:0.125.0.10158186
Supported ModulesAgentix XSIAM Exposure Management

README

Overview

This is the Hello World v2 integration for getting started.

Configure Hello World v2 in Cortex

Parameter Description Required
Server URL (e.g., https://api.dummy-example.com) Default is https://api.dummy-example.com. True
API Key   True
Trust any certificate (not secure)   False
Use system proxy settings   False
Score threshold for IP reputation command The minimum HelloWorld score required to mark an IP as malicious (0-100). Default is 65. False
Source Reliability Reliability of the source providing the intelligence data. Possible values are: A+ - 3rd party enrichment, A - Completely reliable, B - Usually reliable, C - Fairly reliable, D - Not usually reliable, E - Unreliable, F - Reliability cannot be judged. Default is C - Fairly reliable. False
First fetch time The time from which to start fetching alerts. Supports relative time (e.g., “3 hours ago”) or ISO 8601 format (e.g., “2025-12-01T00:00:00Z”). Default is 3 days. False
Severity of alerts to fetch Possible values are: low, medium, high, critical. Default is high. False
Fetch incidents Fetch HelloWorld alerts as incidents in Cortex XSOAR. Supported in Cortex XSOAR only. False
Incident type   False
Maximum number of incidents per fetch Default is 10. Supported in Cortex XSOAR only. False
Fetch events Fetch HelloWorld alerts as events in Cortex XSIAM. Supported in Cortex XSIAM only. False
Maximum number of events per fetch Default is 1000. Supported in Cortex XSIAM only. False
Fetch assets and vulnerabilities   False

Commands

You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.

helloworld-say-hello


Prints hello to a specified name.

Base Command

helloworld-say-hello

Input

Argument Name Description Required
name The name of the person you want to say hello to. Optional

Context Output

Path Type Description
HelloWorld.Hello.name String The greeting message returned by the command.

Command example

!helloworld-say-hello name="Dbot"

Context Example

{
    "HelloWorld": {
        "Hello": {
            "name": "Dbot"
        }
    }
}

Human Readable Output

Hello Dbot

helloworld-alert-list


Lists example alerts as they would appear in a fetch operation.

Base Command

helloworld-alert-list

Input

Argument Name Description Required
alert_id Filter the fetch by alert ID. If not specified, all alert IDs will be retrieved. Optional
limit How many alerts to fetch. Default is 10. Optional
severity The severity by which to filter the alerts. Possible values are: low, medium, high, critical. Optional

Context Output

Path Type Description
HelloWorld.alert.id Number The ID of the alert.
HelloWorld.alert.name String The name of the alert.
HelloWorld.alert.severity String The severity of the alert.
HelloWorld.alert.date Date The date of the alert occurrence.
HelloWorld.alert.status String The status of the alert.

Command example

!helloworld-alert-list limit="3" severity="low"

Context Example

{
    "HelloWorld": {
        "Alert": [
            {
                "date": "2023-09-14T11:30:39.882955",
                "id": 1,
                "name": "XSOAR Test Alert #1",
                "severity": "low",
                "status": "Testing"
            },
            {
                "date": "2023-09-14T11:30:39.882955",
                "id": 2,
                "name": "XSOAR Test Alert #2",
                "severity": "low",
                "status": "Testing"
            },
            {
                "date": "2023-09-14T11:30:39.882955",
                "id": 3,
                "name": "XSOAR Test Alert #3",
                "severity": "low",
                "status": "Testing"
            }
        ]
    }
}

Human Readable Output

Items List (Sample Data)

date id name severity status
2023-09-14T11:30:39.882955 1 XSOAR Test Alert #1 low Testing
2023-09-14T11:30:39.882955 2 XSOAR Test Alert #2 low Testing
2023-09-14T11:30:39.882955 3 XSOAR Test Alert #3 low Testing

Command example

!helloworld-alert-list alert_id=2

Context Example

{
    "HelloWorld": {
        "Alert": {
            "date": "2023-09-14T11:30:39.882955",
            "id": 2,
            "name": "XSOAR Test Alert #2",
            "severity": "low",
            "status": "Testing"
        }
    }
}

Human Readable Output

Items List (Sample Data)

date id name severity status
2023-09-14T11:30:39.882955 2 XSOAR Test Alert #2 low Testing

helloworld-alert-note-create


Create a note in the API.

Base Command

helloworld-alert-note-create

Input

Argument Name Description Required
alert_id The alert ID to add the note to. Required
note_text The text to add to the note. Required

Context Output

Path Type Description
HelloWorld.Note.status String The note creation status.
HelloWorld.Note.msg String The message from the note creation response.

Command example

!helloworld-alert-note-create alert_id=2 note_text=test

Context Example

{
    "HelloWorld": {
        "Note": {
            "msg": "Note was created for alert #2 successfully with comment: test",
            "status": "success"
        }
    }
}

Human Readable Output

Note was created successfully.

ip


The returned IP information and reputation.

Base Command

ip

Input

Argument Name Description Required
ip A comma-separated list of IPs. Required
threshold The score threshold used to determine if an IP is malicious. If not provided, the default threshold from the instance configuration is used. Default is 65. Optional

Context Output

Path Type Description
DBotScore.Indicator String The indicator that was tested.
DBotScore.Score Number The actual score.
DBotScore.Type String The indicator type.
DBotScore.Vendor String The vendor used to calculate the score.
HelloWorld.IP.asn String The autonomous system name (ASN) for the IP address.
HelloWorld.IP.asn_cidr String The network routing prefix in CIDR notation associated with the ASN.
HelloWorld.IP.asn_country_code String The two letter ISO country code associated with the ASN.
HelloWorld.IP.asn_date Date The date the ASN was assigned.
HelloWorld.IP.asn_description String The ASN description.
HelloWorld.IP.asn_registry String The registry the ASN belongs to.
HelloWorld.IP.entities String Entities associated to the IP.
HelloWorld.IP.ip String The actual IP address.
HelloWorld.IP.network.cidr String The network CIDR for the IP address.
HelloWorld.IP.network.country String The country of the IP address.
HelloWorld.IP.network.end_address String The last IP address of the CIDR.
HelloWorld.IP.network.events.action String The specific action recorded for the network (for example, registration or modification).
HelloWorld.IP.network.events.actor Unknown The actor (identifier or entity name) that performed the recorded action on the network.
HelloWorld.IP.network.events.timestamp String The date and time the event occurred.
HelloWorld.IP.network.handle String The unique registry identifier assigned to the network block.
HelloWorld.IP.network.ip_version String The IP address version.
HelloWorld.IP.network.links String Links associated to the IP address.
HelloWorld.IP.network.name String The name of the network.
HelloWorld.IP.network.notices.description String The description of the notice.
HelloWorld.IP.network.notices.links Unknown A list of URLs providing additional information or documentation related to the network notice.
HelloWorld.IP.network.notices.title String The title of a specific notice related to the network.
HelloWorld.IP.network.parent_handle String The unique registry identifier of the parent network from which this block was allocated.
HelloWorld.IP.network.raw Unknown Additional raw data for the network.
HelloWorld.IP.network.remarks Unknown Additional remarks for the network.
HelloWorld.IP.network.start_address String The first IP address of the CIDR.
HelloWorld.IP.network.status String The network status.
HelloWorld.IP.network.type String The type of the network.
HelloWorld.IP.query String The IP address that was queried.
HelloWorld.IP.raw Unknown Additional raw data for the IP address.
HelloWorld.IP.score Number The reputation score from HelloWorld for this IP (0 to 100, where higher is worse).
IP.Address String The IP address.
IP.Malicious.Vendor String The vendor reporting the IP address as malicious.
IP.Malicious.Description String A description explaining why the IP address was reported as malicious.
IP.ASN String The autonomous system name for the IP address.
IP.Relationships.EntityA string The source of the relationship.
IP.Relationships.EntityB string The destination of the relationship.
IP.Relationships.Relationship string The name of the relationship.
IP.Relationships.EntityAType string The relationship source type.
IP.Relationships.EntityBType string The relationship destination type.

Command example

!ip ip="8.8.8.8"

Context Example

{
    "DBotScore": {
        "Indicator": "8.8.8.8",
        "Reliability": "C - Fairly reliable",
        "Score": 3,
        "Type": "ip",
        "Vendor": "HelloWorld"
    },
    "HelloWorld": {
        "IP": {
            "id": "x.x.x.x",
            "ip": "8.8.8.8",
            "links": {
                "self": "https://www.virustotal.com/api/v3/ip_addresses/x.x.x.x"
            },
            "type": "ip_address"
        }
    },
    "IP": {
        "Address": "8.8.8.8",
        "Malicious": {
            "Description": "Hello World returned reputation -4",
            "Vendor": "HelloWorld"
        },
        "Relationships": [
            {
                "EntityA": "8.8.8.8",
                "EntityAType": "IP",
                "EntityB": "h",
                "EntityBType": "URL",
                "Relationship": "related-to"
            },
            {
                "EntityA": "8.8.8.8",
                "EntityAType": "IP",
                "EntityB": "x",
                "EntityBType": "URL",
                "Relationship": "related-to"
            }
        ]
    }
}

Human Readable Output

IP (Sample Data)

id ip links type
x.x.x.x 8.8.8.8 self: https://www.virustotal.com/api/v3/ip_addresses/x.x.x.x ip_address

Attributes

as_owner asn continent country jarm last_analysis_stats last_modification_date network regional_internet_registry reputation tags total_votes whois_date
EMERALD-ONION 396507 NA US :jarm: harmless: 72
malicious: 5
suspicious: 2
timeout: 0
undetected: 8
1613300914 :cidr: ARIN -4   harmless: 0
malicious: 1
1611870274

helloworld-get-events


Retrieves alerts from the HelloWorld API. Use this command for development and debugging only, as it may produce duplicate events, exceed API rate limits, or disrupt the fetch mechanism.

Base Command

helloworld-get-events

Input

Argument Name Description Required
severity The severity by which to filter the alerts. Possible values are: low, medium, high, critical. Required
start_time The time from which to start fetching alerts. Supports relative time (e.g., “3 hours ago”) or ISO 8601 format (e.g., “2025-12-01T00:00:00Z”). Optional
limit Maximum number of alerts to retrieve. Default is 10. Optional
should_push_events Whether to push events to Cortex XSIAM (for Cortex XSIAM tenants only). Possible values are: true, false. Default is false. Optional

Context Output

There is no context output for this command.

Command example

!helloworld-get-events severity="low" limit=3

Human Readable Output

HelloWorld Events

id severity user action date status
1 low userB@test.com Testing 2023-09-14T11:30:39.882955 Error
2 low userA@test.com Testing 2023-09-14T11:30:39.883955 Success
3 low userB@test.com Testing 2023-09-14T11:30:39.884955 Error

helloworld-job-submit


Submits a job to the HelloWorld API and polls for completion. Used for asynchronous APIs and long-running operations.

Base Command

helloworld-job-submit

Input

Argument Name Description Required
interval_in_seconds Interval in seconds between each poll. Default is 30. Optional
timeout_in_seconds Timeout in seconds until polling stops. Default is 600. Optional

Context Output

Path Type Description
HelloWorld.Job.id String The ID of the submitted job.
HelloWorld.Job.status String The current status of the job.
HelloWorld.Job.type String The type of job submitted.
HelloWorld.Job.msg String Message from the completed job.

Command example


#### Context Example

```json
{
    "HelloWorld": {
        "Job": {
            "id": "abc-123",
            "msg": "The configuration has successfully been updated.",
            "status": "complete",
            "type": "HelloWorldRefreshConfig"
        }
    }
}

Human Readable Output

HelloWorld Job abc-123 - Complete

id msg
abc-123 The configuration has successfully been updated.

helloworld-get-assets


Retrieves resources and assets in the HelloWorld environment.

Base Command

helloworld-get-assets

Input

Argument Name Description Required
limit Maximum number of assets to retrieve. Default is 10. Optional

Context Output

There is no context output for this command.

Command example

!helloworld-get-assets limit=3

Human Readable Output

HelloWorld Assets

id name type status created
1 Server-01 server active 2024-01-15T10:00:00
2 Database-01 database active 2024-01-16T11:30:00
3 Storage-01 storage active 2024-01-17T09:15:00

helloworld-get-vulnerabilities


Retrieves vulnerabilities found in the HelloWorld environment.

Base Command

helloworld-get-vulnerabilities

Input

Argument Name Description Required
limit Maximum number of vulnerabilities to retrieve. Default is 10. Optional

Context Output

There is no context output for this command.

Command example

!helloworld-get-vulnerabilities limit=3

Human Readable Output

HelloWorld Vulnerabilities

id cve_id severity description published
1 CVE-MOCK-0001 critical Remote code execution vulnerability 2026-01-10T08:00:00
2 CVE-MOCK-0002 high SQL injection vulnerability 2026-01-12T14:30:00
3 CVE-MOCK-0003 medium Cross-site scripting vulnerability 2026-01-14T16:45:00

Developer Guide

This section documents the key architectural patterns and code features in Hello World v2 and provides guidelines for building robust Cortex integrations.

Key Patterns and Features

Feature Description
Robust User Input Validation Type-safe configuration parameter and command argument validation with user-friendly error messages.
Modern API Client Uses the ContentClient, which provides enhanced reliability, observability, and developer experience features.
Polling / Scheduled Commands Commands that can schedule the future execution of other commands; suitable for periodically checking the status of a long-running external process or asynchronous task.
Centralized Execution Configuration A centralized object for commands, configuration params, command arguments, and fetch last run state to minimize redundant system calls.
Dual Fetch Incidents / Events Support A Unified flow for fetching Cortex XSOAR incidents and Cortex XSIAM events.
Fetch Assets and Vulnerabilities Support A flow for fetching a current snapshot of an environment’s resources and vulnerabilities in Cortex XSIAM.
Structured Logging A consistent, prefix-based Python f-string format that captures specific variable context, ensuring messages are easily searchable and facilitate efficient debugging of the execution flow.

How to Build an Integration

Below is a step-by-step guide on how to build an integration that implements a basic automation command and fetch flow.

  1. Import the Required Modules
  2. Define a Configuration Parameters Validation Model
  3. Create an API Client Class
  4. Implement Standard Automation Command Pattern
  5. Implement Standard Fetch Flow Pattern
  6. Setup Execution Configuration
  7. Define the Main Function

1. Import the Required Modules

At the top of the integration code file, import the required modules. This can include built-in Python modules such as enum, typing, and asyncio, as well as Content-related imports such as CommonServerPython and ContentClientApiModule.

# Use enumerations to group related constants or define all possible values of configuration parameter or command argument
# For example, severity values: critical, high, moderate, low, unknown
from enum import Enum

# Use `typing` and/or `collections.abc` for defining attribute types in validation models and for type hinting.
from typing import Any
from collections.abc import Awaitable

# Import `CommonServerPython` and `demisto` class, which contain many useful helper and utility functions
from CommonServerPython import *
import demistomock as demisto

# Optionally use `CommonServerUserPython` (for custom integrations) to override constants, functions, and classes defined in `CommonServerPython`
from CommonServerUserPython import *

# Import `ContentClientApiModule` to use the new `ContentClient` class, which contains improved error handling, thread safety, and authentication handling.
from ContentClientApiModule import *

# Add any other required imports depending on your code
from datetime import datetime, UTC, timedelta

2. Define a Configuration Parameters Validation Model

Define the schema that corresponds to the configuration parameters in the integration YML file.
Use Pydantic classes that inherit from ContentBaseModel (or its subclasses like BaseParams) for robust input validation with user-friendly error messages.

You can use an AI agent to automatically generate models from the configuration parameters defined in the integration YML file.

class Credentials(ContentBaseModel):
    """Credentials model for API authentication."""

    username: str
    password: SecretStr


class MyIntegrationParams(BaseParams):
    """Integration parameters with validation.
    
    Attributes:
        url: API base URL (trailing slash removed automatically).
        credentials: Username and password for API Authentication.
        max_fetch: Maximum incidents per fetch.
    """
    # `proxy` and `insecure` are already defined in `BaseParams`
    url: AnyUrl
    credentials: Credentials
    # Ensure attribute name matches the param `name` field value in the YML
    # To follow Python "snake_case" format, use an `alias` value for mapping to the `camelCase` param name in the YML
    is_fetch: bool | None = Field(default=False, alias="isFetch")  # corresponds to "Fetch incidents" checkbox
    first_fetch: str  = "1 week"
    max_fetch: int = 50

    @property
    def first_fetch_datetime(self) -> datetime:
        """Cast first fetch to a datetime object."""
        return arg_to_datetime(self.first_fetch) or (datetime.now(tz=UTC) - timedelta(weeks=1))

    @validator('url', reuse=True)
    def clean_url(cls, v) -> str:
        """Remove trailing slash from URL."""
        return v.rstrip('/')
    
    @validator('max_fetch', reuse=True)
    def validate_max_fetch(cls, v) -> int:
        """Check that max fetch is not above the permitted value."""
        max_fetch = arg_to_number(v)
        if max_fetch > 1000:
            raise ValueError("The maximum number of incidents per fetch must not be greater than 1000.")
        return max_fetch

3. Create an API Client Class

Create a MyIntegrationClient class that inherits from ContentClient to leverage built-in retry logic, rate limit handling, authentication, and thread safety.

For authentication, define a custom AuthHandler if needed or use any of the included ones in ContentClientApiModule such as APIKeyAuthHandler, BearerTokenAuthHandler, or BasicAuthHandler.

# Example client class that inherits from ContentClient and adds two integration-specific methods

class MyIntegrationClient(ContentClient):

    def __init__(self, params: HelloWorldParams):
        """Initialize client with ContentClient capabilities.

        Args:
            params (MyIntegrationParams): Validated integration configuration parameters.
        """
        credentials: Credentials = params.credentials
        super().__init__(
            base_url=params.url,
            verify=params.verify,
            proxy=params.proxy,
            auth_handler=BasicAuthHandler(username=credentials.username, password=credentials.password),
            client_name="MyIntegrationClient",
            diagnostic_mode=is_debug_mode(),  # enable if commands are run with `debug-mode=true`
        )

    def get_item_by_id(self, item_id: int) -> dict[str, Any]:
        """Get an item in MyIntegration by its ID.

        Args:
            item_id (int): Item ID.

        Returns:
            dict[str, Any]: Item dictionary.
        """
        endpoint = f"api/items/{item_id}"
        return self.get(endpoint)  # JSON response bodies are decoded by default

    def get_items_list(self, limit: int, start_time: str | None = None) -> list[dict]:
        """Get a list of items in MyIntegration up to the limit.

        Args:
            limit (int): Maximum number of items to return.
            start_time (str | None): Optional start time in ISO 8601 format.

        Returns:
            list[dict]: List of items.
        """
        endpoint = "api/items"
        query_params = assign_params(limit=limit, start_time=start_time)  # use `assign_params` to remove empty values
        return self.get(endpoint, params=query_params)

4. Implement Standard Automation Command Pattern

Define an arguments validation model and a command function for each command. Define additional (helper) functions if needed.

You can use an AI agent to automatically generate models from the command arguments defined in the integration YML file.

The code snippet below demonstrates how to implement a basic automation command.

See the following references for example implementations of more complex commands:

Type Example
Polling / scheduled command helloworld-job-poll command in Hello World v2
Generic reputation command ip command in Hello World v2
# Basic automation command example implementation

class MyIntegrationItemListArgs(BaseArgs):
    """Arguments for `my-integration-item-list` command.
    
    Attributes:
        item_id: Optional item ID to retrieve.
        limit: Maximum number of items to retrieve (default: 10).
    """
    item_id: int | None = None
    limit: int = 10


def my_integration_item_list_command(client: MyIntegrationClient, args: MyIntegrationItemListArgs) -> CommandResults:
    """Run `my-integration-item-list` command logic.

    Args:
        client (MyIntegrationClient): An initialized API client instance.
        args (MyIntegrationItemListArgs): Validated command arguments.

    Returns:
        CommandResults: Command results containing context and human-readable outputs.
    """

    if args.item_id:
        items = client.get_item_by_id(item_id=args.item_id)
    else:
        items = client.get_items_list(limit=args.limit)

    return CommandResults(
        outputs_prefix="MyIntegration.Item",  # Context output prefix
        outputs_key_field="id",  # Objects under the defined prefix will be deduplicated according to this field value
        outputs=items,  # The items to return to the context output
        readable_output=tableToMarkDown("My Integration Items", items),  # Human-readable entry to return to the war room
    )

5. Implement Standard Fetch Flow Pattern

The code snippet below demonstrates how to implement a basic fetch-incidents flow.

See the following references for example implementations of more complex fetch flows:

Type Example
Unified Cortex XSOAR fetch incidents and Cortex XSIAM fetch events fetch-incidents and fetch-events commands, respectively, in Hello World v2
Cortex XSIAM fetch assets flow fetch-assets command in Hello World v2
Fetch indicators fetch-indicators command in Hello World Feed
# Basic fetch-incidents example implementation

class MyIntegrationLastRun(BaseLastRun):
    """State management for fetch-incidents.
    
    Attributes:
        start_time: ISO 8601 timestamp of the last fetched item.
        last_item_ids: List of item IDs from the last fetch time to prevent duplicates.
    """
    start_time: str | None = None
    last_item_ids: list[int] = []


def fetch_incidents(
    client: MyIntegrationClient,
    last_run: MyIntegrationLastRun,
    max_fetch: int,
    first_fetch_datetime: datetime,
) -> MyIntegrationLastRun:
    """Fetch new items as incidents.

    Args:
        client (MyIntegrationClient): An initialized API client instance.
        last_run (MyIntegrationLastRun): Last run state from previous fetch invocation.
        max_fetch (int): Maximum number of incidents to fetch.
        first_fetch_datetime (datetime): Date from which to start fetching incidents.
    """
    default_batch_limit: int = 100
    start_time: str = last_run.start_time or first_fetch_datetime.isoformat()
    last_item_ids: list[int] = last_run.last_item_ids

    unique_items: list[dict] = []

    while len(unique_items) < max_fetch:
        # Send requests in batches to avoid exceeding the API's maximum `limit` value
        remaining_count = max_fetch - len(unique_items)
        batch_limit = min(default_batch_limit, remaining_count)
        items = client.get_items_list(limit=batch_limit, start_time=start_time)

        # Deduplication logic
        for item in items:
            if item["id"] in last_item_ids:
                continue
            unique_items.append(item)
    
    if unique_items:
        start_time = unique_items[-1]["time"]
        last_item_ids = [item["id"] for item in unique_items if item["time"] == start_time]
    
        # Formatting and incident creation logic
        incidents = format_as_incidents(unique_items)
        demisto.createIncidents(incidents)  # create incidents

    return MyIntegrationLastRun(start_time=start_time, last_item_ids=last_item_ids)

6. Setup Execution Configuration

Inherits from the BaseExecutionConfig class in BaseContentApiModule to centralize command execution context, prevent redundant system calls (via the demisto class), and provide type-safe access to configuration parameters, command arguments, and fetch last run state.

class MyIntegrationExecutionConfig(BaseExecutionConfig):

    @property
    def params(self) -> MyIntegrationItemListArgs:
        return MyIntegrationItemListArgs(**self._raw_params)

    @property
    def item_list_args(self) -> MyIntegrationItemListArgs:
        """Get validated arguments for `my-integration-item-list` command."""
        return MyIntegrationItemListArgs.get(**self._raw_args)

    @property
    def last_run(self) -> MyIntegrationLastRun:
        """Get validated last run object for `fetch-incidents` flow."""
        return MyIntegrationLastRun(**self._raw_last_run)

7. Define the Main Function

Define and implement a main() function, which would serve as the entrypoint into the integration logic.

This function should initialize the Execution Configuration and API Client classes and route to the implemented command functions.

def main():
    execution = ExecutionConfig()
    command: str = execution.command
    client = None

    try:
        params: MyIntegrationParams = execution.params
        client = MyIntegrationClient(params)

        # Ensure the integration implements connection / configuration testing logic
        if command == "test-module":
            return_results(my_integration_test_module(client, params))
        
        # Route to automation command
        elif command == "my-integration-item-list":
            args = execution.item_list_args
            return_results(my_integration_item_list_command(client, args))
        
        elif command == "fetch-incidents":
            last_run = execution.last_run
            next_run = fetch_incidents(client, last_run, max_fetch=params.max_fetch, first_fetch_datetime=params.first_fetch_datetime)
            next_run.set()

        else:
            raise NotImplementedError(f"Command {command} is not implemented")

    # Log exceptions and return errors
    except Exception as e:
        demisto.error(f"[Main] Failed to execute {command=}: {str(e)}. {traceback.format_exc()}")
        return_error(f"Failed to execute {command} command.\nError:\n{str(e)}")
    
    finally:
        demisto.debug(f"[Main] Generating diagnostic report after executing {command=}.")
        if client:
            client.log_optional_diagnostic_report()


if __name__ in ("__main__", "__builtin__", "builtins"):
    main()

AI Agent Prompts

Uplift an Existing Integration

Update the logic in MyIntegration.py to follow the style of HelloWorldV2.py.

REFERENCE DOCUMENTATION
- The ContentClientApiModule README.md file
- The "Developer Guide" section in the HelloWorldV2 README.md file
- The HelloWorldV2.py code file

FOCUS AREAS
Focus on implementing key features <including fetch if relevant> and avoid common pitfalls, as documented.

REQUIREMENTS
- Maintain backward compatibility with existing YML configuration parameters and command arguments (Do not add any new commands and keep existing ones)
- Preserve all integration-specific logic (authentication methods, API quirks, data transformations)
- Include consistent debug and diagnostic logging that captures specific variable context
- Pass type checking with Pydantic validation models
- Follow the region-based organization from HelloWorldV2

Make sure to update the unit test to match the new code in MyIntegration.py in the style of HelloWorldV2_test.py. Mock API responses and helper functions where needed.
Update the API Module dependencies and Docker image in MyIntegration.yml to match HelloWorldV2.yml

Create a New Integration

Create a new integration called MyIntegration available in the <xsoar|marketplacev2|platform> marketplaces with supported modules <...> and support level <xsoar|partner|community|...> inside my <new|existing> MyPack pack.

REFERENCE DOCUMENTATION
- The ContentClientApiModule README.md file
- The "Developer Guide" section in the HelloWorldV2 README.md file
- The HelloWorldV2.py code file

FOCUS AREAS
Focus on implementing key features <including fetch if relevant> and avoid common pitfalls, as documented.

API DETAILS
- Base URL: <https://api.example.com>
- Authentication: <OAuth2|Basic|API Key|Custom>
- Rate Limits: <X requests per minute/hour>

CONFIGURATION PARAMETERS 
For each parameter, define in YML and include in the parameter validation model:
1. **Required** `url` - "Server URL" (type: 0, default: https://api.example.com)
2. **Required** `credentials` - "Client ID/Client Secret" (type: 9)
3. **Optional** `proxy` - "Use system proxy settings" (type: 8, inherited from BaseParams)
4. **Optional** `insecure` - "Trust any certificate" (type: 8, inherited from BaseParams)
5. **Optional** `<param_name>` - "<Display Name>" (type: <0-16>, default: <value>)
6. Add more parameters as needed with clear descriptions

COMMANDS TO IMPLEMENT
For each command, define: YML configuration, argument validation model, command function, and client method.
1. **test-module**: Validate connectivity and authentication
   - No arguments
   - Returns: "ok" on success
2. **<integration-name>-<command-name>**: <Brief description>
   - Arguments:
     - **<Required|Optional>** `<arg_name>`: <description> (Python type: <str|int|bool>, default: <value>)
   - Context Outputs:
     - `<IntegrationName>.<CommandPrefix>.<key>` : <description> (YML type: <string|number|boolean|object>)
   - API Endpoint: <GET|POST|PUT|DELETE> /v1/<endpoint>
   - Request <Params|Body>: <list parameters>
   - Returns: CommandResults with readable markdown table and outputs_prefix="<IntegrationName>.<CommandPrefix>"
3. <Add more commands following the same pattern

REQUIREMENTS
- Ensure matching configuration parameters and command arguments in both the YML and code
- Pass type checking with Pydantic validation models
- Follow the region-based organization from HelloWorldV2
- Include consistent debug and diagnostic logging that captures specific variable context

Make sure to write parameterized unit tests in the style of HelloWorldV2_test.py that check edge cases and cover at least 80% of the code. Mock API responses and helper functions where needed.
Update the API Module dependencies and Docker image in MyIntegration.yml to match HelloWorldV2.yml

Pitfalls to Avoid

Avoid the following where possible to adhere to best practices:

  • Do not create an API Client that inherits from BaseClient in CommonServerPython; inherit from ContentClient in ContentClientApiModule instead, which is backwards compatible.
  • Do not call demisto.params() directly; define a params property under the ExecutionConfig class and use execution.params instead.
  • Do not forget to define an alias for YML configuration parameter or command argument mapping if the field name in the YML is in the “camelCase” format in the validation models. For example: snake_case_name: str = Field(alias="camelCaseName").
  • Do not skip defining a custom Pydantic @validator function for specific field(s) under the validation model for complex validation logic.
  • Do not forget to call client.log_optional_diagnostic_report() in finally block of the main() function.
  • Do not forget to accommodate all tenant types if the integration supports multiple marketplaces. For example send_events_to_xsiam is not supported on Cortex XSOAR tenants.

Additional Resources

<~PLATFORM>

License Requirements

The following configuration parameters require the Cortex XSIAM license:

  • Fetch events

The following configuration parameters require Cortex XSIAM with the Exposure Management add-on:

  • Fetch assets and vulnerabilities

The following configuration parameters require one of these licenses: Cortex XSIAM or Agentix:

  • Fetch incidents

</~PLATFORM>

Configuration parameters

  • url — Server URL (e.g., https://api.dummy-example.com) (required)
  • credentials — (required)
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings
  • eventFetchInterval — Events Fetch Interval
  • threshold_ip — Score threshold for IP reputation command
  • integrationReliability — Source Reliability
  • first_fetch — First fetch time
  • severity — Severity of alerts to fetch
  • isFetch — Fetch incidents
  • incidentFetchInterval — Incidents Fetch Interval
  • incidentType — Incident type
  • max_incidents_fetch — Maximum number of incidents per fetch
  • isFetchEvents — Fetch events
  • max_events_fetch — Maximum number of events per fetch
  • isFetchAssets — Fetch assets and vulnerabilities
  • assetsFetchInterval — Assets and vulnerabilities fetch interval

Commands (9)

  • helloworld-alert-list

    Lists example alerts as they would appear in a fetch operation.

  • helloworld-alert-note-create

    Create a note in the API.

  • helloworld-get-assets

    Retrieves resources and assets in the HelloWorld environment.

  • helloworld-get-events

    Retrieves alerts from the HelloWorld API. Use this command for development and debugging only, as it may produce duplicate events, exceed API rate limits, or disrupt the fetch mechanism.

  • helloworld-get-vulnerabilities

    Retrieves vulnerabilities found in the HelloWorld environment.

  • helloworld-job-poll

    Polls a submitted job for completion status. This is called automatically by helloworld-job-submit.

  • helloworld-job-submit

    Submits a job to the HelloWorld API and polls for completion. Used for asynchronous APIs and long-running operations.

  • helloworld-say-hello

    Prints hello to a specified name.

  • ip

    The returned IP information and reputation.

category: Utilities
provider: Open Source
sectionorder:
- Connect
- Collect
commonfields:
  id: HelloWorldV2
  version: -1
configuration:
- name: url
  display: Server URL (e.g., https://api.dummy-example.com)
  defaultvalue: https://api.dummy-example.com
  type: 0
  required: true
  section: Connect
- name: credentials
  displaypassword: API Key
  type: 9
  required: true
  hiddenusername: true
  section: Connect
- name: insecure
  display: Trust any certificate (not secure)
  type: 8
  required: false
  section: Connect
  advanced: true
- name: proxy
  display: Use system proxy settings
  type: 8
  required: false
  section: Connect
  advanced: true
- display: Events Fetch Interval
  name: eventFetchInterval
  defaultvalue: '1'
  type: 19
  required: false
  section: Collect
  hidden:
  - xsoar
  supportedModules:
  - xsiam
- name: threshold_ip
  display: Score threshold for IP reputation command
  defaultvalue: '65'
  additionalinfo: The minimum HelloWorld score required to mark an IP as malicious (0-100).
  type: 0
  required: false
  section: Collect
  advanced: true
- name: integrationReliability
  display: Source Reliability
  defaultvalue: C - Fairly reliable
  additionalinfo: Reliability of the source providing the intelligence data.
  type: 15
  required: false
  section: Collect
  options:
  - A+ - 3rd party enrichment
  - A - Completely reliable
  - B - Usually reliable
  - C - Fairly reliable
  - D - Not usually reliable
  - E - Unreliable
  - F - Reliability cannot be judged
  advanced: true
- name: first_fetch
  display: First fetch time
  defaultvalue: "3 days"
  additionalinfo: The time from which to start fetching alerts. Supports relative time (e.g., "3 hours ago") or ISO 8601 format (e.g., "2025-12-01T00:00:00Z").
  type: 0
  required: false
  section: Collect
  hidden:  # Set internally to "1 minute" on Cortex XSIAM (legacy and platform)
    - marketplacev2
    - platform
- name: severity
  display: Severity of alerts to fetch
  defaultvalue: "high"
  type: 15
  required: false
  section: Collect
  options:
  - low
  - medium
  - high
  - critical
  # Fetch incidents
  # Depending on the integration, you may optionally disable "fetch-incidents" on Cortex XSIAM (legacy and platform)
- name: isFetch
  display: Fetch incidents
  additionalinfo: Fetch HelloWorld alerts as incidents in Cortex XSOAR.
  type: 8
  required: false
  section: Collect
  hidden:
    - marketplacev2
    - platform
  supportedModules:
  - agentix
  - xsiam
- display: Incidents Fetch Interval
  name: incidentFetchInterval
  type: 19
  required: false
  defaultvalue: '1'
  advanced: true
  section: Collect
  hidden:
    - marketplacev2
    - platform
  supportedModules:
  - agentix
  - xsiam
- display: Incident type
  name: incidentType
  type: 13
  section: Connect
  required: false
  hidden:
    - marketplacev2
    - platform
  supportedModules:
  - agentix
  - xsiam
- name: max_incidents_fetch
  display: Maximum number of incidents per fetch
  defaultvalue: '10'
  type: 0
  required: false
  section: Collect
  hidden:
    - marketplacev2
    - platform
  supportedModules:
  - agentix
  - xsiam
  # Fetch Events
  # Not supported in Cortex XSOAR
- name: isFetchEvents
  display: Fetch events
  type: 8
  required: false
  section: Collect
  hidden:
    - xsoar
  supportedModules:
  - xsiam
- name: max_events_fetch
  display: Maximum number of events per fetch
  defaultvalue: '1000'
  type: 0
  required: false
  section: Collect
  hidden:
    - xsoar
  supportedModules:
  - xsiam
  # Fetch Assets (and Vulnerabilities)
  # Not supported in Cortex XSOAR
- display: Fetch assets and vulnerabilities
  name: isFetchAssets
  type: 8
  required: false
  section: Collect
  hidden:
    - xsoar
  supportedModules:
  - xsiam
  - exposure_management
- display: Assets and vulnerabilities fetch interval
  name: assetsFetchInterval
  type: 19
  required: false
  defaultvalue: '1440'
  advanced: true
  section: Collect
  hidden:
    - xsoar
  supportedModules:
  - xsiam
  - exposure_management
description: Use the Hello World v2 integration to learn how to build and configure Cortex integrations.
display: Hello World v2
name: HelloWorldV2
script:
  commands:
  - name: helloworld-say-hello
    description: Prints hello to a specified name.
    arguments:
    - description: The name of the person you want to say hello to.
      name: name
    outputs:
    - contextPath: HelloWorld.Hello.name
      description: The greeting message returned by the command.
      type: String
  - name: helloworld-alert-list
    description: Lists example alerts as they would appear in a fetch operation.
    arguments:
    - description: Filter the fetch by alert ID. If not specified, all alert IDs will be retrieved.
      name: alert_id
    - description: How many alerts to fetch. Default is 10.
      name: limit
    - description: The severity by which to filter the alerts.
      name: severity
      auto: PREDEFINED
      predefined:
      - low
      - medium
      - high
      - critical
    outputs:
    - contextPath: HelloWorld.alert.id
      description: The ID of the alert.
      type: Number
    - contextPath: HelloWorld.alert.name
      description: The name of the alert.
      type: String
    - contextPath: HelloWorld.alert.severity
      description: The severity of the alert.
      type: String
    - contextPath: HelloWorld.alert.date
      description: The date of the alert occurrence.
      type: Date
    - contextPath: HelloWorld.alert.status
      description: The status of the alert.
      type: String
  - name: helloworld-alert-note-create
    description: Create a note in the API.
    arguments:
    - description: The alert ID to add the note to.
      name: alert_id
      required: true
    - description: The text to add to the note.
      name: note_text
      required: true
    outputs:
    - contextPath: HelloWorld.Note.status
      description: The note creation status.
      type: String
    - contextPath: HelloWorld.Note.msg
      description: The message from the note creation response.
      type: String
  - name: ip
    description: The returned IP information and reputation.
    arguments:
    - description: A comma-separated list of IPs.
      name: ip
      default: true
      isArray: true
      required: true
    - description: The score threshold used to determine if an IP is malicious. If not provided, the default threshold from the instance configuration is used.
      name: threshold
      defaultValue: 65
    outputs:
    - contextPath: DBotScore.Indicator
      description: The indicator that was tested.
      type: String
    - contextPath: DBotScore.Score
      description: The actual score.
      type: Number
    - contextPath: DBotScore.Type
      description: The indicator type.
      type: String
    - contextPath: DBotScore.Vendor
      description: The vendor used to calculate the score.
      type: String
    - contextPath: HelloWorld.IP.asn
      description: The autonomous system name (ASN) for the IP address.
      type: String
    - contextPath: HelloWorld.IP.asn_cidr
      description: The network routing prefix in CIDR notation associated with the ASN.
      type: String
    - contextPath: HelloWorld.IP.asn_country_code
      description: The two letter ISO country code associated with the ASN.
      type: String
    - contextPath: HelloWorld.IP.asn_date
      description: The date the ASN was assigned.
      type: Date
    - contextPath: HelloWorld.IP.asn_description
      description: The ASN description.
      type: String
    - contextPath: HelloWorld.IP.asn_registry
      description: The registry the ASN belongs to.
      type: String
    - contextPath: HelloWorld.IP.entities
      description: Entities associated to the IP.
      type: String
    - contextPath: HelloWorld.IP.ip
      description: The actual IP address.
      type: String
    - contextPath: HelloWorld.IP.network.cidr
      description: The network CIDR for the IP address.
      type: String
    - contextPath: HelloWorld.IP.network.country
      description: The country of the IP address.
      type: String
    - contextPath: HelloWorld.IP.network.end_address
      description: The last IP address of the CIDR.
      type: String
    - contextPath: HelloWorld.IP.network.events.action
      description: The specific action recorded for the network (for example, registration or modification).
      type: String
    - contextPath: HelloWorld.IP.network.events.actor
      description: The actor (identifier or entity name) that performed the recorded action on the network.
      type: Unknown
    - contextPath: HelloWorld.IP.network.events.timestamp
      description: The date and time the event occurred.
      type: String
    - contextPath: HelloWorld.IP.network.handle
      description: The unique registry identifier assigned to the network block.
      type: String
    - contextPath: HelloWorld.IP.network.ip_version
      description: The IP address version.
      type: String
    - contextPath: HelloWorld.IP.network.links
      description: Links associated to the IP address.
      type: String
    - contextPath: HelloWorld.IP.network.name
      description: The name of the network.
      type: String
    - contextPath: HelloWorld.IP.network.notices.description
      description: The description of the notice.
      type: String
    - contextPath: HelloWorld.IP.network.notices.links
      description: A list of URLs providing additional information or documentation related to the network notice.
      type: Unknown
    - contextPath: HelloWorld.IP.network.notices.title
      description: The title of a specific notice related to the network.
      type: String
    - contextPath: HelloWorld.IP.network.parent_handle
      description: The unique registry identifier of the parent network from which this block was allocated.
      type: String
    - contextPath: HelloWorld.IP.network.raw
      description: Additional raw data for the network.
      type: Unknown
    - contextPath: HelloWorld.IP.network.remarks
      description: Additional remarks for the network.
      type: Unknown
    - contextPath: HelloWorld.IP.network.start_address
      description: The first IP address of the CIDR.
      type: String
    - contextPath: HelloWorld.IP.network.status
      description: The network status.
      type: String
    - contextPath: HelloWorld.IP.network.type
      description: The type of the network.
      type: String
    - contextPath: HelloWorld.IP.query
      description: The IP address that was queried.
      type: String
    - contextPath: HelloWorld.IP.raw
      description: Additional raw data for the IP address.
      type: Unknown
    - contextPath: HelloWorld.IP.score
      description: The reputation score from HelloWorld for this IP (0 to 100, where higher is worse).
      type: Number
    - contextPath: IP.Address
      description: The IP address.
      type: String
    - contextPath: IP.Malicious.Vendor
      description: The vendor reporting the IP address as malicious.
      type: String
    - contextPath: IP.Malicious.Description
      description: A description explaining why the IP address was reported as malicious.
      type: String
    - contextPath: IP.ASN
      description: The autonomous system name for the IP address.
      type: String
    - contextPath: IP.Relationships.EntityA
      description: The source of the relationship.
      type: string
    - contextPath: IP.Relationships.EntityB
      description: The destination of the relationship.
      type: string
    - contextPath: IP.Relationships.Relationship
      description: The name of the relationship.
      type: string
    - contextPath: IP.Relationships.EntityAType
      description: The relationship source type.
      type: string
    - contextPath: IP.Relationships.EntityBType
      description: The relationship destination type.
      type: string
  - name: helloworld-get-events
    description: Retrieves alerts from the HelloWorld API. Use this command for development and debugging only, as it may produce duplicate events, exceed API rate limits, or disrupt the fetch mechanism.
    arguments:
    - description: The severity by which to filter the alerts.
      name: severity
      required: true
      auto: PREDEFINED
      predefined:
      - low
      - medium
      - high
      - critical
    - description: The time from which to start fetching alerts. Supports relative time (e.g., "3 hours ago") or ISO 8601 format (e.g., "2025-12-01T00:00:00Z").
      name: start_time
    - description: Maximum number of alerts to retrieve.
      name: limit
      defaultValue: "10"
    - description: Whether to push events to Cortex XSIAM (for Cortex XSIAM tenants only).
      name: should_push_events
      auto: PREDEFINED
      predefined:
      - "true"
      - "false"
      defaultValue: "false"
  - name: helloworld-job-submit
    description: Submits a job to the HelloWorld API and polls for completion. Used for asynchronous APIs and long-running operations.
    polling: true
    arguments:
    - description: Interval in seconds between each poll.
      name: interval_in_seconds
      defaultValue: "30"
    - description: Timeout in seconds until polling stops.
      name: timeout_in_seconds
      defaultValue: "600"
    outputs:
    - contextPath: HelloWorld.Job.id
      description: The ID of the submitted job.
      type: String
    - contextPath: HelloWorld.Job.status
      description: The current status of the job.
      type: String
    - contextPath: HelloWorld.Job.type
      description: The type of job submitted.
      type: String
    - contextPath: HelloWorld.Job.msg
      description: Message from the completed job.
      type: String
  - name: helloworld-job-poll
    description: Polls a submitted job for completion status. This is called automatically by helloworld-job-submit.
    polling: true
    hidden: true  # Does not appear in README
    arguments:
    - description: The job ID to poll for completion.
      name: job_id
      required: true
    - description: Interval in seconds between each poll (default is 30 seconds).
      name: interval_in_seconds
    - description: Timeout in seconds until polling stops (default is 600 seconds).
      name: timeout_in_seconds
    outputs:
    - contextPath: HelloWorld.Job.id
      description: The ID of the job.
      type: String
    - contextPath: HelloWorld.Job.status
      description: The current status of the job.
      type: String
    - contextPath: HelloWorld.Job.msg
      description: Message from the completed job.
      type: String
  - name: helloworld-get-assets
    description: Retrieves resources and assets in the HelloWorld environment.
    arguments:
    - description: Maximum number of assets to retrieve.
      name: limit
      defaultValue: "10"
  - name: helloworld-get-vulnerabilities
    description: Retrieves vulnerabilities found in the HelloWorld environment.
    arguments:
    - description: Maximum number of vulnerabilities to retrieve.
      name: limit
      defaultValue: "10"
  dockerimage: demisto/fastapi:0.125.0.10158186
  # Fetch Incidents
  isfetch: true
  isfetch:marketplacev2: false  # Depending on the integration, you may optionally disable "fetch-incidents" on Cortex XSIAM (legacy and platform)
  isfetch:platform: false
  # Fetch Events
  isfetchevents: true
  isfetchevents:xsoar: false  # "fetch-events" is not supported on Cortex XSOAR. This is automatically disabled during the XSOAR Marketplace upload process. This line was added to be clearer and more explicit.
  # Fetch Assets
  isfetchassets: true  # "fetch-assets" is not supported on Cortex XSOAR. This is automatically disabled during the XSOAR Marketplace upload process. This line was added to be clearer and more explicit.
  runonce: false
  script: '-'
  subtype: python3
  type: python
defaultclassifier: HelloWorld   # Incident classifier (if "fetch-incidents" is enabled)
defaultmapperin: HelloWorld-mapper  # Incident field mapper (if "fetch-incidents" is enabled)
fromversion: 6.8.0
tests:
- No tests (auto formatted)