Version: 4.1.0.13

APIs or bindings?

This page describes both the APIs and the bindings provided by the python-maec library.

Overview

The python-maec library provides APIs and utilities that aid in the creation, consumption, and processing of Structured Threat Information eXpression (MAEC) content. The APIs that drive much of the functionality of python-maec sit on top of a binding layer that acts as a direct connection between Python and the MAEC XML. Because both the APIs and the bindings allow for the creation and development of MAEC content, developers that are new to python-maec may not understand the differences between the two. This document aims to identify the purpose and uses of the APIs and bindings.

Bindings

The python-maec library leverages machine generated XML-to-Python bindings for the creation and processing of MAEC content. These bindings are created using the generateDS utility and can be found under maec.bindings within the package hierarchy.

The MAEC bindings allow for a direct, complete mapping between Python classes and MAEC XML Schema data structures. That being said, it is possible (though not advised) to use only the MAEC bindings to create MAEC documents. However, because the code is generated from XML Schema without contextual knowledge of relationships or broader organizational/developmental schemes, it is often a cumbersome and laborious task to create even the simplest of MAEC documents.

Developers within the python-maec team felt that the binding code did not lend itself to rapid development or natural navigation of data, and so it was decided that a higher-level API should be created.

APIs

The python-maec APIs are classes and utilities that leverage the MAEC bindings for the creation and processing of MAEC content. The APIs are designed to behave more naturally when working with MAEC content, allowing developers to conceptualize and interact with MAEC documents as pure Python objects and not XML Schema objects.

The APIs provide validation of inputs, multiple input and output formats, more Pythonic access of data structure internals and interaction with classes, and better interpretation of a developers intent through datatype coercion and implicit instantiation.

Note

The python-maec APIs are under constant development. Our goal is to provide full API coverage of the MAEC data structures, but not all structures are exposed via the APIs yet. Please refer to the API Documentation for API coverage details.

Brevity Wins

The two code examples show the difference in creating and printing a simple MAEC document consisting of only a MAEC Bundle with a single Malware Action using the python-maec and python-cybox bindings. Both examples will produce the same MAEC XML!

API Example

# Import the required APIs
from maec.bundle import Bundle, MalwareAction
from maec.utils import IDGenerator, set_id_method
from cybox.core import Object, AssociatedObjects, AssociatedObject
from cybox.objects.file_object import File
from cybox.common import VocabString

# Instantiate the MAEC/CybOX Entities
set_id_method(IDGenerator.METHOD_INT)
b = Bundle()
a = MalwareAction()
ao = AssociatedObject()

# Build the Associated Object for use in the Action
ao.properties = File()
ao.properties.file_name = "badware.exe"
ao.properties.size_in_bytes = "123456"
ao.association_type = VocabString()
ao.association_type.value = 'output'
ao.association_type.xsi_type = 'maecVocabs:ActionObjectAssociationTypeVocab-1.0'

# Build the Action and add the Associated Object to it
a.name = VocabString()
a.name.value = 'create file'
a.name.xsi_type = 'maecVocabs:FileActionNameVocab-1.0'
a.associated_objects = AssociatedObjects()
a.associated_objects.append(ao)

# Add the Action to the Bundle
b.add_action(a)

# Output the Bundle to stdout
print(b.to_xml(include_namespaces = False))

Binding Example

import sys
# Import the required bindings
import maec.bindings.maec_bundle as bundle_binding
import cybox.bindings.cybox_core as cybox_core_binding
import cybox.bindings.cybox_common as cybox_common_binding
import cybox.bindings.file_object as file_binding

# Instantiate the MAEC/CybOX Entities
b = bundle_binding.BundleType(id="bundle-1")
a = bundle_binding.MalwareActionType(id="action-1")
ao = cybox_core_binding.AssociatedObjectType(id="object-1")

# Build the Associated Object for use in the Action
f = file_binding.FileObjectType()
f_name = cybox_common_binding.StringObjectPropertyType(valueOf_="badware.exe")
f.set_File_Name(f_name)
f_size = cybox_common_binding.UnsignedLongObjectPropertyType(valueOf_="123456")
f.set_Size_In_Bytes(f_size)
f.set_xsi_type = "FileObj:FileObjectType"
ao.set_Properties(f)
ao_type = cybox_common_binding.ControlledVocabularyStringType(valueOf_="output")
ao_type.set_xsi_type("maecVocabs:ActionObjectAssociationTypeVocab-1.0")
ao.set_Association_Type(ao_type)

# Build the Action and add the Associated Object to it
a_name = cybox_common_binding.ControlledVocabularyStringType(valueOf_="create file")
a_name.set_xsi_type("maecVocabs:FileActionNameVocab-1.0")
a.set_Name(a_name)
as_objects = cybox_core_binding.AssociatedObjectsType()
as_objects.add_Associated_Object(ao)
a.set_Associated_Objects(as_objects)

# Add the Action to the Bundle
action_list = bundle_binding.ActionListType()
action_list.add_Action(a)
b.set_Actions(action_list)

# Output the Bundle to stdout
b.export(sys.stdout, 0)

Feedback

If there is a problem with the APIs or bindings, or if there is functionality missing from the APIs that forces the use of the bindings, let us know in the python-maec issue tracker