'Build a hierarchy of XBlocks.
Arguments:
course_hierarchy (BlockStructureDict): Definition of course
hierarchy.
where a BlockStructureDict is a list of dicts in the form {
\'key1\': \'value1\',
\'keyN\': \'valueN\',
\'#type\': block_type,
\'#ref\': short_string_for_referencing_block,
\'#children\': list[BlockStructureDict],
\'#parents\': list[\'#ref\' values]
Special keys start with \'#\'; the rest just get passed as
kwargs to Factory.create.
Note: the caller has a choice of whether to create
(1) a nested block structure with children blocks embedded
within their parents, or
(2) a flat block structure with children blocks defined
alongside their parents and attached via the #parents
field, or
(3) a combination of both #1 and #2 used for whichever
blocks.
Note 2: When the #parents field is used in addition to the
nested pattern for a block, it specifies additional parents
that aren\'t already implied by having the block exist within
another block\'s #children field.
Returns:
dict[str: XBlock]:
Mapping from \'#ref\' values to their XBlocks.'

def build_course(self, course_hierarchy):

    block_map = {}
    for block_hierarchy in course_hierarchy:
        self.build_xblock(block_hierarchy, block_map, parent=None)
    for block_hierarchy in course_hierarchy:
        self.add_parents(block_hierarchy, block_map)
    publish_course(block_map['course'])
    return block_map
