In [1]:
# Delete this cell to re-enable tracebacks
import sys
ipython = get_ipython()

def hide_traceback(exc_tuple=None, filename=None, tb_offset=None,
                   exception_only=False, running_compiled_code=False):
    etype, value, tb = sys.exc_info()
    value.__cause__ = None  # suppress chained exceptions
    return ipython._showtraceback(etype, value, ipython.InteractiveTB.get_exception_only(etype, value))

ipython.showtraceback = hide_traceback

In [2]:
# JSON output syntax highlighting
from __future__ import print_function
from pygments import highlight
from pygments.lexers import JsonLexer, TextLexer
from pygments.formatters import HtmlFormatter
from IPython.display import display, HTML
from IPython.core.interactiveshell import InteractiveShell

InteractiveShell.ast_node_interactivity = "all"

def json_print(inpt):
    string = str(inpt)
    formatter = HtmlFormatter()
    if string[0] == '{':
        lexer = JsonLexer()
    else:
        lexer = TextLexer()
    return HTML('<style type="text/css">{}</style>{}'.format(
                formatter.get_style_defs('.highlight'),
                highlight(string, lexer, formatter)))

globals()['print'] = json_print

Serializing STIX Objects

The string representation of all STIX classes is a valid STIX JSON object.


In [3]:
from stix2 import Indicator

indicator = Indicator(name="File hash for malware variant",
                      pattern_type="stix",
                      pattern="[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']")

print(str(indicator))


Out[3]:
{
    "type": "indicator",
    "spec_version": "2.1",
    "id": "indicator--5e515461-93ad-41a8-a540-4f9d1a098939",
    "created": "2020-06-26T18:47:20.215931Z",
    "modified": "2020-06-26T18:47:20.215931Z",
    "name": "File hash for malware variant",
    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",
    "pattern_type": "stix",
    "pattern_version": "2.1",
    "valid_from": "2020-06-26T18:47:20.215931Z"
}

However, the string representation can be slow, as it sorts properties to be in a more readable order. If you need performance and don't care about the human-readability of the output, use the object's serialize() function:


In [4]:
print(indicator.serialize())


Out[4]:
{"name": "File hash for malware variant", "pattern_type": "stix", "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']", "pattern_version": "2.1", "type": "indicator", "spec_version": "2.1", "id": "indicator--5e515461-93ad-41a8-a540-4f9d1a098939", "created": "2020-06-26T18:47:20.215931Z", "modified": "2020-06-26T18:47:20.215931Z", "valid_from": "2020-06-26T18:47:20.215931Z"}

If you need performance but also need human-readable output, you can pass the indent keyword argument to serialize():


In [5]:
print(indicator.serialize(indent=4))


Out[5]:
{
    "name": "File hash for malware variant",
    "pattern_type": "stix",
    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",
    "pattern_version": "2.1",
    "type": "indicator",
    "spec_version": "2.1",
    "id": "indicator--5e515461-93ad-41a8-a540-4f9d1a098939",
    "created": "2020-06-26T18:47:20.215931Z",
    "modified": "2020-06-26T18:47:20.215931Z",
    "valid_from": "2020-06-26T18:47:20.215931Z"
}

The only difference between this and the string representation from using str() is that this will not sort the keys. This works because the keyword arguments are passed to json.dumps() internally.