Merge branch 'documentation' of https://github.com/oasis-open/cti-python-stix2 into documentation

stix2.1
= 2017-09-24 18:15:53 -04:00
commit 54e917110e
22 changed files with 88 additions and 75 deletions

View File

@ -1,5 +0,0 @@
base
==========
.. automodule:: stix2.base
:members:

View File

@ -19,6 +19,7 @@ autodoc_member_order = 'groupwise'
autosummary_generate = True
napoleon_numpy_docstring = False # Force consistency, leave only Google
napoleon_use_rtype = False
add_module_names = False
templates_path = ['_templates']
source_suffix = '.rst'

View File

@ -3,7 +3,6 @@
.. autosummary::
:toctree: api
base
common
core
environment

View File

@ -65,7 +65,7 @@ class StatementMarking(_STIXBase):
class MarkingProperty(Property):
"""Represent the marking objects in the `definition` property of
"""Represent the marking objects in the ``definition`` property of
marking-definition objects.
"""
@ -120,17 +120,15 @@ def _register_marking(cls):
def CustomMarking(type='x-custom-marking', properties=None):
"""
Custom STIX Marking decorator.
"""Custom STIX Marking decorator.
Examples:
@CustomMarking('x-custom-marking', [
('property1', StringProperty(required=True)),
('property2', IntegerProperty()),
])
class MyNewMarkingObjectType():
pass
Example:
>>> @CustomMarking('x-custom-marking', [
... ('property1', StringProperty(required=True)),
... ('property2', IntegerProperty()),
... ])
... class MyNewMarkingObjectType():
... pass
"""
def custom_builder(cls):

View File

@ -1,4 +1,4 @@
"""STIX 2.0 Objects that are neither SDOs nor SROs"""
"""STIX 2.0 Objects that are neither SDOs nor SROs."""
from collections import OrderedDict

View File

@ -3,7 +3,7 @@ class STIXError(Exception):
class InvalidValueError(STIXError, ValueError):
"""An invalid value was provided to a STIX object's __init__."""
"""An invalid value was provided to a STIX object's ``__init__``."""
def __init__(self, cls, prop_name, reason):
super(InvalidValueError, self).__init__()
@ -45,7 +45,7 @@ class ExtraPropertiesError(STIXError, TypeError):
class ImmutableError(STIXError, ValueError):
"""Attempted to modify an object after creation"""
"""Attempted to modify an object after creation."""
def __init__(self, cls, key):
super(ImmutableError, self).__init__()
@ -85,7 +85,7 @@ class InvalidObjRefError(STIXError, ValueError):
class UnmodifiablePropertyError(STIXError, ValueError):
"""Attempted to modify an unmodifiable property of object when creating a new version"""
"""Attempted to modify an unmodifiable property of object when creating a new version."""
def __init__(self, unchangable_properties):
super(UnmodifiablePropertyError, self).__init__()
@ -139,7 +139,7 @@ class AtLeastOnePropertyError(STIXError, TypeError):
class RevokeError(STIXError, ValueError):
"""Attempted to an operation on a revoked object"""
"""Attempted to an operation on a revoked object."""
def __init__(self, called_by):
super(RevokeError, self).__init__()
@ -153,7 +153,7 @@ class RevokeError(STIXError, ValueError):
class ParseError(STIXError, ValueError):
"""Could not parse object"""
"""Could not parse object."""
def __init__(self, msg):
super(ParseError, self).__init__(msg)

View File

@ -6,7 +6,7 @@ granular markings unless otherwise noted in each of the functions.
.. autosummary::
:toctree: api
:toctree: markings
granular_markings
object_markings

View File

@ -1,3 +1,5 @@
"""Functions for working with STIX 2.0 granular markings.
"""
from stix2 import exceptions
from stix2.markings import utils

View File

@ -1,3 +1,5 @@
"""Functions for working with STIX 2.0 object markings.
"""
from stix2 import exceptions
from stix2.markings import utils

View File

@ -1,3 +1,5 @@
"""Utility functions for STIX 2.0 data markings.
"""
import collections

View File

@ -1,8 +1,8 @@
"""STIX 2.0 Cyber Observable Objects
"""STIX 2.0 Cyber Observable Objects.
Embedded observable object types, such as Email MIME Component, which is
embedded in Email Message objects, inherit from _STIXBase instead of Observable
and do not have a '_type' attribute.
embedded in Email Message objects, inherit from ``_STIXBase`` instead of
Observable and do not have a ``_type`` attribute.
"""
from collections import OrderedDict
@ -19,6 +19,8 @@ from .utils import get_dict
class ObservableProperty(Property):
"""Property for holding Cyber Observable Objects.
"""
def clean(self, value):
try:
@ -39,7 +41,7 @@ class ObservableProperty(Property):
class ExtensionsProperty(DictionaryProperty):
""" Property for representing extensions on Observable objects
"""Property for representing extensions on Observable objects.
"""
def __init__(self, enclosing_type=None, required=False):
@ -138,7 +140,6 @@ class EmailAddress(_Observable):
('display_name', StringProperty()),
('belongs_to_ref', ObjectReferenceProperty(valid_types='user-account')),
('extensions', ExtensionsProperty(enclosing_type=_type)),
])
@ -798,16 +799,15 @@ def _register_observable(new_observable):
def CustomObservable(type='x-custom-observable', properties=None):
"""Custom STIX Cyber Observable type decorator
"""Custom STIX Cyber Observable Object type decorator.
Example 1:
@CustomObservable('x-custom-observable', [
('property1', StringProperty(required=True)),
('property2', IntegerProperty()),
])
class MyNewObservableType():
pass
Example:
>>> @CustomObservable('x-custom-observable', [
... ('property1', StringProperty(required=True)),
... ('property2', IntegerProperty()),
... ])
... class MyNewObservableType():
... pass
"""
def custom_builder(cls):
@ -873,7 +873,7 @@ def _register_extension(observable, new_extension):
def CustomExtension(observable=None, type='x-custom-observable', properties={}):
"""Decorator for custom extensions to STIX Cyber Observables
"""Decorator for custom extensions to STIX Cyber Observables.
"""
if not observable or not issubclass(observable, _Observable):

View File

@ -19,43 +19,44 @@ class Property(object):
"""Represent a property of STIX data type.
Subclasses can define the following attributes as keyword arguments to
__init__():
``__init__()``.
- `required` - If `True`, the property must be provided when creating an
object with that property. No default value exists for these properties.
(Default: `False`)
- `fixed` - This provides a constant default value. Users are free to
provide this value explicity when constructing an object (which allows
you to copy *all* values from an existing object to a new object), but
if the user provides a value other than the `fixed` value, it will raise
an error. This is semantically equivalent to defining both:
- a `clean()` function that checks if the value matches the fixed
value, and
- a `default()` function that returns the fixed value.
(Default: `None`)
Args:
required (bool): If ``True``, the property must be provided when creating an
object with that property. No default value exists for these properties.
(Default: ``False``)
fixed: This provides a constant default value. Users are free to
provide this value explicity when constructing an object (which allows
you to copy **all** values from an existing object to a new object), but
if the user provides a value other than the ``fixed`` value, it will raise
an error. This is semantically equivalent to defining both:
Subclasses can also define the following functions.
- a ``clean()`` function that checks if the value matches the fixed
value, and
- a ``default()`` function that returns the fixed value.
- `def clean(self, value) -> any:`
- Return a value that is valid for this property. If `value` is not
Subclasses can also define the following functions:
- ``def clean(self, value) -> any:``
- Return a value that is valid for this property. If ``value`` is not
valid for this property, this will attempt to transform it first. If
`value` is not valid and no such transformation is possible, it should
``value`` is not valid and no such transformation is possible, it should
raise a ValueError.
- `def default(self):`
- ``def default(self):``
- provide a default value for this property.
- `default()` can return the special value `NOW` to use the current
- ``default()`` can return the special value ``NOW`` to use the current
time. This is useful when several timestamps in the same object need
to use the same default value, so calling now() for each property--
likely several microseconds apart-- does not work.
Subclasses can instead provide a lambda function for `default` as a keyword
argument. `clean` should not be provided as a lambda since lambdas cannot
Subclasses can instead provide a lambda function for ``default`` as a keyword
argument. ``clean`` should not be provided as a lambda since lambdas cannot
raise their own exceptions.
When instantiating Properties, `required` and `default` should not be used
together. `default` implies that the property is required in the specification
When instantiating Properties, ``required`` and ``default`` should not be used
together. ``default`` implies that the property is required in the specification
so this function will be used to supply a value if none is provided.
`required` means that the user must provide this; it is required in the
``required`` means that the user must provide this; it is required in the
specification and we can't or don't want to create a default value.
"""
@ -88,7 +89,7 @@ class ListProperty(Property):
def __init__(self, contained, **kwargs):
"""
Contained should be a function which returns an object from the value.
``contained`` should be a function which returns an object from the value.
"""
if inspect.isclass(contained) and issubclass(contained, Property):
# If it's a class and not an instance, instantiate it so that

View File

@ -298,8 +298,8 @@ def CustomObject(type='x-custom-type', properties=None):
... class MyNewObjectType():
... pass
Supply an __init__() function to add any special validations to the custom
type. Don't call super().__init__() though - doing so will cause an error.
Supply an ``__init__()`` function to add any special validations to the custom
type. Don't call ``super().__init__()`` though - doing so will cause an error.
Example:
>>> @CustomObject('x-type-name', [

View File

@ -16,7 +16,7 @@ Note:
.. autosummary::
:toctree: api
:toctree: sources
filters
filesystem

View File

@ -34,16 +34,21 @@ class STIXdatetime(dt.datetime):
def get_timestamp():
"""Return a STIX timestamp of the current date and time."""
return STIXdatetime.now(tz=pytz.UTC)
def format_datetime(dttm):
# 1. Convert to timezone-aware
# 2. Convert to UTC
# 3. Format in ISO format
# 4. Ensure correct precision
# 4a. Add subsecond value if non-zero and precision not defined
# 5. Add "Z"
"""Convert a datetime object into a valid STIX timestamp string.
1. Convert to timezone-aware
2. Convert to UTC
3. Format in ISO format
4. Ensure correct precision
a. Add subsecond value if non-zero and precision not defined
5. Add "Z"
"""
if dttm.tzinfo is None or dttm.tzinfo.utcoffset(dttm) is None:
# dttm is timezone-naive; assume UTC
@ -63,6 +68,8 @@ def format_datetime(dttm):
def parse_into_datetime(value, precision=None):
"""Parse a value into a valid STIX timestamp object.
"""
if isinstance(value, dt.date):
if hasattr(value, 'hour'):
ts = value
@ -102,6 +109,7 @@ def parse_into_datetime(value, precision=None):
def get_dict(data):
"""Return data as a dictionary.
Input can be a dictionary, string, or file-like object.
"""
@ -124,7 +132,7 @@ def get_dict(data):
def find_property_index(obj, properties, tuple_to_find):
"""Recursively find the property in the object model, return the index
according to the _properties OrderedDict. If its a list look for
according to the _properties OrderedDict. If it's a list look for
individual objects.
"""
from .base import _STIXBase
@ -159,7 +167,7 @@ def find_property_index(obj, properties, tuple_to_find):
def new_version(data, **kwargs):
"""Create a new version of a STIX object, by modifying properties and
updating the `modified` property.
updating the ``modified`` property.
"""
if not isinstance(data, Mapping):
@ -196,6 +204,11 @@ def new_version(data, **kwargs):
def revoke(data):
"""Revoke a STIX object.
Returns:
A new version of the object with ``revoked`` set to ``True``.
"""
if not isinstance(data, Mapping):
raise ValueError('cannot revoke object of this type! Try a dictionary '
'or instance of an SDO or SRO class.')