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
Imports can be used in different ways depending on the use case and support levels.
People who want to support the latest version of STIX 2 without having to make changes, can implicitly use the latest version:
Warning
The implicit import method can cause the code to break between major releases to support a newer approved committee specification. Therefore, not recommended for large scale applications relying on specific object support.
</div>
In [ ]:
import stix2
stix2.Indicator()
or,
In [ ]:
from stix2 import Indicator
Indicator()
People who want to use an explicit version:
In [ ]:
import stix2.v20
stix2.v20.Indicator()
or,
In [ ]:
from stix2.v20 import Indicator
Indicator()
or even, (less preferred)
In [ ]:
import stix2.v20 as stix2
stix2.Indicator()
The last option makes it easy to update to a new version in one place per file, once you've made the deliberate action to do this.
People who want to use multiple versions in a single file:
In [ ]:
import stix2
stix2.v20.Indicator()
stix2.v21.Indicator()
or,
In [ ]:
from stix2 import v20, v21
v20.Indicator()
v21.Indicator()
or (less preferred):
In [ ]:
from stix2.v20 import Indicator as Indicator_v20
from stix2.v21 import Indicator as Indicator_v21
Indicator_v20()
Indicator_v21()
If the version
positional argument is not provided the library will make the best attempt using the "spec_version" property found on a Bundle, SDOs, SCOs, or SROs.
You can lock your parse() method to a specific STIX version by:
In [3]:
from stix2 import parse
indicator = parse("""{
"type": "indicator",
"id": "indicator--dbcbd659-c927-4f9a-994f-0a2632274394",
"created": "2017-09-26T23:33:39.829Z",
"modified": "2017-09-26T23:33:39.829Z",
"labels": [
"malicious-activity"
],
"name": "File hash for malware variant",
"pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",
"valid_from": "2017-09-26T23:33:39.829952Z"
}""", version="2.0")
print(indicator)
Out[3]:
In the example above if a 2.1 or higher object is parsed, the operation will fail.
CustomObject, CustomObservable, CustomMarking and CustomExtension must be registered explicitly by STIX version. This is a design decision since properties or requirements may change as the STIX Technical Specification advances.
You can perform this by:
In [4]:
import stix2
# Make my custom observable available in STIX 2.0
@stix2.v20.CustomObservable('x-new-object-type',
[("prop", stix2.properties.BooleanProperty())])
class NewObject2(object):
pass
# Make my custom observable available in STIX 2.1
@stix2.v21.CustomObservable('x-new-object-type',
[("prop", stix2.properties.BooleanProperty())])
class NewObject2(object):
pass