ariatosca-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From emblempar...@apache.org
Subject [1/3] incubator-ariatosca git commit: Full documentation of models; fix to subtitution
Date Wed, 28 Jun 2017 02:50:20 GMT
Repository: incubator-ariatosca
Updated Branches:
  refs/heads/ARIA-286-sphinx-documentation 7ed92d0fe -> 4ebbbb156


http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/4ebbbb15/aria/modeling/service_template.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_template.py b/aria/modeling/service_template.py
index ba62416..70ec831 100644
--- a/aria/modeling/service_template.py
+++ b/aria/modeling/service_template.py
@@ -49,51 +49,10 @@ from . import (
 
 class ServiceTemplateBase(TemplateModelMixin):
     """
-    A service template is a source for creating :class:`Service` instances.
-
-    It is usually created by various DSL parsers, such as ARIA's TOSCA extension. However, it can
-    also be created programmatically.
-
-    :ivar name: name (unique for this ARIA installation)
-    :vartype name: basestring
-    :ivar main_file_name: filename of CSAR or YAML file from which this service template was parsed
-    :vartype main_file_name: basestring
-    :ivar meta_data: custom annotations
-    :vartype meta_data: {:obj:`basestring`: :class:`Metadata`}
-    :ivar node_templates: templates for creating nodes
-    :vartype node_templates: {:obj:`basestring`: :class:`NodeTemplate`}
-    :ivar group_templates: templates for creating groups
-    :vartype group_templates: {:obj:`basestring`: :class:`GroupTemplate`}
-    :ivar policy_templates: templates for creating policies
-    :vartype policy_templates: {:obj:`basestring`: :class:`PolicyTemplate`}
-    :ivar substitution_template: the entire service can appear as a node
-    :vartype substitution_template: :class:`SubstitutionTemplate`
-    :ivar inputs: externally provided parameters
-    :vartype inputs: {:obj:`basestring`: :class:`Input`}
-    :ivar outputs: these parameters are filled in after service installation
-    :vartype outputs: {:obj:`basestring`: :class:`Output`}
-    :ivar workflow_templates: custom workflows that can be performed on the service
-    :vartype workflow_templates: {:obj:`basestring`: :class:`OperationTemplate`}
-    :ivar plugin_specifications: plugins used by the service
-    :vartype plugin_specifications: {:obj:`basestring`: :class:`PluginSpecification`}
-    :ivar node_types: base for the node type hierarchy
-    :vartype node_types: Type
-    :ivar group_types: base for the group type hierarchy
-    :vartype group_types: Type
-    :ivar policy_types: base for the policy type hierarchy
-    :vartype policy_types: Type
-    :ivar relationship_types: base for the relationship type hierarchy
-    :vartype relationship_types: Type
-    :ivar capability_types: base for the capability type hierarchy
-    :vartype capability_types: Type
-    :ivar interface_types: base for the interface type hierarchy
-    :vartype interface_types: Type
-    :ivar artifact_types: base for the artifact type hierarchy
-    :vartype artifact_types: Type
-    :ivar created_at: creation timestamp
-    :vartype created_at: datetime.datetime
-    :ivar updated_at: update timestamp
-    :vartype updated_at: datetime.datetime
+    Template for creating :class:`Service` instances.
+
+    Usually created by various DSL parsers, such as ARIA's TOSCA extension. However, it can also be
+    created programmatically.
     """
 
     __tablename__ = 'service_template'
@@ -107,54 +66,29 @@ class ServiceTemplateBase(TemplateModelMixin):
                           'interface_type_fk',
                           'artifact_type_fk')
 
-    description = Column(Text)
-    main_file_name = Column(Text)
-    created_at = Column(DateTime, nullable=False, index=True)
-    updated_at = Column(DateTime)
-
-    # region foreign keys
-
-    @declared_attr
-    def substitution_template_fk(cls):
-        """For ServiceTemplate one-to-one to SubstitutionTemplate"""
-        return relationship.foreign_key('substitution_template', nullable=True)
-
-    @declared_attr
-    def node_type_fk(cls):
-        """For ServiceTemplate one-to-one to Type"""
-        return relationship.foreign_key('type', nullable=True)
-
-    @declared_attr
-    def group_type_fk(cls):
-        """For ServiceTemplate one-to-one to Type"""
-        return relationship.foreign_key('type', nullable=True)
+    description = Column(Text, doc="""
+    Human-readable description.
 
-    @declared_attr
-    def policy_type_fk(cls):
-        """For ServiceTemplate one-to-one to Type"""
-        return relationship.foreign_key('type', nullable=True)
+    :type: :obj:`basestring`
+    """)
 
-    @declared_attr
-    def relationship_type_fk(cls):
-        """For ServiceTemplate one-to-one to Type"""
-        return relationship.foreign_key('type', nullable=True)
+    main_file_name = Column(Text, doc="""
+    Filename of CSAR or YAML file from which this service template was parsed.
+    
+    :type: :obj:`basestring`
+    """)
 
-    @declared_attr
-    def capability_type_fk(cls):
-        """For ServiceTemplate one-to-one to Type"""
-        return relationship.foreign_key('type', nullable=True)
+    created_at = Column(DateTime, nullable=False, index=True, doc="""
+    Creation timestamp.
 
-    @declared_attr
-    def interface_type_fk(cls):
-        """For ServiceTemplate one-to-one to Type"""
-        return relationship.foreign_key('type', nullable=True)
+    :type: :class:`~datetime.datetime`
+    """)
 
-    @declared_attr
-    def artifact_type_fk(cls):
-        """For ServiceTemplate one-to-one to Type"""
-        return relationship.foreign_key('type', nullable=True)
+    updated_at = Column(DateTime, doc="""
+    Update timestamp.
 
-    # endregion
+    :type: :class:`~datetime.datetime`
+    """)
 
     # region association proxies
 
@@ -164,41 +98,81 @@ class ServiceTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def substitution_template(cls):
+        """
+        Exposes an entire service as a single node.
+
+        :type: :class:`SubstitutionTemplate`
+        """
         return relationship.one_to_one(
             cls, 'substitution_template', back_populates=relationship.NO_BACK_POP)
 
     @declared_attr
     def node_types(cls):
+        """
+        Base for the node type hierarchy,
+
+        :type: :class:`Type`
+        """
         return relationship.one_to_one(
             cls, 'type', fk='node_type_fk', back_populates=relationship.NO_BACK_POP)
 
     @declared_attr
     def group_types(cls):
+        """
+        Base for the group type hierarchy,
+
+        :type: :class:`Type`
+        """
         return relationship.one_to_one(
             cls, 'type', fk='group_type_fk', back_populates=relationship.NO_BACK_POP)
 
     @declared_attr
     def policy_types(cls):
+        """
+        Base for the policy type hierarchy,
+
+        :type: :class:`Type`
+        """
         return relationship.one_to_one(
             cls, 'type', fk='policy_type_fk', back_populates=relationship.NO_BACK_POP)
 
     @declared_attr
     def relationship_types(cls):
+        """
+        Base for the relationship type hierarchy,
+
+        :type: :class:`Type`
+        """
         return relationship.one_to_one(
             cls, 'type', fk='relationship_type_fk', back_populates=relationship.NO_BACK_POP)
 
     @declared_attr
     def capability_types(cls):
+        """
+        Base for the capability type hierarchy,
+
+        :type: :class:`Type`
+        """
         return relationship.one_to_one(
             cls, 'type', fk='capability_type_fk', back_populates=relationship.NO_BACK_POP)
 
     @declared_attr
     def interface_types(cls):
+        """
+        Base for the interface type hierarchy,
+
+        :type: :class:`Type`
+        """
         return relationship.one_to_one(
             cls, 'type', fk='interface_type_fk', back_populates=relationship.NO_BACK_POP)
 
     @declared_attr
     def artifact_types(cls):
+        """
+        Base for the artifact type hierarchy,
+
+        :type: :class:`Type`
+        """
         return relationship.one_to_one(
             cls, 'type', fk='artifact_type_fk', back_populates=relationship.NO_BACK_POP)
 
@@ -217,30 +191,65 @@ class ServiceTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def node_templates(cls):
-        return relationship.one_to_many(cls, 'node_template', dict_key='name')
-
-    @declared_attr
-    def outputs(cls):
-        return relationship.one_to_many(cls, 'output', dict_key='name')
+        """
+        Templates for creating nodes.
 
-    @declared_attr
-    def inputs(cls):
-        return relationship.one_to_many(cls, 'input', dict_key='name')
+        :type: {:obj:`basestring`, :class:`NodeTemplate`}
+        """
+        return relationship.one_to_many(cls, 'node_template', dict_key='name')
 
     @declared_attr
     def group_templates(cls):
+        """
+        Templates for creating groups.
+
+        :type: {:obj:`basestring`, :class:`GroupTemplate`}
+        """
         return relationship.one_to_many(cls, 'group_template', dict_key='name')
 
     @declared_attr
     def policy_templates(cls):
+        """
+        Templates for creating policies.
+
+        :type: {:obj:`basestring`, :class:`PolicyTemplate`}
+        """
         return relationship.one_to_many(cls, 'policy_template', dict_key='name')
 
     @declared_attr
     def workflow_templates(cls):
+        """
+        Templates for creating workflows.
+
+        :type: {:obj:`basestring`, :class:`OperationTemplate`}
+        """
         return relationship.one_to_many(cls, 'operation_template', dict_key='name')
 
     @declared_attr
+    def outputs(cls):
+        """
+        Declarations for output parameters are filled in after service installation.
+
+        :type: {:obj:`basestring`: :class:`Output`}
+        """
+        return relationship.one_to_many(cls, 'output', dict_key='name')
+
+    @declared_attr
+    def inputs(cls):
+        """
+        Declarations for externally provided parameters.
+
+        :type: {:obj:`basestring`: :class:`Input`}
+        """
+        return relationship.one_to_many(cls, 'input', dict_key='name')
+
+    @declared_attr
     def plugin_specifications(cls):
+        """
+        Required plugins for instantiated services.
+
+        :type: {:obj:`basestring`: :class:`PluginSpecification`}
+        """
         return relationship.one_to_many(cls, 'plugin_specification', dict_key='name')
 
     # endregion
@@ -253,11 +262,60 @@ class ServiceTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def meta_data(cls):
+        """
+        Associated metadata.
+
+        :type: {:obj:`basestring`: :class:`Metadata`}
+        """
         # Warning! We cannot use the attr name "metadata" because it's used by SQLAlchemy!
         return relationship.many_to_many(cls, 'metadata', dict_key='name')
 
     # endregion
 
+    # region foreign keys
+
+    @declared_attr
+    def substitution_template_fk(cls):
+        """For ServiceTemplate one-to-one to SubstitutionTemplate"""
+        return relationship.foreign_key('substitution_template', nullable=True)
+
+    @declared_attr
+    def node_type_fk(cls):
+        """For ServiceTemplate one-to-one to Type"""
+        return relationship.foreign_key('type', nullable=True)
+
+    @declared_attr
+    def group_type_fk(cls):
+        """For ServiceTemplate one-to-one to Type"""
+        return relationship.foreign_key('type', nullable=True)
+
+    @declared_attr
+    def policy_type_fk(cls):
+        """For ServiceTemplate one-to-one to Type"""
+        return relationship.foreign_key('type', nullable=True)
+
+    @declared_attr
+    def relationship_type_fk(cls):
+        """For ServiceTemplate one-to-one to Type"""
+        return relationship.foreign_key('type', nullable=True)
+
+    @declared_attr
+    def capability_type_fk(cls):
+        """For ServiceTemplate one-to-one to Type"""
+        return relationship.foreign_key('type', nullable=True)
+
+    @declared_attr
+    def interface_type_fk(cls):
+        """For ServiceTemplate one-to-one to Type"""
+        return relationship.foreign_key('type', nullable=True)
+
+    @declared_attr
+    def artifact_type_fk(cls):
+        """For ServiceTemplate one-to-one to Type"""
+        return relationship.foreign_key('type', nullable=True)
+
+    # endregion
+
     @property
     def as_raw(self):
         return collections.OrderedDict((
@@ -402,43 +460,8 @@ class ServiceTemplateBase(TemplateModelMixin):
 
 class NodeTemplateBase(TemplateModelMixin):
     """
-    A template for creating zero or more :class:`Node` instances.
-
-    :ivar name: name (unique for this service template; will usually be used as a prefix for node
-                names)
-    :vartype name: basestring
-    :ivar type: node type
-    
-    :ivar description: human-readable description
-    :vartype description: basestring
-    :ivar default_instances: default number nodes that will appear in the service
-    :vartype default_instances: int
-    :ivar min_instances: minimum number nodes that will appear in the service
-    :vartype min_instances: int
-    :ivar max_instances: maximum number nodes that will appear in the service
-    :vartype max_instances: int
-    :ivar properties: associated parameters
-    :vartype properties: {:obj:`basestring`: :class:`Property`}
-    :ivar interface_templates: bundles of operations
-    :vartype interface_templates: {:obj:`basestring`: :class:`InterfaceTemplate`}
-    :ivar artifact_templates: associated files
-    :vartype artifact_templates: {:obj:`basestring`: :class:`ArtifactTemplate`}
-    :ivar capability_templates: exposed capabilities
-    :vartype capability_templates: {:obj:`basestring`: :class:`CapabilityTemplate`}
-    :ivar requirement_templates: potential relationships with other nodes
-    :vartype requirement_templates: [:class:`RequirementTemplate`]
-    :ivar target_node_template_constraints: constraints for filtering relationship targets
-    :vartype target_node_template_constraints: [:class:`NodeTemplateConstraint`]
-    :ivar service_template: containing service template
-    :vartype service_template: ServiceTemplate
-    :ivar group_templates: we are a member of these groups
-    :vartype group_templates: [:class:`GroupTemplate`]
-    :ivar policy_templates: policy templates enacted on this node
-    :vartype policy_templates: [:class:`PolicyTemplate`]
-    :ivar substitution_template_mapping: our contribution to service substitution
-    :vartype substitution_template_mapping: :class:`SubstitutionTemplateMapping`
-    :ivar nodes: instantiated nodes
-    :vartype nodes: [:class:`Node`]
+    Template for creating zero or more :class:`Node` instances, which are typed vertices in the
+    service topology.
     """
 
     __tablename__ = 'node_template'
@@ -446,20 +469,6 @@ class NodeTemplateBase(TemplateModelMixin):
     __private_fields__ = ('type_fk',
                           'service_template_fk')
 
-    # region foreign_keys
-
-    @declared_attr
-    def type_fk(cls):
-        """For NodeTemplate many-to-one to Type"""
-        return relationship.foreign_key('type')
-
-    @declared_attr
-    def service_template_fk(cls):
-        """For ServiceTemplate one-to-many to NodeTemplate"""
-        return relationship.foreign_key('service_template')
-
-    # endregion
-
     # region association proxies
 
     @declared_attr
@@ -482,30 +491,65 @@ class NodeTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def nodes(cls):
+        """
+        Instantiated nodes.
+
+        :type: [:class:`Node`]
+        """
         return relationship.one_to_many(cls, 'node')
 
     @declared_attr
     def interface_templates(cls):
+        """
+        Associated interface templates.
+
+        :type: {:obj:`basestring`: :class:`InterfaceTemplate`}
+        """
         return relationship.one_to_many(cls, 'interface_template', dict_key='name')
 
     @declared_attr
     def artifact_templates(cls):
+        """
+        Associated artifacts.
+
+        :type: {:obj:`basestring`: :class:`ArtifactTemplate`}
+        """
         return relationship.one_to_many(cls, 'artifact_template', dict_key='name')
 
     @declared_attr
     def capability_templates(cls):
+        """
+        Associated exposed capability templates.
+
+        :type: {:obj:`basestring`: :class:`CapabilityTemplate`}
+        """
         return relationship.one_to_many(cls, 'capability_template', dict_key='name')
 
     @declared_attr
     def requirement_templates(cls):
+        """
+        Associated potential relationships with other nodes.
+
+        :type: [:class:`RequirementTemplate`]
+        """
         return relationship.one_to_many(cls, 'requirement_template', child_fk='node_template_fk')
 
     @declared_attr
     def properties(cls):
+        """
+        Declarations for associated immutable parameters.
+
+        :type: {:obj:`basestring`: :class:`Property`}
+        """
         return relationship.one_to_many(cls, 'property', dict_key='name')
 
     @declared_attr
     def attributes(cls):
+        """
+        Declarations for associated mutable parameters.
+
+        :type: {:obj:`basestring`: :class:`Attribute`}
+        """
         return relationship.one_to_many(cls, 'attribute', dict_key='name')
 
     # endregion
@@ -514,19 +558,67 @@ class NodeTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def type(cls):
+        """
+        Node type.
+
+        :type: :class:`Type`
+        """
         return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
 
     @declared_attr
     def service_template(cls):
+        """
+        Containing service template.
+
+        :type: :class:`ServiceTemplate`
+        """
         return relationship.many_to_one(cls, 'service_template')
 
     # endregion
 
-    description = Column(Text)
-    default_instances = Column(Integer, default=1)
-    min_instances = Column(Integer, default=0)
-    max_instances = Column(Integer, default=None)
-    target_node_template_constraints = Column(PickleType)
+    # region foreign_keys
+
+    @declared_attr
+    def type_fk(cls):
+        """For NodeTemplate many-to-one to Type"""
+        return relationship.foreign_key('type')
+
+    @declared_attr
+    def service_template_fk(cls):
+        """For ServiceTemplate one-to-many to NodeTemplate"""
+        return relationship.foreign_key('service_template')
+
+    # endregion
+
+    description = Column(Text, doc="""
+    Human-readable description.
+
+    :type: :obj:`basestring`
+    """)
+
+    default_instances = Column(Integer, default=1, doc="""
+    Default number nodes that will appear in the service.
+
+    :type: :obj:`int`
+    """)
+
+    min_instances = Column(Integer, default=0, doc="""
+    Minimum number nodes that will appear in the service.
+
+    :type: :obj:`int`
+    """)
+
+    max_instances = Column(Integer, default=None, doc="""
+    Maximum number nodes that will appear in the service.
+
+    :type: :obj:`int`
+    """)
+
+    target_node_template_constraints = Column(PickleType, doc="""
+    Constraints for filtering relationship targets.
+
+    :type: [:class:`NodeTemplateConstraint`]
+    """)
 
     def is_target_node_template_valid(self, target_node_template):
         if self.target_node_template_constraints:
@@ -617,28 +709,8 @@ class NodeTemplateBase(TemplateModelMixin):
 
 class GroupTemplateBase(TemplateModelMixin):
     """
-    A template for creating a :class:`Group` instance.
-
-    Groups are logical containers for zero or more nodes.
-
-    :ivar name: name (unique for this service template)
-    :vartype name: basestring
-    :ivar type: group type
-    
-    :ivar description: human-readable description
-    :vartype description: basestring
-    :ivar node_templates: all nodes instantiated by these templates will be members of the group
-    :vartype node_templates: [:class:`NodeTemplate`]
-    :ivar properties: associated parameters
-    :vartype properties: {:obj:`basestring`: :class:`Property`}
-    :ivar interface_templates: bundles of operations
-    :vartype interface_templates: {:obj:`basestring`: :class:`InterfaceTemplate`}
-    :ivar service_template: containing service template
-    :vartype service_template: :class:`ServiceTemplate`
-    :ivar policy_templates: policy templates enacted on this group
-    :vartype policy_templates: [:class:`PolicyTemplate`]
-    :ivar groups: instantiated groups
-    :vartype groups: [:class:`Group`]
+    Template for creating a :class:`Group` instance, which is a typed logical container for zero or
+    more :class:`Node` instances.
     """
 
     __tablename__ = 'group_template'
@@ -646,20 +718,6 @@ class GroupTemplateBase(TemplateModelMixin):
     __private_fields__ = ('type_fk',
                           'service_template_fk')
 
-    # region foreign keys
-
-    @declared_attr
-    def type_fk(cls):
-        """For GroupTemplate many-to-one to Type"""
-        return relationship.foreign_key('type')
-
-    @declared_attr
-    def service_template_fk(cls):
-        """For ServiceTemplate one-to-many to GroupTemplate"""
-        return relationship.foreign_key('service_template')
-
-    # endregion
-
     # region association proxies
 
     # endregion
@@ -672,14 +730,29 @@ class GroupTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def groups(cls):
+        """
+        Instantiated groups.
+
+        :type: [:class:`Group`]
+        """
         return relationship.one_to_many(cls, 'group')
 
     @declared_attr
     def interface_templates(cls):
+        """
+        Associated interface templates.
+
+        :type: {:obj:`basestring`: :class:`InterfaceTemplate`}
+        """
         return relationship.one_to_many(cls, 'interface_template', dict_key='name')
 
     @declared_attr
     def properties(cls):
+        """
+        Declarations for associated immutable parameters.
+
+        :type: {:obj:`basestring`: :class:`Property`}
+        """
         return relationship.one_to_many(cls, 'property', dict_key='name')
 
     # endregion
@@ -688,10 +761,20 @@ class GroupTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def service_template(cls):
+        """
+        Containing service template.
+
+        :type: :class:`ServiceTemplate`
+        """
         return relationship.many_to_one(cls, 'service_template')
 
     @declared_attr
     def type(cls):
+        """
+        Group type.
+
+        :type: :class:`Type`
+        """
         return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
 
     # endregion
@@ -700,18 +783,41 @@ class GroupTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def node_templates(cls):
+        """
+        Nodes instantiated by these templates will be members of the group.
+
+        :type: [:class:`NodeTemplate`]
+        """
         return relationship.many_to_many(cls, 'node_template')
 
     # endregion
 
-    description = Column(Text)
+    # region foreign keys
 
-    @property
-    def as_raw(self):
-        return collections.OrderedDict((
-            ('name', self.name),
-            ('description', self.description),
-            ('type_name', self.type.name),
+    @declared_attr
+    def type_fk(cls):
+        """For GroupTemplate many-to-one to Type"""
+        return relationship.foreign_key('type')
+
+    @declared_attr
+    def service_template_fk(cls):
+        """For ServiceTemplate one-to-many to GroupTemplate"""
+        return relationship.foreign_key('service_template')
+
+    # endregion
+
+    description = Column(Text, doc="""
+    Human-readable description.
+
+    :type: :obj:`basestring`
+    """)
+
+    @property
+    def as_raw(self):
+        return collections.OrderedDict((
+            ('name', self.name),
+            ('description', self.description),
+            ('type_name', self.type.name),
             ('properties', formatting.as_raw_dict(self.properties)),
             ('interface_templates', formatting.as_raw_list(self.interface_templates))))
 
@@ -752,24 +858,8 @@ class GroupTemplateBase(TemplateModelMixin):
 
 class PolicyTemplateBase(TemplateModelMixin):
     """
-    Policies can be applied to zero or more :class:`NodeTemplate` or :class:`GroupTemplate`
-    instances.
-
-    :ivar name: name (unique for this service template)
-    :vartype name: basestring
-    :ivar type: policy type
-    :ivar description: human-readable description
-    :vartype description: basestring
-    :ivar node_templates: policy will be enacted on all nodes instantiated by these templates
-    :vartype node_templates: [:class:`NodeTemplate`]
-    :ivar group_templates: policy will be enacted on all nodes in these groups
-    :vartype group_templates: [:class:`GroupTemplate`]
-    :ivar properties: associated parameters
-    :vartype properties: {:obj:`basestring`: :class:`Property`}
-    :ivar service_template: containing service template
-    :vartype service_template: :class:`ServiceTemplate`
-    :ivar policies: instantiated policies
-    :vartype policies: [:class:`Policy`]
+    Template for creating a :class:`Policy` instance, which is a typed set of orchestration hints
+    applied to zero or more :class:`Node` or :class:`Group` instances.
     """
 
     __tablename__ = 'policy_template'
@@ -777,20 +867,6 @@ class PolicyTemplateBase(TemplateModelMixin):
     __private_fields__ = ('type_fk',
                           'service_template_fk')
 
-    # region foreign keys
-
-    @declared_attr
-    def type_fk(cls):
-        """For PolicyTemplate many-to-one to Type"""
-        return relationship.foreign_key('type')
-
-    @declared_attr
-    def service_template_fk(cls):
-        """For ServiceTemplate one-to-many to PolicyTemplate"""
-        return relationship.foreign_key('service_template')
-
-    # endregion
-
     # region association proxies
 
     # endregion
@@ -803,10 +879,20 @@ class PolicyTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def policies(cls):
+        """
+        Instantiated policies.
+
+        :type: [:class:`Policy`]
+        """
         return relationship.one_to_many(cls, 'policy')
 
     @declared_attr
     def properties(cls):
+        """
+        Declarations for associated immutable parameters.
+
+        :type: {:obj:`basestring`: :class:`Property`}
+        """
         return relationship.one_to_many(cls, 'property', dict_key='name')
 
     # endregion
@@ -815,10 +901,20 @@ class PolicyTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def service_template(cls):
+        """
+        Containing service template.
+
+        :type: :class:`ServiceTemplate`
+        """
         return relationship.many_to_one(cls, 'service_template')
 
     @declared_attr
     def type(cls):
+        """
+        Policy type.
+
+        :type: :class:`Type`
+        """
         return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
 
     # endregion
@@ -827,15 +923,43 @@ class PolicyTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def node_templates(cls):
+        """
+        Policy will be enacted on all nodes instantiated by these templates.
+
+        :type: {:obj:`basestring`: :class:`NodeTemplate`}
+        """
         return relationship.many_to_many(cls, 'node_template')
 
     @declared_attr
     def group_templates(cls):
+        """
+        Policy will be enacted on all nodes in all groups instantiated by these templates.
+
+        :type: {:obj:`basestring`: :class:`GroupTemplate`}
+        """
         return relationship.many_to_many(cls, 'group_template')
 
     # endregion
 
-    description = Column(Text)
+    # region foreign keys
+
+    @declared_attr
+    def type_fk(cls):
+        """For PolicyTemplate many-to-one to Type"""
+        return relationship.foreign_key('type')
+
+    @declared_attr
+    def service_template_fk(cls):
+        """For ServiceTemplate one-to-many to PolicyTemplate"""
+        return relationship.foreign_key('service_template')
+
+    # endregion
+
+    description = Column(Text, doc="""
+    Human-readable description.
+
+    :type: :obj:`basestring`
+    """)
 
     @property
     def as_raw(self):
@@ -884,31 +1008,14 @@ class PolicyTemplateBase(TemplateModelMixin):
 
 class SubstitutionTemplateBase(TemplateModelMixin):
     """
-    Used to substitute a single node for the entire deployment.
-
-    :ivar node_type: exposed node type
-    :vartype node_type: Type
-    :ivar mappings: requirement and capability mappings
-    :vartype mappings: {:obj:`basestring`: :class:`SubstitutionTemplateMapping`}
-    :ivar service_template: containing service template
-    :vartype service_template: :class:`ServiceTemplate`
-    :ivar substitutions: instantiated substitutions
-    :vartype substitutions: [:class:`Substitution`]
+    Template for creating a :class:`Substitution` instance, which exposes an entire instantiated
+    service as a single node.
     """
 
     __tablename__ = 'substitution_template'
 
     __private_fields__ = ('node_type_fk',)
 
-    # region foreign keys
-
-    @declared_attr
-    def node_type_fk(cls):
-        """For SubstitutionTemplate many-to-one to Type"""
-        return relationship.foreign_key('type')
-
-    # endregion
-
     # region association proxies
 
     # endregion
@@ -921,10 +1028,20 @@ class SubstitutionTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def substitutions(cls):
+        """
+        Instantiated substitutions.
+
+        :type: [:class:`Substitution`]
+        """
         return relationship.one_to_many(cls, 'substitution')
 
     @declared_attr
     def mappings(cls):
+        """
+        Map requirement and capabilities to exposed node.
+
+        :type: {:obj:`basestring`: :class:`SubstitutionTemplateMapping`}
+        """
         return relationship.one_to_many(cls, 'substitution_template_mapping', dict_key='name')
 
     # endregion
@@ -933,10 +1050,24 @@ class SubstitutionTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def node_type(cls):
+        """
+        Exposed node type.
+
+        :type: :class:`Type`
+        """
         return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
 
     # endregion
 
+    # region foreign keys
+
+    @declared_attr
+    def node_type_fk(cls):
+        """For SubstitutionTemplate many-to-one to Type"""
+        return relationship.foreign_key('type')
+
+    # endregion
+
     @property
     def as_raw(self):
         return collections.OrderedDict((
@@ -966,53 +1097,21 @@ class SubstitutionTemplateBase(TemplateModelMixin):
 
 class SubstitutionTemplateMappingBase(TemplateModelMixin):
     """
-    Used by :class:`SubstitutionTemplate` to map a capability or a requirement to a node.
-
-    Only one of `capability_template` and `requirement_template` can be set.
-
-    :ivar name: exposed capability or requirement name
-    :vartype name: basestring
-    :ivar node_template: node template
-    :vartype node_template: NodeTemplate
-    :ivar capability_template: capability template in the node template
-    :vartype capability_template: CapabilityTemplate
-    :ivar requirement_template: requirement template in the node template
-    :vartype requirement_template: RequirementTemplate
-    :ivar substitution_template: containing substitution template
-    :vartype substitution_template: SubstitutionTemplate
+    Used by :class:`SubstitutionTemplate` to map a capability template or a requirement template to
+    the exposed node.
+
+    The :attr:`name` field should match the capability or requirement name on the exposed node's
+    type.
+
+    Only one of :attr:`capability_template` and :attr:`requirement_template` can be set.
     """
 
     __tablename__ = 'substitution_template_mapping'
 
     __private_fields__ = ('substitution_template_fk',
-                          'node_template_fk',
                           'capability_template_fk',
                           'requirement_template_fk')
 
-    # region foreign keys
-
-    @declared_attr
-    def substitution_template_fk(cls):
-        """For SubstitutionTemplate one-to-many to SubstitutionTemplateMapping"""
-        return relationship.foreign_key('substitution_template')
-
-    @declared_attr
-    def node_template_fk(cls):
-        """For SubstitutionTemplate one-to-one to NodeTemplate"""
-        return relationship.foreign_key('node_template')
-
-    @declared_attr
-    def capability_template_fk(cls):
-        """For SubstitutionTemplate one-to-one to CapabilityTemplate"""
-        return relationship.foreign_key('capability_template', nullable=True)
-
-    @declared_attr
-    def requirement_template_fk(cls):
-        """For SubstitutionTemplate one-to-one to RequirementTemplate"""
-        return relationship.foreign_key('requirement_template', nullable=True)
-
-    # endregion
-
     # region association proxies
 
     # endregion
@@ -1020,17 +1119,22 @@ class SubstitutionTemplateMappingBase(TemplateModelMixin):
     # region one_to_one relationships
 
     @declared_attr
-    def node_template(cls):
-        return relationship.one_to_one(
-            cls, 'node_template', back_populates=relationship.NO_BACK_POP)
-
-    @declared_attr
     def capability_template(cls):
+        """
+        Capability template to expose (can be ``None``).
+
+        :type: :class:`CapabilityTemplate`
+        """
         return relationship.one_to_one(
             cls, 'capability_template', back_populates=relationship.NO_BACK_POP)
 
     @declared_attr
     def requirement_template(cls):
+        """
+        Requirement template to expose (can be ``None``).
+
+        :type: :class:`RequirementTemplate`
+        """
         return relationship.one_to_one(
             cls, 'requirement_template', back_populates=relationship.NO_BACK_POP)
 
@@ -1044,10 +1148,34 @@ class SubstitutionTemplateMappingBase(TemplateModelMixin):
 
     @declared_attr
     def substitution_template(cls):
+        """
+        Containing substitution template.
+
+        :type: :class:`SubstitutionTemplate`
+        """
         return relationship.many_to_one(cls, 'substitution_template', back_populates='mappings')
 
     # endregion
 
+    # region foreign keys
+
+    @declared_attr
+    def substitution_template_fk(cls):
+        """For SubstitutionTemplate one-to-many to SubstitutionTemplateMapping"""
+        return relationship.foreign_key('substitution_template')
+
+    @declared_attr
+    def capability_template_fk(cls):
+        """For SubstitutionTemplate one-to-one to CapabilityTemplate"""
+        return relationship.foreign_key('capability_template', nullable=True)
+
+    @declared_attr
+    def requirement_template_fk(cls):
+        """For SubstitutionTemplate one-to-one to RequirementTemplate"""
+        return relationship.foreign_key('requirement_template', nullable=True)
+
+    # endregion
+
     @property
     def as_raw(self):
         return collections.OrderedDict((
@@ -1059,7 +1187,11 @@ class SubstitutionTemplateMappingBase(TemplateModelMixin):
     def instantiate(self, container):
         from . import models
         context = ConsumptionContext.get_thread_local()
-        nodes = self.node_template.nodes
+        if self.capability_template is not None:
+            node_template = self.capability_template.node_template
+        else:
+            node_template = self.requirement_template.node_template
+        nodes = node_template.nodes
         if len(nodes) == 0:
             context.validation.report(
                 'mapping "{0}" refers to node template "{1}" but there are no '
@@ -1075,9 +1207,10 @@ class SubstitutionTemplateMappingBase(TemplateModelMixin):
                 if a_capability.capability_template.name == self.capability_template.name:
                     capability = a_capability
         return models.SubstitutionMapping(name=self.name,
-                                          node=node,
                                           capability=capability,
-                                          requirement_template=self.requirement_template)
+                                          requirement_template=self.requirement_template,
+                                          node=node)
+
 
     def validate(self):
         context = ConsumptionContext.get_thread_local()
@@ -1090,9 +1223,13 @@ class SubstitutionTemplateMappingBase(TemplateModelMixin):
 
     def dump(self):
         context = ConsumptionContext.get_thread_local()
+        if self.capability_template is not None:
+            node_template = self.capability_template.node_template
+        else:
+            node_template = self.requirement_template.node_template
         console.puts('{0} -> {1}.{2}'.format(
             context.style.node(self.name),
-            context.style.node(self.node_template.name),
+            context.style.node(node_template.name),
             context.style.node(self.capability_template.name
                                if self.capability_template
                                else self.requirement_template.name)))
@@ -1100,70 +1237,26 @@ class SubstitutionTemplateMappingBase(TemplateModelMixin):
 
 class RequirementTemplateBase(TemplateModelMixin):
     """
-    A requirement for a :class:`NodeTemplate`. During instantiation will be matched with a
-    capability of another node.
-
-    Requirements may optionally contain a :class:`RelationshipTemplate` that will be created between
-    the nodes.
-
-    :ivar name: name (a node template can have multiple requirements with the same name)
-    :vartype name: basestring
-    :ivar target_node_type: required node type (optional)
-    :vartype target_node_type: Type
-    :ivar target_node_template: required node template (optional)
-    :vartype target_node_template: NodeTemplate
-    :ivar target_capability_type: required capability type (optional)
-    :vartype target_capability_type: Type
-    :ivar target_capability_name: name of capability in target node (optional)
-    :vartype target_capability_name: basestring
-    :ivar target_node_template_constraints: constraints for filtering relationship targets
-    :vartype target_node_template_constraints: [:class:`NodeTemplateConstraint`]
-    :ivar relationship_template: template for relationships (optional)
-    :vartype relationship_template: RelationshipTemplate
-    :ivar node_template: containing node template
-    :vartype node_template: NodeTemplate
-    :ivar substitution_template_mapping: our contribution to service substitution
-    :vartype substitution_template_mapping: :class:`SubstitutionTemplateMapping`
-    :ivar substitution_mapping: our contribution to service substitution
-    :vartype substitution_mapping: SubstitutionMapping
-    """
-
-    __tablename__ = 'requirement_template'
-
-    __private_fields__ = ('target_node_type_fk',
-                          'target_node_template_fk',
-                          'target_capability_type_fk'
-                          'node_template_fk',
-                          'relationship_template_fk')
-
-    # region foreign keys
-
-    @declared_attr
-    def target_node_type_fk(cls):
-        """For RequirementTemplate many-to-one to Type"""
-        return relationship.foreign_key('type', nullable=True)
+    Template for creating :class:`Relationship` instances, which are optionally-typed edges in the
+    service topology, connecting a :class:`Node` to a :class:`Capability` of another node.
 
-    @declared_attr
-    def target_node_template_fk(cls):
-        """For RequirementTemplate one-to-one to NodeTemplate"""
-        return relationship.foreign_key('node_template', nullable=True)
+    Note that there is no equivalent "Requirement" instance model. Instead, during instantiation a
+    requirement template is matched with a capability and a :class:`Relationship` is instantiated.
 
-    @declared_attr
-    def target_capability_type_fk(cls):
-        """For RequirementTemplate one-to-one to NodeTemplate"""
-        return relationship.foreign_key('type', nullable=True)
+    A requirement template *must* target a :class:`CapabilityType` or a capability name. It can
+    optionally target a specific :class:`NodeType` or :class:`NodeTemplate`.
 
-    @declared_attr
-    def node_template_fk(cls):
-        """For NodeTemplate one-to-many to RequirementTemplate"""
-        return relationship.foreign_key('node_template')
+    Requirement templates may optionally contain a :class:`RelationshipTemplate`. If they do not,
+    a :class:`Relationship` will be instantiated with default values.
+    """
 
-    @declared_attr
-    def relationship_template_fk(cls):
-        """For RequirementTemplate one-to-one to RelationshipTemplate"""
-        return relationship.foreign_key('relationship_template', nullable=True)
+    __tablename__ = 'requirement_template'
 
-    # endregion
+    __private_fields__ = ('target_capability_type_fk',
+                          'target_node_template_fk',
+                          'target_node_type_fk',
+                          'relationship_template_fk',
+                          'node_template_fk')
 
     # region association proxies
 
@@ -1172,21 +1265,36 @@ class RequirementTemplateBase(TemplateModelMixin):
     # region one_to_one relationships
 
     @declared_attr
-    def target_node_template(cls):
+    def target_capability_type(cls):
+        """
+        Target capability type.
+
+        :type: :class:`CapabilityType`
+        """
         return relationship.one_to_one(cls,
-                                       'node_template',
-                                       fk='target_node_template_fk',
+                                       'type',
+                                       fk='target_capability_type_fk',
                                        back_populates=relationship.NO_BACK_POP)
 
     @declared_attr
-    def target_capability_type(cls):
+    def target_node_template(cls):
+        """
+        Target node template (can be ``None``).
+
+        :type: :class:`NodeTemplate`
+        """
         return relationship.one_to_one(cls,
-                                       'type',
-                                       fk='target_capability_type_fk',
+                                       'node_template',
+                                       fk='target_node_template_fk',
                                        back_populates=relationship.NO_BACK_POP)
 
     @declared_attr
     def relationship_template(cls):
+        """
+        Associated relationship template (can be ``None``).
+
+        :type: :class:`RelationshipTemplate`
+        """
         return relationship.one_to_one(cls, 'relationship_template')
 
     # endregion
@@ -1195,6 +1303,11 @@ class RequirementTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def relationships(cls):
+        """
+        Instantiated relationships.
+
+        :type: [:class:`Relationship`]
+        """
         return relationship.one_to_many(cls, 'relationship')
 
     # endregion
@@ -1203,17 +1316,65 @@ class RequirementTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def node_template(cls):
+        """
+        Containing node template.
+
+        :type: :class:`NodeTemplate`
+        """
         return relationship.many_to_one(cls, 'node_template', fk='node_template_fk')
 
     @declared_attr
     def target_node_type(cls):
+        """
+        Target node type (can be ``None``).
+
+        :type: :class:`Type`
+        """
         return relationship.many_to_one(
             cls, 'type', fk='target_node_type_fk', back_populates=relationship.NO_BACK_POP)
 
     # endregion
 
-    target_capability_name = Column(Text)
-    target_node_template_constraints = Column(PickleType)
+    # region foreign keys
+
+    @declared_attr
+    def target_node_type_fk(cls):
+        """For RequirementTemplate many-to-one to Type"""
+        return relationship.foreign_key('type', nullable=True)
+
+    @declared_attr
+    def target_node_template_fk(cls):
+        """For RequirementTemplate one-to-one to NodeTemplate"""
+        return relationship.foreign_key('node_template', nullable=True)
+
+    @declared_attr
+    def target_capability_type_fk(cls):
+        """For RequirementTemplate one-to-one to Type"""
+        return relationship.foreign_key('type', nullable=True)
+
+    @declared_attr
+    def node_template_fk(cls):
+        """For NodeTemplate one-to-many to RequirementTemplate"""
+        return relationship.foreign_key('node_template')
+
+    @declared_attr
+    def relationship_template_fk(cls):
+        """For RequirementTemplate one-to-one to RelationshipTemplate"""
+        return relationship.foreign_key('relationship_template', nullable=True)
+
+    # endregion
+
+    target_capability_name = Column(Text, doc="""
+    Target capability name in node template or node type (can be ``None``).
+
+    :type: :obj:`basestring`
+    """)
+
+    target_node_template_constraints = Column(PickleType, doc="""
+    Constraints for filtering relationship targets.
+
+    :type: [:class:`NodeTemplateConstraint`]
+    """)
 
     def find_target(self, source_node_template):
         context = ConsumptionContext.get_thread_local()
@@ -1318,43 +1479,18 @@ class RequirementTemplateBase(TemplateModelMixin):
 
 class RelationshipTemplateBase(TemplateModelMixin):
     """
-    Optional addition to a :class:`RequirementTemplate` in :class:`NodeTemplate` that can be applied
-    when the requirement is matched with a capability.
-
-    Note that a relationship template here is not equivalent to a relationship template entity in
-    TOSCA. For example, a TOSCA requirement specifying a relationship type instead of a template
-    would still be represented here as a relationship template.
+    Optional addition to a :class:`RequirementTemplate`.
 
-    :ivar name: name (optional; if present is unique for this service template)
-    :vartype name: basestring
-    :ivar type: relationship type
-    
-    :ivar description: human-readable description
-    :vartype description: basestring
-    :ivar properties: associated parameters
-    :vartype properties: {:obj:`basestring`: :class:`Property`}
-    :ivar interface_templates: bundles of operations
-    :vartype interface_templates: {:obj:`basestring`: :class:`InterfaceTemplate`}
-    :ivar requirement_template: containing requirement template
-    :vartype requirement_template: RequirementTemplate
-    :ivar relationships: instantiated relationships
-    :vartype relationships: [:class:`Relationship`]
+    Note that a relationship template here is not exactly equivalent to a relationship template
+    entity in TOSCA. For example, a TOSCA requirement specifying a relationship type rather than a
+    relationship template would still be represented here as a relationship template.
     """
 
     __tablename__ = 'relationship_template'
 
     __private_fields__ = ('type_fk',)
 
-    # region foreign keys
-
-    @declared_attr
-    def type_fk(cls):
-        """For RelationshipTemplate many-to-one to Type"""
-        return relationship.foreign_key('type', nullable=True)
-
-    # endregion
-
-    # region association proxies
+    # region association proxies
 
     # endregion
 
@@ -1366,14 +1502,29 @@ class RelationshipTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def relationships(cls):
+        """
+        Instantiated relationships.
+
+        :type: [:class:`Relationship`]
+        """
         return relationship.one_to_many(cls, 'relationship')
 
     @declared_attr
     def interface_templates(cls):
+        """
+        Associated interface templates.
+
+        :type: {:obj:`basestring`: :class:`InterfaceTemplate`}
+        """
         return relationship.one_to_many(cls, 'interface_template', dict_key='name')
 
     @declared_attr
     def properties(cls):
+        """
+        Declarations for associated immutable parameters.
+
+        :type: {:obj:`basestring`: :class:`Property`}
+        """
         return relationship.one_to_many(cls, 'property', dict_key='name')
 
     # endregion
@@ -1382,11 +1533,29 @@ class RelationshipTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def type(cls):
+        """
+        Relationship type.
+
+        :type: :class:`Type`
+        """
         return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
 
     # endregion
 
-    description = Column(Text)
+    # region foreign keys
+
+    @declared_attr
+    def type_fk(cls):
+        """For RelationshipTemplate many-to-one to Type"""
+        return relationship.foreign_key('type', nullable=True)
+
+    # endregion
+
+    description = Column(Text, doc="""
+    Human-readable description.
+
+    :type: :obj:`basestring`
+    """)
 
     @property
     def as_raw(self):
@@ -1431,29 +1600,9 @@ class RelationshipTemplateBase(TemplateModelMixin):
 
 class CapabilityTemplateBase(TemplateModelMixin):
     """
-    A capability of a :class:`NodeTemplate`. Nodes expose zero or more capabilities that can be
-    matched with :class:`Requirement` instances of other nodes.
-
-    :ivar name: name (unique for the node template)
-    :vartype name: basestring
-    :ivar type: capability type
-    
-    :ivar description: human-readable description
-    :vartype description: basestring
-    :ivar valid_source_node_types: reject requirements that are not from these node types (optional)
-    :vartype valid_source_node_types: Type`
-    :ivar min_occurrences: minimum number of requirement matches required
-    :vartype min_occurrences: int
-    :ivar max_occurrences: maximum number of requirement matches allowed
-    :vartype min_occurrences: int
-    :ivar properties: associated parameters
-    :vartype properties: {:obj:`basestring`: :class:`Property`}
-    :ivar node_template: containing node template
-    :vartype node_template: NodeTemplate
-    :ivar substitution_template_mapping: our contribution to service substitution
-    :vartype substitution_template_mapping: SubstitutionTemplateMapping
-    :ivar capabilities: instantiated capabilities
-    :vartype capabilities: [:class:`Capability`]
+    Template for creating :class:`Capability` instances, typed attachments which serve two purposes:
+    to provide extra properties and attributes to :class:`Node` instances, and to expose targets for
+    :class:`Relationship` instances from other nodes.
     """
 
     __tablename__ = 'capability_template'
@@ -1461,21 +1610,6 @@ class CapabilityTemplateBase(TemplateModelMixin):
     __private_fields__ = ('type_fk',
                           'node_template_fk')
 
-    # region foreign keys
-
-    @declared_attr
-    def type_fk(cls):
-        """For CapabilityTemplate many-to-one to Type"""
-        return relationship.foreign_key('type')
-
-    @declared_attr
-    def node_template_fk(cls):
-        """For NodeTemplate one-to-many to CapabilityTemplate"""
-        return relationship.foreign_key('node_template')
-
-    # endregion
-
-
     # region association proxies
 
     # endregion
@@ -1488,10 +1622,20 @@ class CapabilityTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def capabilities(cls):
+        """
+        Instantiated capabilities.
+
+        :type: [:class:`Capability`]
+        """
         return relationship.one_to_many(cls, 'capability')
 
     @declared_attr
     def properties(cls):
+        """
+        Declarations for associated immutable parameters.
+
+        :type: {:obj:`basestring`: :class:`Property`}
+        """
         return relationship.one_to_many(cls, 'property', dict_key='name')
 
     # endregion
@@ -1500,10 +1644,20 @@ class CapabilityTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def node_template(cls):
+        """
+        Containing node template.
+
+        :type: :class:`NodeTemplate`
+        """
         return relationship.many_to_one(cls, 'node_template')
 
     @declared_attr
     def type(cls):
+        """
+        Capability type.
+
+        :type: :class:`Type`
+        """
         return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
 
     # endregion
@@ -1512,13 +1666,46 @@ class CapabilityTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def valid_source_node_types(cls):
+        """
+        Reject requirements that are not from these node types.
+
+        :type: [:class:`Type`]
+        """
         return relationship.many_to_many(cls, 'type', prefix='valid_sources')
 
     # endregion
 
-    description = Column(Text)
-    min_occurrences = Column(Integer, default=None)  # optional
-    max_occurrences = Column(Integer, default=None)  # optional
+    # region foreign keys
+
+    @declared_attr
+    def type_fk(cls):
+        """For CapabilityTemplate many-to-one to Type"""
+        return relationship.foreign_key('type')
+
+    @declared_attr
+    def node_template_fk(cls):
+        """For NodeTemplate one-to-many to CapabilityTemplate"""
+        return relationship.foreign_key('node_template')
+
+    # endregion
+
+    description = Column(Text, doc="""
+    Human-readable description.
+
+    :type: :obj:`basestring`
+    """)
+
+    min_occurrences = Column(Integer, default=None, doc="""
+    Minimum number of requirement matches required.
+
+    :type: :obj:`int`
+    """)
+
+    max_occurrences = Column(Integer, default=None, doc="""
+    Maximum number of requirement matches allowed.
+
+    :type: :obj:`int`
+    """)
 
     def satisfies_requirement(self,
                               source_node_template,
@@ -1593,26 +1780,11 @@ class CapabilityTemplateBase(TemplateModelMixin):
 
 class InterfaceTemplateBase(TemplateModelMixin):
     """
-    A typed set of :class:`OperationTemplate`.
+    Template for creating :class:`Interface` instances, which are typed bundles of
+    :class:`Operation` instances.
 
-    :ivar name: name (unique for the node, group, or relationship template)
-    :vartype name: basestring
-    :ivar type: interface type
-    
-    :ivar description: human-readable description
-    :vartype description: basestring
-    :ivar inputs: inputs that can be used by all operations in the interface
-    :vartype inputs: {:obj:`basestring`: :class:`Input`}
-    :ivar operation_templates: operations
-    :vartype operation_templates: {:obj:`basestring`: :class:`OperationTemplate`}
-    :ivar node_template: containing node template
-    :vartype node_template: NodeTemplate
-    :ivar group_template: containing group template
-    :vartype group_template: GroupTemplate
-    :ivar relationship_template: containing relationship template
-    :vartype relationship_template: RelationshipTemplate
-    :ivar interfaces: instantiated interfaces
-    :vartype interfaces: [:class:`Interface`]
+    Can be associated with a :class:`NodeTemplate`, a :class:`GroupTemplate`, or a
+    :class:`RelationshipTemplate`.
     """
 
     __tablename__ = 'interface_template'
@@ -1622,30 +1794,6 @@ class InterfaceTemplateBase(TemplateModelMixin):
                           'group_template_fk',
                           'relationship_template_fk')
 
-    # region foreign keys
-
-    @declared_attr
-    def type_fk(cls):
-        """For InterfaceTemplate many-to-one to Type"""
-        return relationship.foreign_key('type')
-
-    @declared_attr
-    def node_template_fk(cls):
-        """For NodeTemplate one-to-many to InterfaceTemplate"""
-        return relationship.foreign_key('node_template', nullable=True)
-
-    @declared_attr
-    def group_template_fk(cls):
-        """For GroupTemplate one-to-many to InterfaceTemplate"""
-        return relationship.foreign_key('group_template', nullable=True)
-
-    @declared_attr
-    def relationship_template_fk(cls):
-        """For RelationshipTemplate one-to-many to InterfaceTemplate"""
-        return relationship.foreign_key('relationship_template', nullable=True)
-
-    # endregion
-
     # region association proxies
 
     # endregion
@@ -1658,14 +1806,30 @@ class InterfaceTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def inputs(cls):
+        """
+        Declarations for externally provided parameters that can be used by all operations of the
+        interface.
+
+        :type: {:obj:`basestring`: :class:`Input`}
+        """
         return relationship.one_to_many(cls, 'input', dict_key='name')
 
     @declared_attr
     def interfaces(cls):
+        """
+        Instantiated interfaces.
+
+        :type: [:class:`Interface`]
+        """
         return relationship.one_to_many(cls, 'interface')
 
     @declared_attr
     def operation_templates(cls):
+        """
+        Associated operation templates.
+
+        :type: {:obj:`basestring`: :class:`OperationTemplate`}
+        """
         return relationship.one_to_many(cls, 'operation_template', dict_key='name')
 
     # endregion
@@ -1673,24 +1837,72 @@ class InterfaceTemplateBase(TemplateModelMixin):
     # region many_to_one relationships
 
     @declared_attr
-    def relationship_template(cls):
-        return relationship.many_to_one(cls, 'relationship_template')
+    def node_template(cls):
+        """
+        Containing node template (can be ``None``).
+
+        :type: :class:`NodeTemplate`
+        """
+        return relationship.many_to_one(cls, 'node_template')
 
     @declared_attr
     def group_template(cls):
+        """
+        Containing group template (can be ``None``).
+
+        :type: :class:`GroupTemplate`
+        """
         return relationship.many_to_one(cls, 'group_template')
 
     @declared_attr
-    def node_template(cls):
-        return relationship.many_to_one(cls, 'node_template')
+    def relationship_template(cls):
+        """
+        Containing relationship template (can be ``None``).
+
+        :type: :class:`RelationshipTemplate`
+        """
+        return relationship.many_to_one(cls, 'relationship_template')
 
     @declared_attr
     def type(cls):
+        """
+        Interface type.
+
+        :type: :class:`Type`
+        """
         return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
 
     # endregion
 
-    description = Column(Text)
+    # region foreign keys
+
+    @declared_attr
+    def type_fk(cls):
+        """For InterfaceTemplate many-to-one to Type"""
+        return relationship.foreign_key('type')
+
+    @declared_attr
+    def node_template_fk(cls):
+        """For NodeTemplate one-to-many to InterfaceTemplate"""
+        return relationship.foreign_key('node_template', nullable=True)
+
+    @declared_attr
+    def group_template_fk(cls):
+        """For GroupTemplate one-to-many to InterfaceTemplate"""
+        return relationship.foreign_key('group_template', nullable=True)
+
+    @declared_attr
+    def relationship_template_fk(cls):
+        """For RelationshipTemplate one-to-many to InterfaceTemplate"""
+        return relationship.foreign_key('relationship_template', nullable=True)
+
+    # endregion
+
+    description = Column(Text, doc="""
+    Human-readable description.
+
+    :type: :obj:`basestring`
+    """)
 
     @property
     def as_raw(self):
@@ -1733,42 +1945,8 @@ class InterfaceTemplateBase(TemplateModelMixin):
 
 class OperationTemplateBase(TemplateModelMixin):
     """
-    An operation in a :class:`InterfaceTemplate`.
-
-    Operations are executed by an associated :class:`PluginSpecification` via an executor.
-
-    :ivar name: name (unique for the interface or service template)
-    :vartype name: basestring
-    :ivar description: human-readable description
-    :vartype description: basestring
-    :ivar relationship_edge: when ``True`` specifies that the operation is on the relationship's
-                             target edge instead of its source (only used by relationship
-                             operations)
-    :vartype relationship_edge: bool
-    :ivar implementation: implementation (interpreted by the plugin)
-    :vartype implementation: basestring
-    :ivar dependencies: dependency strings (interpreted by the plugin)
-    :vartype dependencies: [obj:`basestring`]
-    :ivar inputs: inputs that can be used by this operation
-    :vartype inputs: {:obj:`basestring`: :class:`Input`}
-    :ivar plugin_specification: associated plugin
-    :vartype plugin_specification: PluginSpecification
-    :ivar configurations: configuration (interpreted by the plugin)
-    :vartype configurations: {obj:`basestring`: :class:`Configuration`}
-    :ivar function: name of the operation function
-    :vartype function: basestring
-    :ivar executor: name of executor to run the operation with
-    :vartype executor: basestring
-    :ivar max_attempts: maximum number of attempts allowed in case of failure
-    :vartype max_attempts: int
-    :ivar retry_interval: interval between retries (in seconds)
-    :vartype retry_interval: int
-    :ivar interface_template: containing interface template
-    :vartype interface_template: InterfaceTemplate
-    :ivar service_template: containing service template
-    :vartype service_template: ServiceTemplate
-    :ivar operations: instantiated operations
-    :vartype operations: [:class:`Operation`]
+    Template for creating :class:`Operation` instances, which are entry points to Python functions
+    called as part of a workflow execution.
     """
 
     __tablename__ = 'operation_template'
@@ -1777,25 +1955,6 @@ class OperationTemplateBase(TemplateModelMixin):
                           'interface_template_fk',
                           'plugin_fk')
 
-    # region foreign keys
-
-    @declared_attr
-    def service_template_fk(cls):
-        """For ServiceTemplate one-to-many to OperationTemplate"""
-        return relationship.foreign_key('service_template', nullable=True)
-
-    @declared_attr
-    def interface_template_fk(cls):
-        """For InterfaceTemplate one-to-many to OperationTemplate"""
-        return relationship.foreign_key('interface_template', nullable=True)
-
-    @declared_attr
-    def plugin_specification_fk(cls):
-        """For OperationTemplate one-to-one to PluginSpecification"""
-        return relationship.foreign_key('plugin_specification', nullable=True)
-
-    # endregion
-
     # region association proxies
 
     # endregion
@@ -1804,6 +1963,11 @@ class OperationTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def plugin_specification(cls):
+        """
+        Associated plugin specification.
+
+        :type: :class:`PluginSpecification`
+        """
         return relationship.one_to_one(
             cls, 'plugin_specification', back_populates=relationship.NO_BACK_POP)
 
@@ -1812,15 +1976,30 @@ class OperationTemplateBase(TemplateModelMixin):
     # region one_to_many relationships
 
     @declared_attr
-    def inputs(cls):
-        return relationship.one_to_many(cls, 'input', dict_key='name')
-
-    @declared_attr
     def operations(cls):
+        """
+        Instantiated operations.
+
+        :type: [:class:`Operation`]
+        """
         return relationship.one_to_many(cls, 'operation')
 
     @declared_attr
+    def inputs(cls):
+        """
+        Declarations for parameters provided to the :attr:`implementation`.
+
+        :type: {:obj:`basestring`: :class:`Input`}
+        """
+        return relationship.one_to_many(cls, 'input', dict_key='name')
+
+    @declared_attr
     def configurations(cls):
+        """
+        Configuration parameters for the operation instance Python :attr:`function`.
+
+        :type: {:obj:`basestring`: :class:`Configuration`}
+        """
         return relationship.one_to_many(cls, 'configuration', dict_key='name')
 
     # endregion
@@ -1829,11 +2008,21 @@ class OperationTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def service_template(cls):
+        """
+        Containing service template (can be ``None``). For workflow operation templates.
+
+        :type: :class:`ServiceTemplate`
+        """
         return relationship.many_to_one(cls, 'service_template',
                                         back_populates='workflow_templates')
 
     @declared_attr
     def interface_template(cls):
+        """
+        Containing interface template (can be ``None``).
+
+        :type: :class:`InterfaceTemplate`
+        """
         return relationship.many_to_one(cls, 'interface_template')
 
     # endregion
@@ -1842,14 +2031,73 @@ class OperationTemplateBase(TemplateModelMixin):
 
     # endregion
 
-    description = Column(Text)
-    relationship_edge = Column(Boolean)
-    implementation = Column(Text)
-    dependencies = Column(modeling_types.StrictList(item_cls=basestring))
-    function = Column(Text)
-    executor = Column(Text)
-    max_attempts = Column(Integer)
-    retry_interval = Column(Integer)
+    # region foreign keys
+
+    @declared_attr
+    def service_template_fk(cls):
+        """For ServiceTemplate one-to-many to OperationTemplate"""
+        return relationship.foreign_key('service_template', nullable=True)
+
+    @declared_attr
+    def interface_template_fk(cls):
+        """For InterfaceTemplate one-to-many to OperationTemplate"""
+        return relationship.foreign_key('interface_template', nullable=True)
+
+    @declared_attr
+    def plugin_specification_fk(cls):
+        """For OperationTemplate one-to-one to PluginSpecification"""
+        return relationship.foreign_key('plugin_specification', nullable=True)
+
+    # endregion
+
+    description = Column(Text, doc="""
+    Human-readable description.
+
+    :type: :obj:`basestring`
+    """)
+
+    relationship_edge = Column(Boolean, doc="""
+    When ``True`` specifies that the operation is on the relationship's target edge; ``False`` is
+    the source edge (only used by operations on relationships)
+
+    :type: :obj:`bool`
+    """)
+
+    implementation = Column(Text, doc="""
+    Implementation (usually the name of an artifact).
+
+    :type: :obj:`basestring`
+    """)
+
+    dependencies = Column(modeling_types.StrictList(item_cls=basestring), doc="""
+    Dependencies (usually names of artifacts).
+
+    :type: [:obj:`basestring`]
+    """)
+
+    function = Column(Text, doc="""
+    Full path to Python function.
+
+    :type: :obj:`basestring`
+    """)
+
+    executor = Column(Text, doc="""
+    Name of executor.
+
+    :type: :obj:`basestring`
+    """)
+
+    max_attempts = Column(Integer, doc="""
+    Maximum number of attempts allowed in case of task failure.
+
+    :type: :obj:`int`
+    """)
+
+    retry_interval = Column(Integer, doc="""
+    Interval between task retry attemps (in seconds).
+
+    :type: :obj:`float`
+    """)
 
     @property
     def as_raw(self):
@@ -1922,28 +2170,8 @@ class OperationTemplateBase(TemplateModelMixin):
 
 class ArtifactTemplateBase(TemplateModelMixin):
     """
-    A file associated with a :class:`NodeTemplate`.
-
-    :ivar name: name (unique for the node template)
-    :vartype name: basestring
-    :ivar type: artifact type
-    
-    :ivar description: human-readable description
-    :vartype description: basestring
-    :ivar source_path: source path (CSAR or repository)
-    :vartype source_path: basestring
-    :ivar target_path: path at destination machine
-    :vartype target_path: basestring
-    :ivar repository_url: repository URL
-    :vartype repository_path: basestring
-    :ivar repository_credential: credentials for accessing the repository
-    :vartype repository_credential: {:obj:`basestring`: :obj:`basestring`}
-    :ivar properties: associated parameters
-    :vartype properties: {:obj:`basestring`: :class:`Property`}
-    :ivar node_template: containing node template
-    :vartype node_template: NodeTemplate
-    :ivar artifacts: instantiated artifacts
-    :vartype artifacts: [:class:`Artifact`]
+    Template for creating an :class:`Artifact` instance, which is a typed file, either provided in a
+    CSAR or downloaded from a repository.
     """
 
     __tablename__ = 'artifact_template'
@@ -1951,20 +2179,6 @@ class ArtifactTemplateBase(TemplateModelMixin):
     __private_fields__ = ('type_fk',
                           'node_template_fk')
 
-    # region foreign keys
-
-    @declared_attr
-    def type_fk(cls):
-        """For ArtifactTemplate many-to-one to Type"""
-        return relationship.foreign_key('type')
-
-    @declared_attr
-    def node_template_fk(cls):
-        """For NodeTemplate one-to-many to ArtifactTemplate"""
-        return relationship.foreign_key('node_template')
-
-    # endregion
-
     # region association proxies
 
     # endregion
@@ -1977,10 +2191,20 @@ class ArtifactTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def artifacts(cls):
+        """
+        Instantiated artifacts.
+
+        :type: [:class:`Artifact`]
+        """
         return relationship.one_to_many(cls, 'artifact')
 
     @declared_attr
     def properties(cls):
+        """
+        Declarations for associated immutable parameters.
+
+        :type: {:obj:`basestring`: :class:`Property`}
+        """
         return relationship.one_to_many(cls, 'property', dict_key='name')
 
     # endregion
@@ -1989,19 +2213,67 @@ class ArtifactTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def node_template(cls):
+        """
+        Containing node template.
+
+        :type: :class:`NodeTemplate`
+        """
         return relationship.many_to_one(cls, 'node_template')
 
     @declared_attr
     def type(cls):
+        """
+        Artifact type.
+
+        :type: :class:`Type`
+        """
         return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
 
     # endregion
 
-    description = Column(Text)
-    source_path = Column(Text)
-    target_path = Column(Text)
-    repository_url = Column(Text)
-    repository_credential = Column(modeling_types.StrictDict(basestring, basestring))
+    # region foreign keys
+
+    @declared_attr
+    def type_fk(cls):
+        """For ArtifactTemplate many-to-one to Type"""
+        return relationship.foreign_key('type')
+
+    @declared_attr
+    def node_template_fk(cls):
+        """For NodeTemplate one-to-many to ArtifactTemplate"""
+        return relationship.foreign_key('node_template')
+
+    # endregion
+
+    description = Column(Text, doc="""
+    Human-readable description.
+
+    :type: :obj:`basestring`
+    """)
+
+    source_path = Column(Text, doc="""
+    Source path (in CSAR or repository).
+
+    :type: :obj:`basestring`
+    """)
+
+    target_path = Column(Text, doc="""
+    Path at which to install at destination.
+
+    :type: :obj:`basestring`
+    """)
+
+    repository_url = Column(Text, doc="""
+    Repository URL.
+
+    :type: :obj:`basestring`
+    """)
+
+    repository_credential = Column(modeling_types.StrictDict(basestring, basestring), doc="""
+    Credentials for accessing the repository.
+
+    :type: {:obj:`basestring`, :obj:`basestring`}
+    """)
 
     @property
     def as_raw(self):
@@ -2055,16 +2327,9 @@ class ArtifactTemplateBase(TemplateModelMixin):
 
 class PluginSpecificationBase(TemplateModelMixin):
     """
-    Plugin specification.
-
-    :ivar name: required plugin name
-    :vartype name: basestring
-    :ivar version: minimum plugin version
-    :vartype version: basestring
-    :ivar enabled: whether the plugin is enabled
-    :vartype enabled: bool
-    :ivar plugin: the matching plugin (or ``None`` if not matched)
-    :vartype plugin: Plugin
+    Requirement for a :class:`Plugin`.
+
+    The actual plugin to be selected depends on those currently installed in ARIA.
     """
 
     __tablename__ = 'plugin_specification'
@@ -2072,35 +2337,54 @@ class PluginSpecificationBase(TemplateModelMixin):
     __private_fields__ = ('service_template_fk',
                           'plugin_fk')
 
-    version = Column(Text)
-    enabled = Column(Boolean, nullable=False, default=True)
-
-    # region foreign keys
+    version = Column(Text, doc="""
+    Minimum plugin version.
 
-    @declared_attr
-    def service_template_fk(cls):
-        """For ServiceTemplate one-to-many to PluginSpecification"""
-        return relationship.foreign_key('service_template', nullable=True)
+    :type: :obj:`basestring`
+    """)
 
-    @declared_attr
-    def plugin_fk(cls):
-        """For PluginSpecification many-to-one to Plugin"""
-        return relationship.foreign_key('plugin', nullable=True)
+    enabled = Column(Boolean, nullable=False, default=True, doc="""
+    Whether the plugin is enabled.
 
-    # endregion
+    :type: :obj:`bool`
+    """)
 
     # region many_to_one relationships
 
     @declared_attr
     def service_template(cls):
+        """
+        Containing service template.
+
+        :type: :class:`ServiceTemplate`
+        """
         return relationship.many_to_one(cls, 'service_template')
 
     @declared_attr
     def plugin(cls): # pylint: disable=method-hidden
+        """
+        Matched plugin.
+
+        :type: :class:`Plugin`
+        """
         return relationship.many_to_one(cls, 'plugin', back_populates=relationship.NO_BACK_POP)
 
     # endregion
 
+    # region foreign keys
+
+    @declared_attr
+    def service_template_fk(cls):
+        """For ServiceTemplate one-to-many to PluginSpecification"""
+        return relationship.foreign_key('service_template', nullable=True)
+
+    @declared_attr
+    def plugin_fk(cls):
+        """For PluginSpecification many-to-one to Plugin"""
+        return relationship.foreign_key('plugin', nullable=True)
+
+    # endregion
+
     @property
     def as_raw(self):
         return collections.OrderedDict((

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/4ebbbb15/aria/modeling/types.py
----------------------------------------------------------------------
diff --git a/aria/modeling/types.py b/aria/modeling/types.py
index 4c25f93..c34326e 100644
--- a/aria/modeling/types.py
+++ b/aria/modeling/types.py
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 """
-Allows JSON-serializable collections to be used as SQLAlchemy column types. 
+Allows JSON-serializable collections to be used as SQLAlchemy column types.
 """
 
 import json

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/4ebbbb15/aria/modeling/utils.py
----------------------------------------------------------------------
diff --git a/aria/modeling/utils.py b/aria/modeling/utils.py
index 9d02194..a60a7a5 100644
--- a/aria/modeling/utils.py
+++ b/aria/modeling/utils.py
@@ -34,9 +34,9 @@ class ModelJSONEncoder(JSONEncoder):
     JSON encoder that automatically unwraps ``value`` attributes.
     """
     def __init__(self, *args, **kwargs):
-        # Hack to make sure Sphinx doesn't grab the base constructor's docstring
-        super(self, JSONEncoder).__init__(*args, **kwargs)
-    
+        # Just here to make sure Sphinx doesn't grab the base constructor's docstring
+        super(ModelJSONEncoder, self).__init__(*args, **kwargs)
+
     def default(self, o):  # pylint: disable=method-hidden
         from .mixins import ModelMixin
         if isinstance(o, ModelMixin):

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/4ebbbb15/aria/parser/loading/context.py
----------------------------------------------------------------------
diff --git a/aria/parser/loading/context.py b/aria/parser/loading/context.py
index e4ada0e..1d1aaf6 100644
--- a/aria/parser/loading/context.py
+++ b/aria/parser/loading/context.py
@@ -23,7 +23,7 @@ class LoadingContext(object):
     Properties:
 
     :ivar loader_source: for finding loader instances
-    :vartype loader_source: LoaderSource 
+    :vartype loader_source: LoaderSource
     :ivar prefixes: additional prefixes for :class:`UriTextLoader`
     :vartype prefixes: [:obj:`basestring`]
     """

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/4ebbbb15/aria/parser/presentation/presentation.py
----------------------------------------------------------------------
diff --git a/aria/parser/presentation/presentation.py b/aria/parser/presentation/presentation.py
index b92506c..0fcb9e4 100644
--- a/aria/parser/presentation/presentation.py
+++ b/aria/parser/presentation/presentation.py
@@ -183,8 +183,8 @@ class Presentation(PresentationBase):
     ARIA presentation classes will often be decorated with ``@has_fields``, as that mechanism
     automates a lot of field-specific validation. However, that is not a requirement.
 
-    Make sure that your utility property and method names begin with a "\_", because those names
-    without a "\_" prefix are normally reserved for fields.
+    Make sure that your utility property and method names begin with a ``_``, because those names
+    without a ``_`` prefix are normally reserved for fields.
     """
 
     def _validate(self, context):

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/4ebbbb15/aria/utils/caching.py
----------------------------------------------------------------------
diff --git a/aria/utils/caching.py b/aria/utils/caching.py
index 5c82b0d..4c3d82b 100644
--- a/aria/utils/caching.py
+++ b/aria/utils/caching.py
@@ -43,7 +43,7 @@ class cachedmethod(object):  # pylint: disable=invalid-name
     ENABLED = True
 
     def __init__(self, func):
-        self.__doc__  = func.__doc__
+        self.__doc__ = func.__doc__
         self.func = func
         self.hits = 0
         self.misses = 0

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/4ebbbb15/aria/utils/collections.py
----------------------------------------------------------------------
diff --git a/aria/utils/collections.py b/aria/utils/collections.py
index 89bb390..d8b7e90 100644
--- a/aria/utils/collections.py
+++ b/aria/utils/collections.py
@@ -36,8 +36,7 @@ class FrozenList(list):
     """
     An immutable list.
 
-    After initialization it will raise :class:`TypeError` exceptions if modification
-    is attempted.
+    After initialization it will raise :class:`TypeError` exceptions if modification is attempted.
 
     Note that objects stored in the list may not be immutable.
     """
@@ -82,12 +81,12 @@ class FrozenList(list):
 
 EMPTY_READ_ONLY_LIST = FrozenList()
 
+
 class FrozenDict(OrderedDict):
     """
     An immutable ordered dict.
 
-    After initialization it will raise :class:`TypeError` exceptions if modification
-    is attempted.
+    After initialization it will raise :class:`TypeError` exceptions if modification is attempted.
 
     Note that objects stored in the dict may not be immutable.
     """
@@ -113,6 +112,7 @@ class FrozenDict(OrderedDict):
 
 EMPTY_READ_ONLY_DICT = FrozenDict()
 
+
 class StrictList(list):
     """
     A list that raises :class:`TypeError` exceptions when objects of the wrong type are inserted.
@@ -172,10 +172,11 @@ class StrictList(list):
         value = self._wrap(value)
         return super(StrictList, self).insert(index, value)
 
+
 class StrictDict(OrderedDict):
     """
-    An ordered dict that raises :class:`TypeError` exceptions
-    when keys or values of the wrong type are used.
+    An ordered dict that raises :class:`TypeError` exceptions when keys or values of the wrong type
+    are used.
     """
 
     def __init__(self,
@@ -215,6 +216,7 @@ class StrictDict(OrderedDict):
             value = self.wrapper_function(value)
         return super(StrictDict, self).__setitem__(key, value)
 
+
 def merge(dict_a, dict_b, path=None, strict=False):
     """
     Merges dicts, recursively.
@@ -238,9 +240,11 @@ def merge(dict_a, dict_b, path=None, strict=False):
             dict_a[key] = value_b
     return dict_a
 
+
 def is_removable(_container, _key, v):
     return (v is None) or ((isinstance(v, dict) or isinstance(v, list)) and (len(v) == 0))
 
+
 def prune(value, is_removable_function=is_removable):
     """
     Deletes ``None`` and empty lists and dicts, recursively.
@@ -263,6 +267,7 @@ def prune(value, is_removable_function=is_removable):
 
 
 # TODO: Move following two methods to some place parser specific
+
 def deepcopy_with_locators(value):
     """
     Like :func:`deepcopy`, but also copies over locators.

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/4ebbbb15/docs/aria.modeling.models.rst
----------------------------------------------------------------------
diff --git a/docs/aria.modeling.models.rst b/docs/aria.modeling.models.rst
index 13f9494..b1ddb29 100644
--- a/docs/aria.modeling.models.rst
+++ b/docs/aria.modeling.models.rst
@@ -19,3 +19,4 @@
 ---------------------------
 
 .. automodule:: aria.modeling.models
+   :no-show-inheritance:

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/4ebbbb15/docs/conf.py
----------------------------------------------------------------------
diff --git a/docs/conf.py b/docs/conf.py
index 4f57968..b1a17ea 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -374,35 +374,41 @@ autodoc_default_flags = [
     'show-inheritance'
 ]
 
-_skip_fields = (
+_SKIP_MEMBERS = (
     'FIELDS',
     'ALLOW_UNKNOWN_FIELDS',
     'SHORT_FORM_FIELD'
 )
 
-_no_skip_fields = (
+_SKIP_MEMBER_SUFFIXES = (
+    '_fk'
+)
+
+_NEVER_SKIP_MEMBERS = (
     '__evaluate__',
 )
 
 # Event handling
 def on_skip_members(app, what, name, obj, skip, options):
-    if (name in _skip_fields) or name.endswith('_fk'): 
-        skip = True
-    elif name in _no_skip_fields: 
-        skip = False
+    if name in _NEVER_SKIP_MEMBERS:
+        return False
+    if name in _SKIP_MEMBERS: 
+        return True
+    for suffix in _SKIP_MEMBER_SUFFIXES:
+        if name.endswith(suffix):
+            return True
     return skip
 
 from sphinx.domains.python import PythonDomain
 
-class PatchedPythonDomain(PythonDomain):
+class _PatchedPythonDomain(PythonDomain):
     # See: https://github.com/sphinx-doc/sphinx/issues/3866
     def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode):
         if 'refspecific' in node:
             del node['refspecific']
-        return super(PatchedPythonDomain, self).resolve_xref(
+        return super(_PatchedPythonDomain, self).resolve_xref(
             env, fromdocname, builder, typ, target, node, contnode)
 
 def setup(app):
     app.connect('autodoc-skip-member', on_skip_members)
-    app.override_domain(PatchedPythonDomain)
-    print PatchedPythonDomain.roles
+    app.override_domain(_PatchedPythonDomain)

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/4ebbbb15/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
index 5813ccf..957dc7b 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
@@ -484,7 +484,6 @@ def create_substitution_template_model(context, service_template, substitution_m
                 node_template_model.capability_templates[capability.capability]
             model.mappings[name] = \
                 SubstitutionTemplateMapping(name=name,
-                                            node_template=node_template_model,
                                             capability_template=capability_template_model)
 
     requirements = substitution_mappings.requirements
@@ -499,7 +498,6 @@ def create_substitution_template_model(context, service_template, substitution_m
                     break
             model.mappings[name] = \
                 SubstitutionTemplateMapping(name=name,
-                                            node_template=node_template_model,
                                             requirement_template=requirement_template_model)
 
     return model

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/4ebbbb15/tests/orchestrator/workflows/core/test_events.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/workflows/core/test_events.py b/tests/orchestrator/workflows/core/test_events.py
index 2b82443..6a4fdd0 100644
--- a/tests/orchestrator/workflows/core/test_events.py
+++ b/tests/orchestrator/workflows/core/test_events.py
@@ -129,8 +129,8 @@ def run_standard_lifecycle_operation_on_node(ctx, op_name):
 
 
 def _assert_node_state_changed_as_a_result_of_standard_lifecycle_operation(node, op_name):
-    assert global_test_dict['transitional_state'] == NodeBase._op_to_state[op_name]['transitional']
-    assert node.state == NodeBase._op_to_state[op_name]['finished']
+    assert global_test_dict['transitional_state'] == NodeBase._OP_TO_STATE[op_name]['transitional']
+    assert node.state == NodeBase._OP_TO_STATE[op_name]['finished']
 
 
 @workflow


Mime
View raw message