signature:
def remove_decorator ( source : str ) :
    """Remove decorators from function definition"""

implementation:
lines = source . splitlines ( )
atok = asttokens . ASTTokens ( source , parse = True )
for node in ast . walk ( atok . tree ) :
    if isinstance ( node , ast . FunctionDef ) :
        break
if node . decorator_list :
    deco_first = node . decorator_list [ 0 ]
    deco_last = node . decorator_list [ - 1 ]
    line_first = atok . tokens [ deco_first . first_token . index - 1 ] . start [ 0 ]
    line_last = atok . tokens [ deco_last . last_token . index + 1 ] . start [ 0 ]
    lines = lines [ : line_first - 1 ] + lines [ line_last : ]
return "\n" . join ( lines ) + "\n"


signature:
def replace_funcname ( source : str , name : str ) :
    """Replace function name"""

implementation:
lines = source . splitlines ( )
atok = asttokens . ASTTokens ( source , parse = True )
for node in ast . walk ( atok . tree ) :
    if isinstance ( node , ast . FunctionDef ) :
        break
i = node . first_token . index
for i in range ( node . first_token . index , node . last_token . index ) :
    if ( atok . tokens [ i ] . type == token . NAME and atok . tokens [ i ] . string == "def" ) :
        break
lineno , col_begin = atok . tokens [ i + 1 ] . start
lineno_end , col_end = atok . tokens [ i + 1 ] . end
assert lineno == lineno_end
lines [ lineno - 1 ] = ( lines [ lineno - 1 ] [ : col_begin ] + name + lines [ lineno - 1 ] [ col_end : ] )
return "\n" . join ( lines ) + "\n"


signature:
def has_lambda ( src ) :
    """True if only one lambda expression is included"""

implementation:
module_node = ast . parse ( dedent ( src ) )
lambdaexp = [ node for node in ast . walk ( module_node ) if isinstance ( node , ast . Lambda ) ]
return bool ( lambdaexp )


signature:
def _reload ( self , module = None ) :
    """Reload the source function from the source module .
 * * Internal use only * *
 Update the source function of the formula .
 This method is used to updated the underlying formula
 when the source code of the module in which the source function
 is read from is modified .
 If the formula was not created from a module , an error is raised .
 If ` ` module _ ` ` is not given , the source module of the formula is
 reloaded . If ` ` module _ ` ` is given and matches the source module ,
 then the module _ is used without being reloaded .
 If ` ` module _ ` ` is given and does not match the source module of
 the formula , an error is raised .
 Args :
 module _ : A ` ` ModuleSource ` ` object
 Returns :
 self"""

implementation:
if self . module is None :
    raise RuntimeError
elif module is None :
    import importlib
    module = ModuleSource ( importlib . reload ( module ) )
elif module . name != self . module :
    raise RuntimeError
if self . name in module . funcs :
    func = module . funcs [ self . name ]
    self . __init__ ( func = func )
else :
    self . __init__ ( func = NULL_FORMULA )
return self


signature:
def get_description ( ) :
    """Get long description from README ."""

implementation:
with open ( path . join ( here , 'README.rst' ) , 'r' ) as f :
    data = f . read ( )
return data


signature:
def to_frame ( self , * args ) :
    """Convert the cells in the view into a DataFrame object .
 If ` ` args ` ` is not given , this method returns a DataFrame that
 has an Index or a MultiIndex depending of the number of
 cells parameters and columns each of which corresponds to each
 cells included in the view .
 ` ` args ` ` can be given to calculate cells values and limit the
 DataFrame indexes to the given arguments .
 The cells in this view may have different number of parameters ,
 but parameters shared among multiple cells
 must appear in the same position in all the parameter lists .
 For example ,
 Having ` ` foo ( ) ` ` , ` ` bar ( x ) ` ` and ` ` baz ( x , y = 1 ) ` ` is okay
 because the shared parameter ` ` x ` ` is always the first parameter ,
 but this method does not work if the view has ` ` quz ( x , z = 2 , y = 1 ) ` `
 cells in addition to the first three cells , because ` ` y ` ` appears
 in different positions .
 Args :
 args ( optional ) : multiple arguments ,
 or an iterator of arguments to the cells ."""

implementation:
if sys . version_info < ( 3 , 6 , 0 ) :
    from collections import OrderedDict
    impls = OrderedDict ( )
    for name , obj in self . items ( ) :
        impls [ name ] = obj . _impl
else :
    impls = get_impls ( self )
return _to_frame_inner ( impls , args )


signature:
def _baseattrs ( self ) :
    """A dict of members expressed in literals"""

implementation:
result = super ( ) . _baseattrs
result [ "static_spaces" ] = self . static_spaces . _baseattrs
result [ "dynamic_spaces" ] = self . dynamic_spaces . _baseattrs
result [ "cells" ] = self . cells . _baseattrs
result [ "refs" ] = self . refs . _baseattrs
if self . has_params ( ) :
    result [ "params" ] = ", " . join ( self . parameters )
else :
    result [ "params" ] = ""
return result


signature:
def new_cells ( self , name = None , formula = None ) :
    """Create a cells in the space .
 Args :
 name : If omitted , the model is named automatically ` ` CellsN ` ` ,
 where ` ` N ` ` is an available number .
 func : The function to define the formula of the cells .
 Returns :
 The new cells ."""

implementation:
# Outside formulas only
return self . _impl . new_cells ( name , formula ) . interface


signature:
def import_funcs ( self , module ) :
    """Create a cells from a module ."""

implementation:
# Outside formulas only
newcells = self . _impl . new_cells_from_module ( module )
return get_interfaces ( newcells )


signature:
def new_cells_from_excel ( self , book , range_ , sheet = None , names_row = None , param_cols = None , param_order = None , transpose = False , names_col = None , param_rows = None , ) :
    """Create multiple cells from an Excel range .
 This method reads values from a range in an Excel file ,
 create cells and populate them with the values in the range .
 To use this method , ` ` openpyxl ` ` package must be installed .
 The Excel file to read data from is specified by ` ` book ` `
 parameters . The ` ` range _ ` ` can be a range address , such as " $ G4 : $ K10 " ,
 or a named range . In case a range address is given ,
 ` ` sheet ` ` must also be given .
 By default , cells data are interpreted as being laid out side - by - side .
 ` ` names _ row ` ` is a row index ( starting from 0 ) to specify the
 row that contains the names of cells and parameters .
 Cells and parameter names must be contained in a single row .
 ` ` param _ cols ` ` accepts a sequence ( such as list or tuple ) of
 column indexes ( starting from 0 ) that indicate columns that
 contain cells arguments .
 * * 2 - dimensional cells definitions * *
 The optional ` ` names _ col ` ` and ` ` param _ rows ` ` parameters are used ,
 when data for one cells spans more than one column .
 In such cases , the cells data is 2 - dimensional , and
 there must be parameter row ( s ) across the columns
 that contain arguments of the parameters .
 A sequence of row indexes that indicate parameter rows
 is passed to ` ` param _ rows ` ` .
 The names of those parameters must be contained in the
 same rows as parameter values ( arguments ) , and
 ` ` names _ col ` ` is to indicate the column position at which
 the parameter names are defined .
 * * Horizontal arrangement * *
 By default , cells data are interpreted as being placed
 side - by - side , regardless of whether one cells corresponds
 to a single column or multiple columns .
 ` ` transpose ` ` parameter is used to alter this orientation ,
 and if it is set to ` ` True ` ` , cells values are
 interpreted as being placed one above the other .
 " row ( s ) " and " col ( s ) " in the parameter
 names are interpreted inversely , i . e .
 all indexes passed to " row ( s ) " parameters are interpreted
 as column indexes ,
 and all indexes passed to " col ( s ) " parameters as row indexes .
 Args :
 book ( str ) : Path to an Excel file .
 range _ ( str ) : Range expression , such as " A1 " , " $ G4 : $ K10 " ,
 or named range " NamedRange1 " .
 sheet ( str ) : Sheet name ( case ignored ) .
 names _ row ( optional ) : an index number indicating
 what row contains the names of cells and parameters .
 Defaults to the top row ( 0 ) .
 param _ cols ( optional ) : a sequence of index numbers
 indicating parameter columns .
 Defaults to only the leftmost column ( [ 0 ] ) .
 names _ col ( optional ) : an index number , starting from 0,
 indicating what column contains additional parameters .
 param _ rows ( optional ) : a sequence of index numbers , starting from
 0 , indicating rows of additional parameters , in case cells are
 defined in two dimensions .
 transpose ( optional ) : Defaults to ` ` False ` ` .
 If set to ` ` True ` ` , " row ( s ) " and " col ( s ) " in the parameter
 names are interpreted inversely , i . e .
 all indexes passed to " row ( s ) " parameters are interpreted
 as column indexes ,
 and all indexes passed to " col ( s ) " parameters as row indexes .
 param _ order ( optional ) : a sequence to reorder the parameters .
 The elements of the sequence are the indexes of ` ` param _ cols ` `
 elements , and optionally the index of ` ` param _ rows ` ` elements
 shifted by the length of ` ` param _ cols ` ` ."""

implementation: return self . _impl . new_cells_from_excel ( book , range_ , sheet , names_row , param_cols , param_order , transpose , names_col , param_rows , )


signature:
def get_object ( self , name ) :
    """Retrieve an object by a dotted name relative to the space ."""

implementation:
parts = name . split ( "." )
child = parts . pop ( 0 )
if parts :
    return self . spaces [ child ] . get_object ( "." . join ( parts ) )
else :
    return self . _namespace_impl [ child ]


signature:
def _get_dynamic_base ( self , bases_ ) :
    """Create or get the base space from a list of spaces
 if a direct base space in ` bases ` is dynamic , replace it with
 its base ."""

implementation:
bases = tuple ( base . bases [ 0 ] if base . is_dynamic ( ) else base for base in bases_ )
if len ( bases ) == 1 :
    return bases [ 0 ]
elif len ( bases ) > 1 :
    return self . model . get_dynamic_base ( bases )
else :
    RuntimeError ( "must not happen" )


signature:
def _new_dynspace ( self , name = None , bases = None , formula = None , refs = None , arguments = None , source = None , ) :
    """Create a new dynamic root space ."""

implementation:
if name is None :
    name = self . spacenamer . get_next ( self . namespace )
if name in self . namespace :
    raise ValueError ( "Name '%s' already exists." % name )
if not is_valid_name ( name ) :
    raise ValueError ( "Invalid name '%s'." % name )
space = RootDynamicSpaceImpl ( parent = self , name = name , formula = formula , refs = refs , source = source , arguments = arguments , )
space . is_derived = False
self . _set_space ( space )
if bases : # i . e . not [ ]
    dynbase = self . _get_dynamic_base ( bases )
    space . _dynbase = dynbase
    dynbase . _dynamic_subs . append ( space )
return space


signature:
def get_dynspace ( self , args , kwargs = None ) :
    """Create a dynamic root space
 Called from interface methods"""

implementation:
node = get_node ( self , * convert_args ( args , kwargs ) )
key = node [ KEY ]
if key in self . param_spaces :
    return self . param_spaces [ key ]
else :
    last_self = self . system . self
    self . system . self = self
    try :
        space_args = self . eval_formula ( node )
    finally :
        self . system . self = last_self
    if space_args is None :
        space_args = { "bases" : [ self ] }
        # Default
    else :
        if "bases" in space_args :
            bases = get_impls ( space_args [ "bases" ] )
            if isinstance ( bases , StaticSpaceImpl ) :
                space_args [ "bases" ] = [ bases ]
            elif bases is None :
                space_args [ "bases" ] = [ self ]
                # Default
            else :
                space_args [ "bases" ] = bases
        else :
            space_args [ "bases" ] = [ self ]
    space_args [ "arguments" ] = node_get_args ( node )
    space = self . _new_dynspace ( ** space_args )
    self . param_spaces [ key ] = space
    space . inherit ( clear_value = False )
    return space


signature:
def restore_state ( self , system ) :
    """Called after unpickling to restore some attributes manually ."""

implementation:
super ( ) . restore_state ( system )
BaseSpaceContainerImpl . restore_state ( self , system )
for cells in self . _cells . values ( ) :
    cells . restore_state ( system )


signature:
def new_cells_from_excel ( self , book , range_ , sheet = None , names_row = None , param_cols = None , param_order = None , transpose = False , names_col = None , param_rows = None , ) :
    """Create multiple cells from an Excel range .
 Args :
 book ( str ) : Path to an Excel file .
 range _ ( str ) : Range expression , such as " A1 " , " $ G4 : $ K10 " ,
 or named range " NamedRange1 " .
 sheet ( str ) : Sheet name ( case ignored ) .
 names _ row : Cells names in a sequence , or an integer number , or
 a string expression indicating row ( or column depending on
 ` ` ` orientation ` ` ` ) to read cells names from .
 param _ cols : a sequence of them
 indicating parameter columns ( or rows depending on ` ` `
 orientation ` ` ` )
 param _ order : a sequence of integers representing
 the order of params and extra _ params .
 transpose : in which direction ' vertical ' or ' horizontal '
 names _ col : a string or a list of names of the extra params .
 param _ rows : integer or string expression , or a sequence of them
 indicating row ( or column ) to be interpreted as parameters ."""

implementation:
import modelx . io . excel as xl
cellstable = xl . CellsTable ( book , range_ , sheet , names_row , param_cols , param_order , transpose , names_col , param_rows , )
if cellstable . param_names :
    sig = "=None, " . join ( cellstable . param_names ) + "=None"
else :
    sig = ""
blank_func = "def _blank_func(" + sig + "): pass"
for cellsdata in cellstable . items ( ) :
    cells = self . new_cells ( name = cellsdata . name , formula = blank_func )
    for args , value in cellsdata . items ( ) :
        cells . set_value ( args , value )


signature:
def set_attr ( self , name , value ) :
    """Implementation of attribute setting
 ` ` space . name = value ` ` by user script
 Called from ` ` Space . _ _ setattr _ _ ` `"""

implementation:
if not is_valid_name ( name ) :
    raise ValueError ( "Invalid name '%s'" % name )
if name in self . namespace :
    if name in self . refs :
        if name in self . self_refs :
            self . new_ref ( name , value )
        else :
            raise KeyError ( "Ref '%s' cannot be changed" % name )
    elif name in self . cells :
        if self . cells [ name ] . is_scalar ( ) :
            self . cells [ name ] . set_value ( ( ) , value )
        else :
            raise AttributeError ( "Cells '%s' is not a scalar." % name )
    else :
        raise ValueError
else :
    self . new_ref ( name , value )


signature:
def del_attr ( self , name ) :
    """Implementation of attribute deletion
 ` ` del space . name ` ` by user script
 Called from ` ` StaticSpace . _ _ delattr _ _ ` `"""

implementation:
if name in self . namespace :
    if name in self . cells :
        self . del_cells ( name )
    elif name in self . spaces :
        self . del_space ( name )
    elif name in self . refs :
        self . del_ref ( name )
    else :
        raise RuntimeError ( "Must not happen" )
else :
    raise KeyError ( "'%s' not found in Space '%s'" % ( name , self . name ) )


signature:
def del_space ( self , name ) :
    """Delete a space ."""

implementation:
if name not in self . spaces :
    raise ValueError ( "Space '%s' does not exist" % name )
if name in self . static_spaces :
    space = self . static_spaces [ name ]
    if space . is_derived :
        raise ValueError ( "%s has derived spaces" % repr ( space . interface ) )
    else :
        self . static_spaces . del_item ( name )
        self . model . spacegraph . remove_node ( space )
        self . inherit ( )
        self . model . spacegraph . update_subspaces ( self )
        # TODO : Destroy space
elif name in self . dynamic_spaces : # TODO : Destroy space
    self . dynamic_spaces . del_item ( name )
else :
    raise ValueError ( "Derived cells cannot be deleted" )


signature:
def del_cells ( self , name ) :
    """Implementation of cells deletion
 ` ` del space . name ` ` where name is a cells , or
 ` ` del space . cells [ ' name ' ] ` `"""

implementation:
if name in self . cells :
    cells = self . cells [ name ]
    self . cells . del_item ( name )
    self . inherit ( )
    self . model . spacegraph . update_subspaces ( self )
elif name in self . dynamic_spaces :
    cells = self . dynamic_spaces . pop ( name )
    self . dynamic_spaces . set_update ( )
else :
    raise KeyError ( "Cells '%s' does not exist" % name )
NullImpl ( cells )


signature:
def evalrepr ( self ) :
    """Evaluable repr"""

implementation:
args = [ repr ( arg ) for arg in get_interfaces ( self . argvalues ) ]
param = ", " . join ( args )
return "%s(%s)" % ( self . parent . evalrepr , param )


signature:
def cellsiter_to_dataframe ( cellsiter , args , drop_allna = True ) :
    """Convert multiple cells to a frame .
 If args is an empty sequence , all values are included .
 If args is specified , cellsiter must have shareable parameters .
 Args :
 cellsiter : A mapping from cells names to CellsImpl objects .
 args : A sequence of arguments"""

implementation:
from modelx . core . cells import shareable_parameters
if len ( args ) :
    indexes = shareable_parameters ( cellsiter )
else :
    indexes = get_all_params ( cellsiter . values ( ) )
result = None
for cells in cellsiter . values ( ) :
    df = cells_to_dataframe ( cells , args )
    if drop_allna and df . isnull ( ) . all ( ) . all ( ) :
        continue
    # Ignore all NA or empty
    if df . index . names != [ None ] :
        if isinstance ( df . index , pd . MultiIndex ) :
            if _pd_ver < ( 0 , 20 ) :
                df = _reset_naindex ( df )
        df = df . reset_index ( )
    missing_params = set ( indexes ) - set ( df )
    for params in missing_params :
        df [ params ] = np . nan
    if result is None :
        result = df
    else :
        try :
            result = pd . merge ( result , df , how = "outer" )
        except MergeError : # When no common column exists , i . e . all cells are scalars .
            result = pd . concat ( [ result , df ] , axis = 1 )
        except ValueError : # When common columns are not coercible ( numeric vs object ) ,
        # Make the numeric column object type
            cols = set ( result . columns ) & set ( df . columns )
            for col in cols : # When only either of them has object dtype
                if ( len ( [ str ( frame [ col ] . dtype ) for frame in ( result , df ) if str ( frame [ col ] . dtype ) == "object" ] ) == 1 ) :
                    if str ( result [ col ] . dtype ) == "object" :
                        frame = df
                    else :
                        frame = result
                    frame [ [ col ] ] = frame [ col ] . astype ( "object" )
            # Try again
            result = pd . merge ( result , df , how = "outer" )
if result is None :
    return pd . DataFrame ( )
else :
    return result . set_index ( indexes ) if indexes else result


signature:
def cells_to_series ( cells , args ) :
    """Convert a CellImpl into a Series .
 ` args ` must be a sequence of argkeys .
 ` args ` can be longer or shorter then the number of cell ' s parameters .
 If shorter , then defaults are filled if any , else raise error .
 If longer , then redundant args are ignored ."""

implementation:
paramlen = len ( cells . formula . parameters )
is_multidx = paramlen > 1
if len ( cells . data ) == 0 :
    data = { }
    indexes = None
elif paramlen == 0 : # Const Cells
    data = list ( cells . data . values ( ) )
    indexes = [ np . nan ]
else :
    if len ( args ) > 0 :
        defaults = tuple ( param . default for param in cells . formula . signature . parameters . values ( ) )
        updated_args = [ ]
        for arg in args :
            if len ( arg ) > paramlen :
                arg = arg [ : paramlen ]
            elif len ( arg ) < paramlen :
                arg += defaults [ len ( arg ) : ]
            updated_args . append ( arg )
        items = [ ( arg , cells . data [ arg ] ) for arg in updated_args if arg in cells . data ]
    else :
        items = [ ( key , value ) for key , value in cells . data . items ( ) ]
    if not is_multidx : # Peel 1 - element tuple
        items = [ ( key [ 0 ] , value ) for key , value in items ]
    if len ( items ) == 0 :
        indexes , data = None , { }
    else :
        indexes , data = zip ( * items )
        if is_multidx :
            indexes = pd . MultiIndex . from_tuples ( indexes )
result = pd . Series ( data = data , name = cells . name , index = indexes )
if indexes is not None and any ( i is not np . nan for i in indexes ) :
    result . index . names = list ( cells . formula . parameters )
return result


signature:
def clear_descendants ( self , source , clear_source = True ) :
    """Remove all descendants of ( reachable from ) ` source ` .
 Args :
 source : Node descendants
 clear _ source ( bool ) : Remove origin too if True .
 Returns :
 set : The removed nodes ."""

implementation:
desc = nx . descendants ( self , source )
if clear_source :
    desc . add ( source )
self . remove_nodes_from ( desc )
return desc


signature:
def clear_obj ( self , obj ) :
    """" Remove all nodes with ` obj ` and their descendants ."""

implementation:
obj_nodes = self . get_nodes_with ( obj )
removed = set ( )
for node in obj_nodes :
    if self . has_node ( node ) :
        removed . update ( self . clear_descendants ( node ) )
return removed


signature:
def get_nodes_with ( self , obj ) :
    """Return nodes with ` obj ` ."""

implementation:
result = set ( )
if nx . __version__ [ 0 ] == "1" :
    nodes = self . nodes_iter ( )
else :
    nodes = self . nodes
for node in nodes :
    if node [ OBJ ] == obj :
        result . add ( node )
return result


signature:
def add_path ( self , nodes , ** attr ) :
    """In replacement for Deprecated add _ path method"""

implementation:
if nx . __version__ [ 0 ] == "1" :
    return super ( ) . add_path ( nodes , ** attr )
else :
    return nx . add_path ( self , nodes , ** attr )


signature:
def rename ( self , name ) :
    """Rename the model itself"""

implementation: self . _impl . system . rename_model ( new_name = name , old_name = self . name )


signature:
def rename ( self , name ) :
    """Rename self . Must be called only by its system ."""

implementation:
if is_valid_name ( name ) :
    if name not in self . system . models :
        self . name = name
        return True
        # Rename success
    else : # Model name already exists
        return False
else :
    raise ValueError ( "Invalid name '%s'." % name )


signature:
def clear_descendants ( self , source , clear_source = True ) :
    """Clear values and nodes calculated from ` source ` ."""

implementation:
removed = self . cellgraph . clear_descendants ( source , clear_source )
for node in removed :
    del node [ OBJ ] . data [ node [ KEY ] ]


signature:
def clear_obj ( self , obj ) :
    """Clear values and nodes of ` obj ` and their dependants ."""

implementation:
removed = self . cellgraph . clear_obj ( obj )
for node in removed :
    del node [ OBJ ] . data [ node [ KEY ] ]


signature:
def get_object ( self , name ) :
    """Retrieve an object by a dotted name relative to the model ."""

implementation:
parts = name . split ( "." )
space = self . spaces [ parts . pop ( 0 ) ]
if parts :
    return space . get_object ( "." . join ( parts ) )
else :
    return space


signature:
def restore_state ( self , system ) :
    """Called after unpickling to restore some attributes manually ."""

implementation:
Impl . restore_state ( self , system )
BaseSpaceContainerImpl . restore_state ( self , system )
mapping = { }
for node in self . cellgraph :
    if isinstance ( node , tuple ) :
        name , key = node
    else :
        name , key = node , None
    cells = self . get_object ( name )
    mapping [ node ] = get_node ( cells , key , None )
self . cellgraph = nx . relabel_nodes ( self . cellgraph , mapping )


signature:
def get_dynamic_base ( self , bases : tuple ) :
    """Create of get a base space for a tuple of bases"""

implementation:
try :
    return self . _dynamic_bases_inverse [ bases ]
except KeyError :
    name = self . _dynamic_base_namer . get_next ( self . _dynamic_bases )
    base = self . _new_space ( name = name )
    self . spacegraph . add_space ( base )
    self . _dynamic_bases [ name ] = base
    self . _dynamic_bases_inverse [ bases ] = base
    base . add_bases ( bases )
    return base


signature:
def check_mro ( self , bases ) :
    """Check if C3 MRO is possible with given bases"""

implementation:
try :
    self . add_node ( "temp" )
    for base in bases :
        nx . DiGraph . add_edge ( self , base , "temp" )
    result = self . get_mro ( "temp" ) [ 1 : ]
finally :
    self . remove_node ( "temp" )
return result


signature:
def get_command_names ( ) :
    """Returns a list of command names supported"""

implementation:
ret = [ ]
for f in os . listdir ( COMMAND_MODULE_PATH ) :
    if os . path . isfile ( os . path . join ( COMMAND_MODULE_PATH , f ) ) and f . endswith ( COMMAND_MODULE_SUFFIX ) :
        ret . append ( f [ : - len ( COMMAND_MODULE_SUFFIX ) ] )
return ret


signature:
def get ( vals , key , default_val = None ) :
    """Returns a dictionary value"""

implementation:
val = vals
for part in key . split ( '.' ) :
    if isinstance ( val , dict ) :
        val = val . get ( part , None )
        if val is None :
            return default_val
    else :
        return default_val
return val


signature:
def parse_option_settings ( option_settings ) :
    """Parses option _ settings as they are defined in the configuration file"""

implementation:
ret = [ ]
for namespace , params in list ( option_settings . items ( ) ) :
    for key , value in list ( params . items ( ) ) :
        ret . append ( ( namespace , key , value ) )
return ret


signature:
def parse_env_config ( config , env_name ) :
    """Parses an environment config"""

implementation:
all_env = get ( config , 'app.all_environments' , { } )
env = get ( config , 'app.environments.' + str ( env_name ) , { } )
return merge_dict ( all_env , env )


signature:
def create_archive ( directory , filename , config = { } , ignore_predicate = None , ignored_files = [ '.git' , '.svn' ] ) :
    """Creates an archive from a directory and returns
 the file that was created ."""

implementation:
with zipfile . ZipFile ( filename , 'w' , compression = zipfile . ZIP_DEFLATED ) as zip_file :
    root_len = len ( os . path . abspath ( directory ) )
    # create it
    out ( "Creating archive: " + str ( filename ) )
    for root , dirs , files in os . walk ( directory , followlinks = True ) :
        archive_root = os . path . abspath ( root ) [ root_len + 1 : ]
        for f in files :
            fullpath = os . path . join ( root , f )
            archive_name = os . path . join ( archive_root , f )
            # ignore the file we ' re creating
            if filename in fullpath :
                continue
            # ignored files
            if ignored_files is not None :
                for name in ignored_files :
                    if fullpath . endswith ( name ) :
                        out ( "Skipping: " + str ( name ) )
                        continue
            # do predicate
            if ignore_predicate is not None :
                if not ignore_predicate ( archive_name ) :
                    out ( "Skipping: " + str ( archive_name ) )
                    continue
            out ( "Adding: " + str ( archive_name ) )
            zip_file . write ( fullpath , archive_name , zipfile . ZIP_DEFLATED )
return filename


signature:
def add_config_files_to_archive ( directory , filename , config = { } ) :
    """Adds configuration files to an existing archive"""

implementation:
with zipfile . ZipFile ( filename , 'a' ) as zip_file :
    for conf in config :
        for conf , tree in list ( conf . items ( ) ) :
            if 'yaml' in tree :
                content = yaml . dump ( tree [ 'yaml' ] , default_flow_style = False )
            else :
                content = tree . get ( 'content' , '' )
            out ( "Adding file " + str ( conf ) + " to archive " + str ( filename ) )
            file_entry = zipfile . ZipInfo ( conf )
            file_entry . external_attr = tree . get ( 'permissions' , 0o644 ) << 16
            zip_file . writestr ( file_entry , content )
return filename


signature:
def swap_environment_cnames ( self , from_env_name , to_env_name ) :
    """Swaps cnames for an environment"""

implementation: self . ebs . swap_environment_cnames ( source_environment_name = from_env_name , destination_environment_name = to_env_name )


signature:
def upload_archive ( self , filename , key , auto_create_bucket = True ) :
    """Uploads an application archive version to s3"""

implementation:
try :
    bucket = self . s3 . get_bucket ( self . aws . bucket )
    if ( ( self . aws . region != 'us-east-1' and self . aws . region != 'eu-west-1' ) and bucket . get_location ( ) != self . aws . region ) or ( self . aws . region == 'us-east-1' and bucket . get_location ( ) != '' ) or ( self . aws . region == 'eu-west-1' and bucket . get_location ( ) != 'eu-west-1' ) :
        raise Exception ( "Existing bucket doesn't match region" )
except S3ResponseError :
    bucket = self . s3 . create_bucket ( self . aws . bucket , location = self . aws . region )
def __report_upload_progress ( sent , total ) :
    if not sent :
        sent = 0
    if not total :
        total = 0
    out ( "Uploaded " + str ( sent ) + " bytes of " + str ( total ) + " (" + str ( int ( float ( max ( 1 , sent ) ) / float ( total ) * 100 ) ) + "%)" )
# upload the new version
k = Key ( bucket )
k . key = self . aws . bucket_path + key
k . set_metadata ( 'time' , str ( time ( ) ) )
k . set_contents_from_filename ( filename , cb = __report_upload_progress , num_cb = 10 )


signature:
def create_application ( self , description = None ) :
    """Creats an application and sets the helpers current
 app _ name to the created application"""

implementation:
out ( "Creating application " + str ( self . app_name ) )
self . ebs . create_application ( self . app_name , description = description )


signature:
def delete_application ( self ) :
    """Creats an application and sets the helpers current
 app _ name to the created application"""

implementation:
out ( "Deleting application " + str ( self . app_name ) )
self . ebs . delete_application ( self . app_name , terminate_env_by_force = True )


signature:
def application_exists ( self ) :
    """Returns whether or not the given app _ name exists"""

implementation:
response = self . ebs . describe_applications ( application_names = [ self . app_name ] )
return len ( response [ 'DescribeApplicationsResponse' ] [ 'DescribeApplicationsResult' ] [ 'Applications' ] ) > 0


signature:
def create_environment ( self , env_name , version_label = None , solution_stack_name = None , cname_prefix = None , description = None , option_settings = None , tier_name = 'WebServer' , tier_type = 'Standard' , tier_version = '1.1' ) :
    """Creates a new environment"""

implementation:
out ( "Creating environment: " + str ( env_name ) + ", tier_name:" + str ( tier_name ) + ", tier_type:" + str ( tier_type ) )
self . ebs . create_environment ( self . app_name , env_name , version_label = version_label , solution_stack_name = solution_stack_name , cname_prefix = cname_prefix , description = description , option_settings = option_settings , tier_type = tier_type , tier_name = tier_name , tier_version = tier_version )


signature:
def environment_exists ( self , env_name ) :
    """Returns whether or not the given environment exists"""

implementation:
response = self . ebs . describe_environments ( application_name = self . app_name , environment_names = [ env_name ] , include_deleted = False )
return len ( response [ 'DescribeEnvironmentsResponse' ] [ 'DescribeEnvironmentsResult' ] [ 'Environments' ] ) > 0 and response [ 'DescribeEnvironmentsResponse' ] [ 'DescribeEnvironmentsResult' ] [ 'Environments' ] [ 0 ] [ 'Status' ] != 'Terminated'


signature:
def rebuild_environment ( self , env_name ) :
    """Rebuilds an environment"""

implementation:
out ( "Rebuilding " + str ( env_name ) )
self . ebs . rebuild_environment ( environment_name = env_name )


signature:
def get_environments ( self ) :
    """Returns the environments"""

implementation:
response = self . ebs . describe_environments ( application_name = self . app_name , include_deleted = False )
return response [ 'DescribeEnvironmentsResponse' ] [ 'DescribeEnvironmentsResult' ] [ 'Environments' ]


signature:
def delete_environment ( self , environment_name ) :
    """Deletes an environment"""

implementation: self . ebs . terminate_environment ( environment_name = environment_name , terminate_resources = True )


signature:
def update_environment ( self , environment_name , description = None , option_settings = [ ] , tier_type = None , tier_name = None , tier_version = '1.0' ) :
    """Updates an application version"""

implementation:
out ( "Updating environment: " + str ( environment_name ) )
messages = self . ebs . validate_configuration_settings ( self . app_name , option_settings , environment_name = environment_name )
messages = messages [ 'ValidateConfigurationSettingsResponse' ] [ 'ValidateConfigurationSettingsResult' ] [ 'Messages' ]
ok = True
for message in messages :
    if message [ 'Severity' ] == 'error' :
        ok = False
    out ( "[" + message [ 'Severity' ] + "] " + str ( environment_name ) + " - '" + message [ 'Namespace' ] + ":" + message [ 'OptionName' ] + "': " + message [ 'Message' ] )
self . ebs . update_environment ( environment_name = environment_name , description = description , option_settings = option_settings , tier_type = tier_type , tier_name = tier_name , tier_version = tier_version )


signature:
def environment_name_for_cname ( self , env_cname ) :
    """Returns an environment name for the given cname"""

implementation:
envs = self . get_environments ( )
for env in envs :
    if env [ 'Status' ] != 'Terminated' and 'CNAME' in env and env [ 'CNAME' ] and env [ 'CNAME' ] . lower ( ) . startswith ( env_cname . lower ( ) + '.' ) :
        return env [ 'EnvironmentName' ]
return None


signature:
def deploy_version ( self , environment_name , version_label ) :
    """Deploys a version to an environment"""

implementation:
out ( "Deploying " + str ( version_label ) + " to " + str ( environment_name ) )
self . ebs . update_environment ( environment_name = environment_name , version_label = version_label )


signature:
def get_versions ( self ) :
    """Returns the versions available"""

implementation:
response = self . ebs . describe_application_versions ( application_name = self . app_name )
return response [ 'DescribeApplicationVersionsResponse' ] [ 'DescribeApplicationVersionsResult' ] [ 'ApplicationVersions' ]


signature:
def create_application_version ( self , version_label , key ) :
    """Creates an application version"""

implementation:
out ( "Creating application version " + str ( version_label ) + " for " + str ( key ) )
self . ebs . create_application_version ( self . app_name , version_label , s3_bucket = self . aws . bucket , s3_key = self . aws . bucket_path + key )


signature:
def delete_unused_versions ( self , versions_to_keep = 10 ) :
    """Deletes unused versions"""

implementation:
# get versions in use
environments = self . ebs . describe_environments ( application_name = self . app_name , include_deleted = False )
environments = environments [ 'DescribeEnvironmentsResponse' ] [ 'DescribeEnvironmentsResult' ] [ 'Environments' ]
versions_in_use = [ ]
for env in environments :
    versions_in_use . append ( env [ 'VersionLabel' ] )
# get all versions
versions = self . ebs . describe_application_versions ( application_name = self . app_name )
versions = versions [ 'DescribeApplicationVersionsResponse' ] [ 'DescribeApplicationVersionsResult' ] [ 'ApplicationVersions' ]
versions = sorted ( versions , reverse = True , key = functools . cmp_to_key ( lambda x , y : ( x [ 'DateCreated' ] > y [ 'DateCreated' ] ) - ( x [ 'DateCreated' ] < y [ 'DateCreated' ] ) ) )
# delete versions in use
for version in versions [ versions_to_keep : ] :
    if version [ 'VersionLabel' ] in versions_in_use :
        out ( "Not deleting " + version [ "VersionLabel" ] + " because it is in use" )
    else :
        out ( "Deleting unused version: " + version [ "VersionLabel" ] )
        self . ebs . delete_application_version ( application_name = self . app_name , version_label = version [ 'VersionLabel' ] )
        sleep ( 2 )


signature:
def describe_events ( self , environment_name , next_token = None , start_time = None ) :
    """Describes events from the given environment"""

implementation:
events = self . ebs . describe_events ( application_name = self . app_name , environment_name = environment_name , next_token = next_token , start_time = start_time + 'Z' )
return ( events [ 'DescribeEventsResponse' ] [ 'DescribeEventsResult' ] [ 'Events' ] , events [ 'DescribeEventsResponse' ] [ 'DescribeEventsResult' ] [ 'NextToken' ] )


signature:
def wait_for_environments ( self , environment_names , health = None , status = None , version_label = None , include_deleted = True , use_events = True ) :
    """Waits for an environment to have the given version _ label
 and to be in the green state"""

implementation:
# turn into a list
if not isinstance ( environment_names , ( list , tuple ) ) :
    environment_names = [ environment_names ]
environment_names = environment_names [ : ]
# print some stuff
s = "Waiting for environment(s) " + ( ", " . join ( environment_names ) ) + " to"
if health is not None :
    s += " have health " + health
else :
    s += " have any health"
if version_label is not None :
    s += " and have version " + version_label
if status is not None :
    s += " and have status " + status
out ( s )
started = time ( )
seen_events = list ( )
for env_name in environment_names :
    ( events , next_token ) = self . describe_events ( env_name , start_time = datetime . now ( ) . isoformat ( ) )
    for event in events :
        seen_events . append ( event )
while True : # bail if they ' re all good
    if len ( environment_names ) == 0 :
        break
    # wait
    sleep ( 10 )
    # # get the env
    environments = self . ebs . describe_environments ( application_name = self . app_name , environment_names = environment_names , include_deleted = include_deleted )
    environments = environments [ 'DescribeEnvironmentsResponse' ] [ 'DescribeEnvironmentsResult' ] [ 'Environments' ]
    if len ( environments ) <= 0 :
        raise Exception ( "Couldn't find any environments" )
    # loop through and wait
    for env in environments [ : ] :
        env_name = env [ 'EnvironmentName' ]
        # the message
        msg = "Environment " + env_name + " is " + str ( env [ 'Health' ] )
        if version_label is not None :
            msg = msg + " and has version " + str ( env [ 'VersionLabel' ] )
        if status is not None :
            msg = msg + " and has status " + str ( env [ 'Status' ] )
        # what we ' re doing
        good_to_go = True
        if health is not None :
            good_to_go = good_to_go and str ( env [ 'Health' ] ) == health
        if status is not None :
            good_to_go = good_to_go and str ( env [ 'Status' ] ) == status
        if version_label is not None :
            good_to_go = good_to_go and str ( env [ 'VersionLabel' ] ) == version_label
        # allow a certain number of Red samples before failing
        if env [ 'Status' ] == 'Ready' and env [ 'Health' ] == 'Red' :
            if 'RedCount' not in env :
                env [ 'RedCount' ] = 0
            env [ 'RedCount' ] += 1
            if env [ 'RedCount' ] > MAX_RED_SAMPLES :
                out ( 'Deploy failed' )
                raise Exception ( 'Ready and red' )
        # log it
        if good_to_go :
            out ( msg + " ... done" )
            environment_names . remove ( env_name )
        else :
            out ( msg + " ... waiting" )
        # log events
        ( events , next_token ) = self . describe_events ( env_name , start_time = datetime . now ( ) . isoformat ( ) )
        for event in events :
            if event not in seen_events :
                out ( "[" + event [ 'Severity' ] + "] " + event [ 'Message' ] )
                seen_events . append ( event )
    # check the time
    elapsed = time ( ) - started
    if elapsed > self . wait_time_secs :
        message = "Wait time for environment(s) {environments} to be {health} expired" . format ( environments = " and " . join ( environment_names ) , health = ( health or "Green" ) )
        raise Exception ( message )


signature:
def add_arguments ( parser ) :
    """adds arguments for the swap urls command"""

implementation:
parser . add_argument ( '-o' , '--old-environment' , help = 'Old environment name' , required = True )
parser . add_argument ( '-n' , '--new-environment' , help = 'New environment name' , required = True )


signature:
def execute ( helper , config , args ) :
    """Swaps old and new URLs .
 If old _ environment was active , new _ environment will become the active environment"""

implementation:
old_env_name = args . old_environment
new_env_name = args . new_environment
# swap C - Names
out ( "Assuming that {} is the currently active environment..." . format ( old_env_name ) )
out ( "Swapping environment cnames: {} will become active, {} will become inactive." . format ( new_env_name , old_env_name ) )
helper . swap_environment_cnames ( old_env_name , new_env_name )
helper . wait_for_environments ( [ old_env_name , new_env_name ] , status = 'Ready' , include_deleted = False )


signature:
def execute ( helper , config , args ) :
    """dump command dumps things"""

implementation:
env = parse_env_config ( config , args . environment )
option_settings = env . get ( 'option_settings' , { } )
settings = parse_option_settings ( option_settings )
for setting in settings :
    out ( str ( setting ) )


signature:
def cached_property ( f ) :
    """Similar to ` @ property ` but it calls the function just once and caches
 the result . The object has to can have ` ` _ _ cache _ _ ` ` attribute .
 If you define ` _ _ slots _ _ ` for optimization , the metaclass should be a
 : class : ` CacheMeta ` ."""

implementation:
@ property
@ functools . wraps ( f )
def wrapped ( self , name = f . __name__ ) :
    try :
        cache = self . __cache__
    except AttributeError :
        self . __cache__ = cache = { }
    try :
        return cache [ name ]
    except KeyError :
        cache [ name ] = rv = f ( self )
        return rv
return wrapped


signature:
def execute ( helper , config , args ) :
    """Lists environments"""

implementation:
envs = config . get ( 'app' , { } ) . get ( 'environments' , [ ] )
out ( "Parsed environments:" )
for name , conf in list ( envs . items ( ) ) :
    out ( '\t' + name )
envs = helper . get_environments ( )
out ( "Deployed environments:" )
for env in envs :
    if env [ 'Status' ] != 'Terminated' :
        out ( '\t' + str ( env [ 'EnvironmentName' ] ) + ' (' + str ( env [ 'Status' ] ) + ', ' + str ( env [ 'CNAME' ] ) + ')' )


signature:
def execute ( helper , config , args ) :
    """The init command"""

implementation:
# check to see if the application exists
if not helper . application_exists ( ) :
    helper . create_application ( get ( config , 'app.description' ) )
else :
    out ( "Application " + get ( config , 'app.app_name' ) + " exists" )
# create environments
environment_names = [ ]
environments_to_wait_for_green = [ ]
for env_name , env_config in list ( get ( config , 'app.environments' ) . items ( ) ) :
    environment_names . append ( env_name )
    env_config = parse_env_config ( config , env_name )
    if not helper . environment_exists ( env_name ) :
        option_settings = parse_option_settings ( env_config . get ( 'option_settings' , { } ) )
        helper . create_environment ( env_name , solution_stack_name = env_config . get ( 'solution_stack_name' ) , cname_prefix = env_config . get ( 'cname_prefix' , None ) , description = env_config . get ( 'description' , None ) , option_settings = option_settings , tier_name = env_config . get ( 'tier_name' ) , tier_type = env_config . get ( 'tier_type' ) , tier_version = env_config . get ( 'tier_version' ) , version_label = args . version_label )
        environments_to_wait_for_green . append ( env_name )
    else :
        out ( "Environment " + env_name )
# get the environments
environments_to_wait_for_term = [ ]
if args . delete :
    environments = helper . get_environments ( )
    for env in environments :
        if env [ 'EnvironmentName' ] not in environment_names :
            if env [ 'Status' ] != 'Ready' :
                out ( "Unable to delete " + env [ 'EnvironmentName' ] + " because it's not in status Ready (" + env [ 'Status' ] + ")" )
            else :
                out ( "Deleting environment: " + env [ 'EnvironmentName' ] )
                helper . delete_environment ( env [ 'EnvironmentName' ] )
                environments_to_wait_for_term . append ( env [ 'EnvironmentName' ] )
# wait
if not args . dont_wait and len ( environments_to_wait_for_green ) > 0 :
    helper . wait_for_environments ( environments_to_wait_for_green , status = 'Ready' , include_deleted = False )
if not args . dont_wait and len ( environments_to_wait_for_term ) > 0 :
    helper . wait_for_environments ( environments_to_wait_for_term , status = 'Terminated' , include_deleted = False )
out ( "Application initialized" )
return 0


signature:
def execute ( helper , config , args ) :
    """Deletes an environment"""

implementation:
helper . delete_application ( )
# wait
if not args . dont_wait : # get environments
    environment_names = [ ]
    for env in helper . get_environments ( ) :
        environment_names . append ( env [ 'EnvironmentName' ] )
    # wait for them
    helper . wait_for_environments ( environment_names , status = 'Terminated' )
return 0


implementation:
env_config = parse_env_config ( config , args . environment )
environments_to_wait_for_term = [ ]
environments = helper . get_environments ( )
for env in environments :
    if env [ 'EnvironmentName' ] == args . environment :
        if env [ 'Status' ] != 'Ready' :
            out ( "Unable to delete " + env [ 'EnvironmentName' ] + " because it's not in status Ready (" + env [ 'Status' ] + ")" )
        else :
            out ( "Deleting environment: " + env [ 'EnvironmentName' ] )
            helper . delete_environment ( env [ 'EnvironmentName' ] )
            environments_to_wait_for_term . append ( env [ 'EnvironmentName' ] )
if not args . dont_wait :
    helper . wait_for_environments ( environments_to_wait_for_term , status = 'Terminated' , include_deleted = True )
out ( "Environment deleted" )
return 0


signature:
def execute ( helper , config , args ) :
    """Deploys to an environment"""

implementation:
version_label = args . version_label
env_config = parse_env_config ( config , args . environment )
env_name = args . environment
# upload or build an archive
version_label = upload_application_archive ( helper , env_config , archive = args . archive , directory = args . directory , version_label = version_label )
import datetime
start_time = datetime . datetime . utcnow ( ) . isoformat ( ) + 'Z'
# deploy it
helper . deploy_version ( env_name , version_label )
# wait
if not args . dont_wait :
    helper . wait_for_environments ( env_name , status = 'Ready' , version_label = version_label , include_deleted = False )
# update it
env = parse_env_config ( config , env_name )
option_settings = parse_option_settings ( env . get ( 'option_settings' , { } ) )
helper . update_environment ( env_name , description = env . get ( 'description' , None ) , option_settings = option_settings , tier_type = env . get ( 'tier_type' ) , tier_name = env . get ( 'tier_name' ) , tier_version = env . get ( 'tier_version' ) )
# wait
if not args . dont_wait :
    helper . wait_for_environments ( env_name , health = 'Green' , status = 'Ready' , version_label = version_label , include_deleted = False )
events = helper . ebs . describe_events ( start_time = start_time , environment_name = env_name )
import json
if args . log_events_to_file :
    with open ( 'ebs_events.json' , 'w+' ) as f :
        json . dump ( events , f )
# delete unused
helper . delete_unused_versions ( versions_to_keep = int ( get ( config , 'app.versions_to_keep' , 10 ) ) )


signature:
def add_arguments ( parser ) :
    """adds arguments for the deploy command"""

implementation:
parser . add_argument ( '-e' , '--environment' , help = 'Environment name' , required = True )
parser . add_argument ( '-w' , '--dont-wait' , help = 'Skip waiting for the init to finish' , action = 'store_true' )
parser . add_argument ( '-l' , '--version-label' , help = 'Version label' , required = False )


implementation:
env_config = parse_env_config ( config , args . environment )
cname_prefix = env_config . get ( 'cname_prefix' , None )
env_name = args . environment
# change version
if args . version_label :
    helper . deploy_version ( env_name , args . version_label )
    if not args . dont_wait :
        helper . wait_for_environments ( env_name , status = 'Ready' , version_label = args . version_label )
# update it
env = parse_env_config ( config , env_name )
option_settings = parse_option_settings ( env . get ( 'option_settings' , { } ) )
helper . update_environment ( env_name , description = env . get ( 'description' , None ) , option_settings = option_settings , tier_type = env . get ( 'tier_type' ) , tier_name = env . get ( 'tier_name' ) , tier_version = env . get ( 'tier_version' ) )
# wait
if not args . dont_wait :
    helper . wait_for_environments ( env_name , health = 'Green' , status = 'Ready' , version_label = args . version_label )
# delete unused
helper . delete_unused_versions ( versions_to_keep = int ( get ( config , 'app.versions_to_keep' , 10 ) ) )


signature:
def join_phonemes ( * args ) :
    """Joins a Hangul letter from Korean phonemes ."""

implementation:
# Normalize arguments as onset , nucleus , coda .
if len ( args ) == 1 : # tuple of ( onset , nucleus [ , coda ] )
    args = args [ 0 ]
if len ( args ) == 2 :
    args += ( CODAS [ 0 ] , )
try :
    onset , nucleus , coda = args
except ValueError :
    raise TypeError ( 'join_phonemes() takes at most 3 arguments' )
offset = ( ( ONSETS . index ( onset ) * NUM_NUCLEUSES + NUCLEUSES . index ( nucleus ) ) * NUM_CODAS + CODAS . index ( coda ) )
return unichr ( FIRST_HANGUL_OFFSET + offset )


signature:
def split_phonemes ( letter , onset = True , nucleus = True , coda = True ) :
    """Splits Korean phonemes as known as " 자소 " from a Hangul letter .
 : returns : ( onset , nucleus , coda )
 : raises ValueError : ` letter ` is not a Hangul single letter ."""

implementation:
if len ( letter ) != 1 or not is_hangul ( letter ) :
    raise ValueError ( 'Not Hangul letter: %r' % letter )
offset = ord ( letter ) - FIRST_HANGUL_OFFSET
phonemes = [ None ] * 3
if onset :
    phonemes [ 0 ] = ONSETS [ offset // ( NUM_NUCLEUSES * NUM_CODAS ) ]
if nucleus :
    phonemes [ 1 ] = NUCLEUSES [ ( offset // NUM_CODAS ) % NUM_NUCLEUSES ]
if coda :
    phonemes [ 2 ] = CODAS [ offset % NUM_CODAS ]
return tuple ( phonemes )


signature:
def combine_words ( word1 , word2 ) :
    """Combines two words . If the first word ends with a vowel and the initial
 letter of the second word is only consonant , it merges them into one
 letter : :
 > > > combine _ words ( u ' 다 ' , u ' ᆰ ' )
 닭
 > > > combine _ words ( u ' 가오 ' , u ' ᄂ누리 ' )
 가온누리"""

implementation:
if word1 and word2 and is_consonant ( word2 [ 0 ] ) :
    onset , nucleus , coda = split_phonemes ( word1 [ - 1 ] )
    if not coda :
        glue = join_phonemes ( onset , nucleus , word2 [ 0 ] )
        return word1 [ : - 1 ] + glue + word2 [ 1 : ]
return word1 + word2


signature:
def index_particles ( particles ) :
    """Indexes : class : ` Particle ` objects . It returns a regex pattern which
 matches to any particle morphs and a dictionary indexes the given particles
 by regex groups ."""

implementation:
patterns , indices = [ ] , { }
for x , p in enumerate ( particles ) :
    group = u'_%d' % x
    indices [ group ] = x
    patterns . append ( u'(?P<%s>%s)' % ( group , p . regex_pattern ( ) ) )
pattern = re . compile ( u'|' . join ( patterns ) )
return pattern , indices


signature:
def execute ( helper , config , args ) :
    """Waits for an environment to be healthy"""

implementation: helper . wait_for_environments ( args . environment , health = args . health )


implementation:
versions = helper . get_versions ( )
out ( "Deployed versions:" )
for version in versions :
    out ( version )


signature:
def add_arguments ( parser ) :
    """Args for the init command"""

implementation:
parser . add_argument ( '-e' , '--environment' , help = 'Environment name' , required = False , nargs = '+' )
parser . add_argument ( '-w' , '--dont-wait' , help = 'Skip waiting for the app to be deleted' , action = 'store_true' )


signature:
def execute ( helper , config , args ) :
    """Updates environments"""

implementation:
environments = [ ]
if args . environment :
    for env_name in args . environment :
        environments . append ( env_name )
else :
    for env_name , env_config in list ( get ( config , 'app.environments' ) . items ( ) ) :
        environments . append ( env_name )
wait_environments = [ ]
for env_name in environments :
    env = parse_env_config ( config , env_name )
    option_settings = parse_option_settings ( env . get ( 'option_settings' , { } ) )
    helper . update_environment ( env_name , description = env . get ( 'description' , None ) , option_settings = option_settings , tier_type = env . get ( 'tier_type' ) , tier_name = env . get ( 'tier_name' ) , tier_version = env . get ( 'tier_version' ) )
    wait_environments . append ( env_name )
# wait
if not args . dont_wait :
    helper . wait_for_environments ( wait_environments , health = 'Green' , status = 'Ready' )


signature:
def execute ( helper , config , args ) :
    """Describes recent events for an environment ."""

implementation:
environment_name = args . environment
( events , next_token ) = helper . describe_events ( environment_name , start_time = datetime . now ( ) . isoformat ( ) )
# swap C - Names
for event in events :
    print ( ( "[" + event [ 'Severity' ] + "] " + event [ 'Message' ] ) )


signature:
def execute ( helper , config , args ) :
    """Rebuilds an environment"""

implementation:
env_config = parse_env_config ( config , args . environment )
helper . rebuild_environment ( args . environment )
# wait
if not args . dont_wait :
    helper . wait_for_environments ( args . environment , health = 'Green' , status = 'Ready' )


signature:
def generate_tolerances ( morph1 , morph2 ) :
    """Generates all reasonable tolerant particle morphs : :
 > > > set ( generate _ tolerances ( u ' 이 ' , u ' 가 ' ) )
 set ( [ u ' 이 ( 가 ) ' , u ' ( 이 ) 가 ' , u ' 가 ( 이 ) ' , u ' ( 가 ) 이 ' ] )
 > > > set ( generate _ tolerances ( u ' 이면 ' , u ' 면 ' ) )
 set ( [ u ' ( 이 ) 면 ' ] )"""

implementation:
if morph1 == morph2 : # Tolerance not required .
    return
if not ( morph1 and morph2 ) : # Null allomorph exists .
    yield u'(%s)' % ( morph1 or morph2 )
    return
len1 , len2 = len ( morph1 ) , len ( morph2 )
if len1 != len2 :
    longer , shorter = ( morph1 , morph2 ) if len1 > len2 else ( morph2 , morph1 )
    if longer . endswith ( shorter ) : # Longer morph ends with shorter morph .
        yield u'(%s)%s' % ( longer [ : - len ( shorter ) ] , shorter )
        return
# Find common suffix between two morphs .
for x , ( let1 , let2 ) in enumerate ( zip ( reversed ( morph1 ) , reversed ( morph2 ) ) ) :
    if let1 != let2 :
        break
if x : # They share the common suffix .
    x1 , x2 = len ( morph1 ) - x , len ( morph2 ) - x
    common_suffix = morph1 [ x1 : ]
    morph1 , morph2 = morph1 [ : x1 ] , morph2 [ : x2 ]
else : # No similarity with each other .
    common_suffix = ''
for morph1 , morph2 in [ ( morph1 , morph2 ) , ( morph2 , morph1 ) ] :
    yield u'%s(%s)%s' % ( morph1 , morph2 , common_suffix )
    yield u'(%s)%s%s' % ( morph1 , morph2 , common_suffix )


signature:
def parse_tolerance_style ( style , registry = None ) :
    """Resolves a tolerance style of the given tolerant particle morph : :
 > > > parse _ tolerance _ style ( u ' 은 ( 는 ) ' )
 > > > parse _ tolerance _ style ( u ' ( 은 ) 는 ' )
 > > > parse _ tolerance _ style ( OPTIONAL _ MORPH2 _ AND _ MORPH1)"""

implementation:
if isinstance ( style , integer_types ) :
    return style
if registry is None :
    from . import registry
particle = registry . parse ( style )
if len ( particle . tolerances ) != 4 :
    raise ValueError ( 'Set tolerance style by general allomorphic particle' )
return particle . tolerances . index ( style )


signature:
def execute ( helper , config , args ) :
    """Lists solution stacks"""

implementation:
out ( "Available solution stacks" )
for stack in helper . list_available_solution_stacks ( ) :
    out ( "    " + str ( stack ) )
return 0


implementation:
parser . add_argument ( '-e' , '--environment' , help = 'Environment name' , required = True )
parser . add_argument ( '-w' , '--dont-wait' , help = 'Skip waiting' , action = 'store_true' )
parser . add_argument ( '-a' , '--archive' , help = 'Archive file' , required = False )
parser . add_argument ( '-d' , '--directory' , help = 'Directory' , required = False )
parser . add_argument ( '-l' , '--version-label' , help = 'Version label' , required = False )
parser . add_argument ( '-t' , '--termination-delay' , help = 'Delay termination of old environment by this number of seconds' , type = int , required = False )


implementation:
version_label = args . version_label
archive = args . archive
# get the environment configuration
env_config = parse_env_config ( config , args . environment )
option_settings = parse_option_settings ( env_config . get ( 'option_settings' , { } ) )
cname_prefix = env_config . get ( 'cname_prefix' , None )
# no zdt for anything but web server
tier_name = env_config . get ( 'tier_name' , 'WebServer' )
if tier_name != 'WebServer' :
    raise Exception ( "Only able to do zero downtime deployments for " "WebServer tiers, can't do them for %s" % ( tier_name , ) )
# find an available environment name
out ( "Determining new environment name..." )
new_env_name = None
if not helper . environment_exists ( args . environment ) :
    new_env_name = args . environment
else :
    for i in range ( 10 ) :
        temp_env_name = args . environment + '-' + str ( i )
        if not helper . environment_exists ( temp_env_name ) :
            new_env_name = temp_env_name
            break
if new_env_name is None :
    raise Exception ( "Unable to determine new environment name" )
out ( "New environment name will be " + new_env_name )
# find an available cname name
out ( "Determining new environment cname..." )
new_env_cname = None
for i in range ( 10 ) :
    temp_cname = cname_prefix + '-' + str ( i )
    if not helper . environment_name_for_cname ( temp_cname ) :
        new_env_cname = temp_cname
        break
if new_env_cname is None :
    raise Exception ( "Unable to determine new environment cname" )
out ( "New environment cname will be " + new_env_cname )
# upload or build an archive
version_label = upload_application_archive ( helper , env_config , archive = args . archive , directory = args . directory , version_label = version_label )
# create the new environment
helper . create_environment ( new_env_name , solution_stack_name = env_config . get ( 'solution_stack_name' ) , cname_prefix = new_env_cname , description = env_config . get ( 'description' , None ) , option_settings = option_settings , version_label = version_label , tier_name = tier_name , tier_type = env_config . get ( 'tier_type' ) , tier_version = env_config . get ( 'tier_version' ) )
helper . wait_for_environments ( new_env_name , status = 'Ready' , health = 'Green' , include_deleted = False )
# find existing environment name
old_env_name = helper . environment_name_for_cname ( cname_prefix )
if old_env_name is None :
    raise Exception ( "Unable to find current environment with cname: " + cname_prefix )
out ( "Current environment name is " + old_env_name )
# swap C - Names
out ( "Swapping environment cnames" )
helper . swap_environment_cnames ( old_env_name , new_env_name )
helper . wait_for_environments ( [ old_env_name , new_env_name ] , status = 'Ready' , include_deleted = False )
# delete the old environment
if args . termination_delay :
    out ( "Termination delay specified, sleeping for {} seconds..." . format ( args . termination_delay ) )
    time . sleep ( args . termination_delay )
out ( "Deleting old environment {}" . format ( old_env_name ) )
helper . delete_environment ( old_env_name )
# delete unused
helper . delete_unused_versions ( versions_to_keep = int ( get ( config , 'app.versions_to_keep' , 10 ) ) )


signature:
def filter_only_significant ( word ) :
    """Gets a word which removes insignificant letters at the end of the given
 word : :
 > > > pick _ significant ( u ' 넥슨 ( 코리아 ) ' )
 넥슨
 > > > pick _ significant ( u ' 메이플스토리 . . . ' )
 메이플스토리"""

implementation:
if not word :
    return word
# Unwrap a complete parenthesis .
if word . startswith ( u'(' ) and word . endswith ( u')' ) :
    return filter_only_significant ( word [ 1 : - 1 ] )
x = len ( word )
while x > 0 :
    x -= 1
    c = word [ x ]
    # Skip a complete parenthesis .
    if c == u')' :
        m = INSIGNIFICANT_PARENTHESIS_PATTERN . search ( word [ : x + 1 ] )
        if m is not None :
            x = m . start ( )
        continue
    # Skip unreadable characters such as punctuations .
    unicode_category = unicodedata . category ( c )
    if not SIGNIFICANT_UNICODE_CATEGORY_PATTERN . match ( unicode_category ) :
        continue
    break
return word [ : x + 1 ]


signature:
def pick_coda_from_letter ( letter ) :
    """Picks only a coda from a Hangul letter . It returns ` ` None ` ` if the
 given letter is not Hangul ."""

implementation:
try :
    __ , __ , coda = split_phonemes ( letter , onset = False , nucleus = False , coda = True )
except ValueError :
    return None
else :
    return coda


signature:
def pick_coda_from_decimal ( decimal ) :
    """Picks only a coda from a decimal ."""

implementation:
decimal = Decimal ( decimal )
__ , digits , exp = decimal . as_tuple ( )
if exp < 0 :
    return DIGIT_CODAS [ digits [ - 1 ] ]
__ , digits , exp = decimal . normalize ( ) . as_tuple ( )
index = bisect_right ( EXP_INDICES , exp ) - 1
if index < 0 :
    return DIGIT_CODAS [ digits [ - 1 ] ]
else :
    return EXP_CODAS [ EXP_INDICES [ index ] ]


signature:
def deposit_fetcher ( record_uuid , data ) :
    """Fetch a deposit identifier .
 : param record _ uuid : Record UUID .
 : param data : Record content .
 : returns : A : class : ` invenio _ pidstore . fetchers . FetchedPID ` that contains
 data [ ' _ deposit ' ] [ ' id ' ] as pid _ value ."""

implementation: return FetchedPID ( provider = DepositProvider , pid_type = DepositProvider . pid_type , pid_value = str ( data [ '_deposit' ] [ 'id' ] ) , )


signature:
def deposit_minter ( record_uuid , data ) :
    """Mint a deposit identifier .
 A PID with the following characteristics is created :
 . . code - block : : python
 " object _ type " : " rec " ,
 " object _ uuid " : record _ uuid ,
 " pid _ value " : " < new - pid - value > " ,
 " pid _ type " : " depid " ,
 The following deposit meta information are updated :
 . . code - block : : python
 deposit [ ' _ deposit ' ] = {
 " id " : " < new - pid - value > " ,
 " status " : " draft " ,
 : param record _ uuid : Record UUID .
 : param data : Record content .
 : returns : A : class : ` invenio _ pidstore . models . PersistentIdentifier ` object ."""

implementation:
provider = DepositProvider . create ( object_type = 'rec' , object_uuid = record_uuid , pid_value = uuid . uuid4 ( ) . hex , )
data [ '_deposit' ] = { 'id' : provider . pid . pid_value , 'status' : 'draft' , }
return provider . pid


signature:
def admin_permission_factory ( ) :
    """Factory for creating a permission for an admin ` deposit - admin - access ` .
 If ` invenio - access ` module is installed , it returns a
 : class : ` invenio _ access . permissions . DynamicPermission ` object .
 Otherwise , it returns a : class : ` flask _ principal . Permission ` object .
 : returns : Permission instance ."""

implementation:
try :
    pkg_resources . get_distribution ( 'invenio-access' )
    from invenio_access . permissions import DynamicPermission as Permission
except pkg_resources . DistributionNotFound :
    from flask_principal import Permission
return Permission ( action_admin_access )


signature:
def default_view_method ( pid , record , template = None ) :
    """Default view method .
 Sends ` ` record _ viewed ` ` signal and renders template ."""

implementation:
record_viewed . send ( current_app . _get_current_object ( ) , pid = pid , record = record , )
deposit_type = request . values . get ( 'type' )
return render_template ( template , pid = pid , record = record , jsonschema = current_deposit . jsonschemas [ deposit_type ] , schemaform = current_deposit . schemaforms [ deposit_type ] , )


signature:
def create ( cls , object_type = None , object_uuid = None , ** kwargs ) :
    """Create a new deposit identifier .
 : param object _ type : The object type ( Default : ` ` None ` ` )
 : param object _ uuid : The object UUID ( Default : ` ` None ` ` )
 : param kwargs : It contains the pid value ."""

implementation:
assert 'pid_value' in kwargs
kwargs . setdefault ( 'status' , cls . default_status )
return super ( DepositProvider , cls ) . create ( object_type = object_type , object_uuid = object_uuid , ** kwargs )


signature:
def extract_actions_from_class ( record_class ) :
    """Extract actions from class ."""

implementation:
for name in dir ( record_class ) :
    method = getattr ( record_class , name , None )
    if method and getattr ( method , '__deposit_action__' , False ) :
        yield method . __name__


signature:
def check_oauth2_scope ( can_method , * myscopes ) :
    """Base permission factory that check OAuth2 scope and can _ method .
 : param can _ method : Permission check function that accept a record in input
 and return a boolean .
 : param myscopes : List of scopes required to permit the access .
 : returns : A : class : ` flask _ principal . Permission ` factory ."""

implementation:
def check ( record , * args , ** kwargs ) :
    @ require_api_auth ( )
    @ require_oauth_scopes ( * myscopes )
    def can ( self ) :
        return can_method ( record )
    return type ( 'CheckOAuth2Scope' , ( ) , { 'can' : can } ) ( )
return check


signature:
def can_elasticsearch ( record ) :
    """Check if a given record is indexed .
 : param record : A record object .
 : returns : If the record is indexed returns ` True ` , otherwise ` False ` ."""

implementation:
search = request . _methodview . search_class ( )
search = search . get_record ( str ( record . id ) )
return search . count ( ) == 1


signature:
def create_error_handlers ( blueprint ) :
    """Create error handlers on blueprint ."""

implementation:
blueprint . errorhandler ( PIDInvalidAction ) ( create_api_errorhandler ( status = 403 , message = 'Invalid action' ) )
records_rest_error_handlers ( blueprint )


signature:
def create_blueprint ( endpoints ) :
    """Create Invenio - Deposit - REST blueprint .
 See : : data : ` invenio _ deposit . config . DEPOSIT _ REST _ ENDPOINTS ` .
 : param endpoints : List of endpoints configuration .
 : returns : The configured blueprint ."""

implementation:
blueprint = Blueprint ( 'invenio_deposit_rest' , __name__ , url_prefix = '' , )
create_error_handlers ( blueprint )
for endpoint , options in ( endpoints or { } ) . items ( ) :
    options = deepcopy ( options )
    if 'files_serializers' in options :
        files_serializers = options . get ( 'files_serializers' )
        files_serializers = { mime : obj_or_import_string ( func ) for mime , func in files_serializers . items ( ) }
        del options [ 'files_serializers' ]
    else :
        files_serializers = { }
    if 'record_serializers' in options :
        serializers = options . get ( 'record_serializers' )
        serializers = { mime : obj_or_import_string ( func ) for mime , func in serializers . items ( ) }
    else :
        serializers = { }
    file_list_route = options . pop ( 'file_list_route' , '{0}/files' . format ( options [ 'item_route' ] ) )
    file_item_route = options . pop ( 'file_item_route' , '{0}/files/<path:key>' . format ( options [ 'item_route' ] ) )
    options . setdefault ( 'search_class' , DepositSearch )
    search_class = obj_or_import_string ( options [ 'search_class' ] )
    # records rest endpoints will use the deposit class as record class
    options . setdefault ( 'record_class' , Deposit )
    record_class = obj_or_import_string ( options [ 'record_class' ] )
    # backward compatibility for indexer class
    options . setdefault ( 'indexer_class' , None )
    for rule in records_rest_url_rules ( endpoint , ** options ) :
        blueprint . add_url_rule ( ** rule )
    search_class_kwargs = { }
    if options . get ( 'search_index' ) :
        search_class_kwargs [ 'index' ] = options [ 'search_index' ]
    if options . get ( 'search_type' ) :
        search_class_kwargs [ 'doc_type' ] = options [ 'search_type' ]
    ctx = dict ( read_permission_factory = obj_or_import_string ( options . get ( 'read_permission_factory_imp' ) ) , create_permission_factory = obj_or_import_string ( options . get ( 'create_permission_factory_imp' ) ) , update_permission_factory = obj_or_import_string ( options . get ( 'update_permission_factory_imp' ) ) , delete_permission_factory = obj_or_import_string ( options . get ( 'delete_permission_factory_imp' ) ) , record_class = record_class , search_class = partial ( search_class , ** search_class_kwargs ) , default_media_type = options . get ( 'default_media_type' ) , )
    deposit_actions = DepositActionResource . as_view ( DepositActionResource . view_name . format ( endpoint ) , serializers = serializers , pid_type = options [ 'pid_type' ] , ctx = ctx , )
    blueprint . add_url_rule ( '{0}/actions/<any({1}):action>' . format ( options [ 'item_route' ] , ',' . join ( extract_actions_from_class ( record_class ) ) , ) , view_func = deposit_actions , methods = [ 'POST' ] , )
    deposit_files = DepositFilesResource . as_view ( DepositFilesResource . view_name . format ( endpoint ) , serializers = files_serializers , pid_type = options [ 'pid_type' ] , ctx = ctx , )
    blueprint . add_url_rule ( file_list_route , view_func = deposit_files , methods = [ 'GET' , 'POST' , 'PUT' ] , )
    deposit_file = DepositFileResource . as_view ( DepositFileResource . view_name . format ( endpoint ) , serializers = files_serializers , pid_type = options [ 'pid_type' ] , ctx = ctx , )
    blueprint . add_url_rule ( file_item_route , view_func = deposit_file , methods = [ 'GET' , 'PUT' , 'DELETE' ] , )
return blueprint


signature:
def post ( self , pid , record , action ) :
    """Handle deposit action .
 After the action is executed , a
 : class : ` invenio _ deposit . signals . post _ action ` signal is sent .
 Permission required : ` update _ permission _ factory ` .
 : param pid : Pid object ( from url ) .
 : param record : Record object resolved from the pid .
 : param action : The action to execute ."""

implementation:
record = getattr ( record , action ) ( pid = pid )
db . session . commit ( )
# Refresh the PID and record metadata
db . session . refresh ( pid )
db . session . refresh ( record . model )
post_action . send ( current_app . _get_current_object ( ) , action = action , pid = pid , deposit = record )
response = self . make_response ( pid , record , 202 if action == 'publish' else 201 )
endpoint = '.{0}_item' . format ( pid . pid_type )
location = url_for ( endpoint , pid_value = pid . pid_value , _external = True )
response . headers . extend ( dict ( Location = location ) )
return response


signature:
def get ( self , pid , record ) :
    """Get files .
 Permission required : ` read _ permission _ factory ` .
 : param pid : Pid object ( from url ) .
 : param record : Record object resolved from the pid .
 : returns : The files ."""

implementation: return self . make_response ( obj = record . files , pid = pid , record = record )


signature:
def post ( self , pid , record ) :
    """Handle POST deposit files .
 Permission required : ` update _ permission _ factory ` .
 : param pid : Pid object ( from url ) .
 : param record : Record object resolved from the pid ."""

implementation:
# load the file
uploaded_file = request . files [ 'file' ]
# file name
key = secure_filename ( request . form . get ( 'name' ) or uploaded_file . filename )
# check if already exists a file with this name
if key in record . files :
    raise FileAlreadyExists ( )
# add it to the deposit
record . files [ key ] = uploaded_file . stream
record . commit ( )
db . session . commit ( )
return self . make_response ( obj = record . files [ key ] . obj , pid = pid , record = record , status = 201 )


signature:
def put ( self , pid , record ) :
    """Handle the sort of the files through the PUT deposit files .
 Expected input in body PUT :
 . . code - block : : javascript
 " id " : 1
 " id " : 2
 Permission required : ` update _ permission _ factory ` .
 : param pid : Pid object ( from url ) .
 : param record : Record object resolved from the pid .
 : returns : The files ."""

implementation:
try :
    ids = [ data [ 'id' ] for data in json . loads ( request . data . decode ( 'utf-8' ) ) ]
except KeyError :
    raise WrongFile ( )
record . files . sort_by ( * ids )
record . commit ( )
db . session . commit ( )
return self . make_response ( obj = record . files , pid = pid , record = record )


signature:
def get ( self , pid , record , key , version_id , ** kwargs ) :
    """Get file .
 Permission required : ` read _ permission _ factory ` .
 : param pid : Pid object ( from url ) .
 : param record : Record object resolved from the pid .
 : param key : Unique identifier for the file in the deposit .
 : param version _ id : File version . Optional . If no version is provided ,
 the last version is retrieved .
 : returns : the file content ."""

implementation:
try :
    obj = record . files [ str ( key ) ] . get_version ( version_id = version_id )
    return self . make_response ( obj = obj or abort ( 404 ) , pid = pid , record = record )
except KeyError :
    abort ( 404 )


signature:
def put ( self , pid , record , key ) :
    """Handle the file rename through the PUT deposit file .
 Permission required : ` update _ permission _ factory ` .
 : param pid : Pid object ( from url ) .
 : param record : Record object resolved from the pid .
 : param key : Unique identifier for the file in the deposit ."""

implementation:
try :
    data = json . loads ( request . data . decode ( 'utf-8' ) )
    new_key = data [ 'filename' ]
except KeyError :
    raise WrongFile ( )
new_key_secure = secure_filename ( new_key )
if not new_key_secure or new_key != new_key_secure :
    raise WrongFile ( )
try :
    obj = record . files . rename ( str ( key ) , new_key_secure )
except KeyError :
    abort ( 404 )
record . commit ( )
db . session . commit ( )
return self . make_response ( obj = obj , pid = pid , record = record )


signature:
def delete ( self , pid , record , key ) :
    """Handle DELETE deposit file .
 Permission required : ` update _ permission _ factory ` .
 : param pid : Pid object ( from url ) .
 : param record : Record object resolved from the pid .
 : param key : Unique identifier for the file in the deposit ."""

implementation:
try :
    del record . files [ str ( key ) ]
    record . commit ( )
    db . session . commit ( )
    return make_response ( '' , 204 )
except KeyError :
    abort ( 404 , 'The specified object does not exist or has already ' 'been deleted.' )


signature:
def records ( ) :
    """Load records ."""

implementation:
import pkg_resources
from dojson . contrib . marc21 import marc21
from dojson . contrib . marc21 . utils import create_record , split_blob
from flask_login import login_user , logout_user
from invenio_accounts . models import User
from invenio_deposit . api import Deposit
users = User . query . all ( )
# pkg resources the demodata
data_path = pkg_resources . resource_filename ( 'invenio_records' , 'data/marc21/bibliographic.xml' )
with open ( data_path ) as source :
    with current_app . test_request_context ( ) :
        indexer = RecordIndexer ( )
        with db . session . begin_nested ( ) :
            for index , data in enumerate ( split_blob ( source . read ( ) ) , start = 1 ) :
                login_user ( users [ index % len ( users ) ] )
                # do translate
                record = marc21 . do ( create_record ( data ) )
                # create record
                indexer . index ( Deposit . create ( record ) )
                logout_user ( )
        db . session . commit ( )


signature:
def location ( ) :
    """Load default location ."""

implementation:
d = current_app . config [ 'DATADIR' ]
with db . session . begin_nested ( ) :
    Location . query . delete ( )
    loc = Location ( name = 'local' , uri = d , default = True )
    db . session . add ( loc )
db . session . commit ( )


signature:
def jsonschemas ( self ) :
    """Load deposit JSON schemas ."""

implementation:
_jsonschemas = { k : v [ 'jsonschema' ] for k , v in self . app . config [ 'DEPOSIT_RECORDS_UI_ENDPOINTS' ] . items ( ) if 'jsonschema' in v }
return defaultdict ( lambda : self . app . config [ 'DEPOSIT_DEFAULT_JSONSCHEMA' ] , _jsonschemas )


signature:
def schemaforms ( self ) :
    """Load deposit schema forms ."""

implementation:
_schemaforms = { k : v [ 'schemaform' ] for k , v in self . app . config [ 'DEPOSIT_RECORDS_UI_ENDPOINTS' ] . items ( ) if 'schemaform' in v }
return defaultdict ( lambda : self . app . config [ 'DEPOSIT_DEFAULT_SCHEMAFORM' ] , _schemaforms )


signature:
def init_app ( self , app ) :
    """Flask application initialization .
 Initialize the UI endpoints . Connect all signals if
 ` DEPOSIT _ REGISTER _ SIGNALS ` is ` ` True ` ` .
 : param app : An instance of : class : ` flask . Flask ` ."""

implementation:
self . init_config ( app )
app . register_blueprint ( ui . create_blueprint ( app . config [ 'DEPOSIT_RECORDS_UI_ENDPOINTS' ] ) )
app . extensions [ 'invenio-deposit' ] = _DepositState ( app )
if app . config [ 'DEPOSIT_REGISTER_SIGNALS' ] :
    post_action . connect ( index_deposit_after_publish , sender = app , weak = False )


signature:
def process_minter ( value ) :
    """Load minter from PIDStore registry based on given value .
 : param value : Name of the minter .
 : returns : The minter ."""

implementation:
try :
    return current_pidstore . minters [ value ]
except KeyError :
    raise click . BadParameter ( 'Unknown minter {0}. Please use one of {1}.' . format ( value , ', ' . join ( current_pidstore . minters . keys ( ) ) ) )


signature:
def process_schema ( value ) :
    """Load schema from JSONSchema registry based on given value .
 : param value : Schema path , relative to the directory when it was
 registered .
 : returns : The schema absolute path ."""

implementation:
schemas = current_app . extensions [ 'invenio-jsonschemas' ] . schemas
try :
    return schemas [ value ]
except KeyError :
    raise click . BadParameter ( 'Unknown schema {0}. Please use one of:\n {1}' . format ( value , '\n' . join ( schemas . keys ( ) ) ) )


signature:
def json_serializer ( pid , data , * args ) :
    """Build a JSON Flask response using the given data .
 : param pid : The ` invenio _ pidstore . models . PersistentIdentifier ` of the
 record .
 : param data : The record metadata .
 : returns : A Flask response with JSON data .
 : rtype : : py : class : ` flask . Response ` ."""

implementation:
if data is not None :
    response = Response ( json . dumps ( data . dumps ( ) ) , mimetype = 'application/json' )
else :
    response = Response ( mimetype = 'application/json' )
return response


signature:
def file_serializer ( obj ) :
    """Serialize a object .
 : param obj : A : class : ` invenio _ files _ rest . models . ObjectVersion ` instance .
 : returns : A dictionary with the fields to serialize ."""

implementation: return { "id" : str ( obj . file_id ) , "filename" : obj . key , "filesize" : obj . file . size , "checksum" : obj . file . checksum , }


signature:
def json_files_serializer ( objs , status = None ) :
    """JSON Files Serializer .
 : parma objs : A list of : class : ` invenio _ files _ rest . models . ObjectVersion `
 instances .
 : param status : A HTTP Status . ( Default : ` ` None ` ` )
 : returns : A Flask response with JSON data .
 : rtype : : py : class : ` flask . Response ` ."""

implementation:
files = [ file_serializer ( obj ) for obj in objs ]
return make_response ( json . dumps ( files ) , status )


signature:
def json_file_response ( obj = None , pid = None , record = None , status = None ) :
    """JSON Files / File serializer .
 : param obj : A : class : ` invenio _ files _ rest . models . ObjectVersion ` instance or
 a : class : ` invenio _ records _ files . api . FilesIterator ` if it ' s a list of
 files .
 : param pid : PID value . ( not used )
 : param record : The record metadata . ( not used )
 : param status : The HTTP status code .
 : returns : A Flask response with JSON data .
 : rtype : : py : class : ` flask . Response ` ."""

implementation:
from invenio_records_files . api import FilesIterator
if isinstance ( obj , FilesIterator ) :
    return json_files_serializer ( obj , status = status )
else :
    return json_file_serializer ( obj , status = status )


signature:
def index_deposit_after_publish ( sender , action = None , pid = None , deposit = None ) :
    """Index the record after publishing .
 . . note : : if the record is not published , it doesn ' t index .
 : param sender : Who send the signal .
 : param action : Action executed by the sender . ( Default : ` ` None ` ` )
 : param pid : PID object . ( Default : ` ` None ` ` )
 : param deposit : Deposit object . ( Default : ` ` None ` ` )"""

implementation:
if action == 'publish' :
    _ , record = deposit . fetch_published ( )
    index_record . delay ( str ( record . id ) )


signature:
def pid ( self ) :
    """Return an instance of deposit PID ."""

implementation:
pid = self . deposit_fetcher ( self . id , self )
return PersistentIdentifier . get ( pid . pid_type , pid . pid_value )


signature:
def record_schema ( self ) :
    """Convert deposit schema to a valid record schema ."""

implementation:
schema_path = current_jsonschemas . url_to_path ( self [ '$schema' ] )
schema_prefix = current_app . config [ 'DEPOSIT_JSONSCHEMAS_PREFIX' ]
if schema_path and schema_path . startswith ( schema_prefix ) :
    return current_jsonschemas . path_to_url ( schema_path [ len ( schema_prefix ) : ] )


signature:
def build_deposit_schema ( self , record ) :
    """Convert record schema to a valid deposit schema .
 : param record : The record used to build deposit schema .
 : returns : The absolute URL to the schema or ` None ` ."""

implementation:
schema_path = current_jsonschemas . url_to_path ( record [ '$schema' ] )
schema_prefix = current_app . config [ 'DEPOSIT_JSONSCHEMAS_PREFIX' ]
if schema_path :
    return current_jsonschemas . path_to_url ( schema_prefix + schema_path )


signature:
def fetch_published ( self ) :
    """Return a tuple with PID and published record ."""

implementation:
pid_type = self [ '_deposit' ] [ 'pid' ] [ 'type' ]
pid_value = self [ '_deposit' ] [ 'pid' ] [ 'value' ]
resolver = Resolver ( pid_type = pid_type , object_type = 'rec' , getter = partial ( self . published_record_class . get_record , with_deleted = True ) )
return resolver . resolve ( pid_value )


signature:
def merge_with_published ( self ) :
    """Merge changes with latest published version ."""

implementation:
pid , first = self . fetch_published ( )
lca = first . revisions [ self [ '_deposit' ] [ 'pid' ] [ 'revision_id' ] ]
# ignore _ deposit and $ schema field
args = [ lca . dumps ( ) , first . dumps ( ) , self . dumps ( ) ]
for arg in args :
    del arg [ '$schema' ] , arg [ '_deposit' ]
args . append ( { } )
m = Merger ( * args )
try :
    m . run ( )
except UnresolvedConflictsException :
    raise MergeConflict ( )
return patch ( m . unified_patches , lca )


signature:
def commit ( self , * args , ** kwargs ) :
    """Store changes on current instance in database and index it ."""

implementation: return super ( Deposit , self ) . commit ( * args , ** kwargs )


signature:
def create ( cls , data , id_ = None ) :
    """Create a deposit .
 Initialize the follow information inside the deposit :
 . . code - block : : python
 deposit [ ' _ deposit ' ] = {
 ' id ' : pid _ value ,
 ' status ' : ' draft ' ,
 ' owners ' : [ user _ id ] ,
 ' created _ by ' : user _ id ,
 The deposit index is updated .
 : param data : Input dictionary to fill the deposit .
 : param id _ : Default uuid for the deposit .
 : returns : The new created deposit ."""

implementation:
data . setdefault ( '$schema' , current_jsonschemas . path_to_url ( current_app . config [ 'DEPOSIT_DEFAULT_JSONSCHEMA' ] ) )
if '_deposit' not in data :
    id_ = id_ or uuid . uuid4 ( )
    cls . deposit_minter ( id_ , data )
data [ '_deposit' ] . setdefault ( 'owners' , list ( ) )
if current_user and current_user . is_authenticated :
    creator_id = int ( current_user . get_id ( ) )
    if creator_id not in data [ '_deposit' ] [ 'owners' ] :
        data [ '_deposit' ] [ 'owners' ] . append ( creator_id )
    data [ '_deposit' ] [ 'created_by' ] = creator_id
return super ( Deposit , cls ) . create ( data , id_ = id_ )


signature:
def _process_files ( self , record_id , data ) :
    """Snapshot bucket and add files in record during first publishing ."""

implementation:
if self . files :
    assert not self . files . bucket . locked
    self . files . bucket . locked = True
    snapshot = self . files . bucket . snapshot ( lock = True )
    data [ '_files' ] = self . files . dumps ( bucket = snapshot . id )
    yield data
    db . session . add ( RecordsBuckets ( record_id = record_id , bucket_id = snapshot . id ) )
else :
    yield data


signature:
def _publish_new ( self , id_ = None ) :
    """Publish new deposit .
 : param id _ : The forced record UUID ."""

implementation:
minter = current_pidstore . minters [ current_app . config [ 'DEPOSIT_PID_MINTER' ] ]
id_ = id_ or uuid . uuid4 ( )
record_pid = minter ( id_ , self )
self [ '_deposit' ] [ 'pid' ] = { 'type' : record_pid . pid_type , 'value' : record_pid . pid_value , 'revision_id' : 0 , }
data = dict ( self . dumps ( ) )
data [ '$schema' ] = self . record_schema
with self . _process_files ( id_ , data ) :
    record = self . published_record_class . create ( data , id_ = id_ )
return record


signature:
def _publish_edited ( self ) :
    """Publish the deposit after for editing ."""

implementation:
record_pid , record = self . fetch_published ( )
if record . revision_id == self [ '_deposit' ] [ 'pid' ] [ 'revision_id' ] :
    data = dict ( self . dumps ( ) )
else :
    data = self . merge_with_published ( )
data [ '$schema' ] = self . record_schema
data [ '_deposit' ] = self [ '_deposit' ]
record = record . __class__ ( data , model = record . model )
return record


signature:
def publish ( self , pid = None , id_ = None ) :
    """Publish a deposit .
 If it ' s the first time :
 * it calls the minter and set the following meta information inside
 the deposit :
 . . code - block : : python
 deposit [ ' _ deposit ' ] = {
 ' type ' : pid _ type ,
 ' value ' : pid _ value ,
 ' revision _ id ' : 0,
 * A dump of all information inside the deposit is done .
 * A snapshot of the files is done .
 Otherwise , published the new edited version .
 In this case , if in the mainwhile someone already published a new
 version , it ' ll try to merge the changes with the latest version .
 . . note : : no need for indexing as it calls ` self . commit ( ) ` .
 Status required : ` ` ' draft ' ` ` .
 : param pid : Force the new pid value . ( Default : ` ` None ` ` )
 : param id _ : Force the new uuid value as deposit id . ( Default : ` ` None ` ` )
 : returns : Returns itself ."""

implementation:
pid = pid or self . pid
if not pid . is_registered ( ) :
    raise PIDInvalidAction ( )
self [ '_deposit' ] [ 'status' ] = 'published'
if self [ '_deposit' ] . get ( 'pid' ) is None : # First publishing
    self . _publish_new ( id_ = id_ )
else : # Update after edit
    record = self . _publish_edited ( )
    record . commit ( )
self . commit ( )
return self


signature:
def _prepare_edit ( self , record ) :
    """Update selected keys .
 : param record : The record to prepare ."""

implementation:
data = record . dumps ( )
# Keep current record revision for merging .
data [ '_deposit' ] [ 'pid' ] [ 'revision_id' ] = record . revision_id
data [ '_deposit' ] [ 'status' ] = 'draft'
data [ '$schema' ] = self . build_deposit_schema ( record )
return data


signature:
def edit ( self , pid = None ) :
    """Edit deposit .
 # . The signal : data : ` invenio _ records . signals . before _ record _ update `
 is sent before the edit execution .
 # . The following meta information are saved inside the deposit :
 . . code - block : : python
 deposit [ ' _ deposit ' ] [ ' pid ' ] = record . revision _ id
 deposit [ ' _ deposit ' ] [ ' status ' ] = ' draft '
 deposit [ ' $ schema ' ] = deposit _ schema _ from _ record _ schema
 # . The signal : data : ` invenio _ records . signals . after _ record _ update ` is
 sent after the edit execution .
 # . The deposit index is updated .
 Status required : ` published ` .
 . . note : : the process fails if the pid has status
 : attr : ` invenio _ pidstore . models . PIDStatus . REGISTERED ` .
 : param pid : Force a pid object . ( Default : ` ` None ` ` )
 : returns : A new Deposit object ."""

implementation:
pid = pid or self . pid
with db . session . begin_nested ( ) :
    before_record_update . send ( current_app . _get_current_object ( ) , record = self )
    record_pid , record = self . fetch_published ( )
    assert PIDStatus . REGISTERED == record_pid . status
    assert record [ '_deposit' ] == self [ '_deposit' ]
    self . model . json = self . _prepare_edit ( record )
    flag_modified ( self . model , 'json' )
    db . session . merge ( self . model )
after_record_update . send ( current_app . _get_current_object ( ) , record = self )
return self . __class__ ( self . model . json , model = self . model )


signature:
def discard ( self , pid = None ) :
    """Discard deposit changes .
 # . The signal : data : ` invenio _ records . signals . before _ record _ update ` is
 sent before the edit execution .
 # . It restores the last published version .
 # . The following meta information are saved inside the deposit :
 . . code - block : : python
 deposit [ ' $ schema ' ] = deposit _ schema _ from _ record _ schema
 # . The signal : data : ` invenio _ records . signals . after _ record _ update ` is
 sent after the edit execution .
 # . The deposit index is updated .
 Status required : ` ` ' draft ' ` ` .
 : param pid : Force a pid object . ( Default : ` ` None ` ` )
 : returns : A new Deposit object ."""

implementation:
pid = pid or self . pid
with db . session . begin_nested ( ) :
    before_record_update . send ( current_app . _get_current_object ( ) , record = self )
    _ , record = self . fetch_published ( )
    self . model . json = deepcopy ( record . model . json )
    self . model . json [ '$schema' ] = self . build_deposit_schema ( record )
    flag_modified ( self . model , 'json' )
    db . session . merge ( self . model )
after_record_update . send ( current_app . _get_current_object ( ) , record = self )
return self . __class__ ( self . model . json , model = self . model )


signature:
def delete ( self , force = True , pid = None ) :
    """Delete deposit .
 Status required : ` ` ' draft ' ` ` .
 : param force : Force deposit delete . ( Default : ` ` True ` ` )
 : param pid : Force pid object . ( Default : ` ` None ` ` )
 : returns : A new Deposit object ."""

implementation:
pid = pid or self . pid
if self [ '_deposit' ] . get ( 'pid' ) :
    raise PIDInvalidAction ( )
if pid :
    pid . delete ( )
return super ( Deposit , self ) . delete ( force = force )


signature:
def clear ( self , * args , ** kwargs ) :
    """Clear only drafts .
 Status required : ` ` ' draft ' ` ` .
 Meta information inside ` _ deposit ` are preserved ."""

implementation: super ( Deposit , self ) . clear ( * args , ** kwargs )


signature:
def update ( self , * args , ** kwargs ) :
    """Update only drafts .
 Status required : ` ` ' draft ' ` ` .
 Meta information inside ` _ deposit ` are preserved ."""

implementation: super ( Deposit , self ) . update ( * args , ** kwargs )


signature:
def patch ( self , * args , ** kwargs ) :
    """Patch only drafts .
 Status required : ` ` ' draft ' ` ` .
 Meta information inside ` _ deposit ` are preserved ."""

implementation: return super ( Deposit , self ) . patch ( * args , ** kwargs )


signature:
def rst2node ( doc_name , data ) :
    """Converts a reStructuredText into its node"""

implementation:
if not data :
    return
parser = docutils . parsers . rst . Parser ( )
document = docutils . utils . new_document ( '<%s>' % doc_name )
document . settings = docutils . frontend . OptionParser ( ) . get_default_values ( )
document . settings . tab_width = 4
document . settings . pep_references = False
document . settings . rfc_references = False
document . settings . env = Env ( )
parser . parse ( data , document )
if len ( document . children ) == 1 :
    return document . children [ 0 ]
else :
    par = docutils . nodes . paragraph ( )
    for child in document . children :
        par += child
    return par


signature:
def setup ( app ) :
    """Hook the directives when Sphinx ask for it ."""

implementation:
if 'http' not in app . domains :
    httpdomain . setup ( app )
app . add_directive ( 'autopyramid' , RouteDirective )


signature:
def _parse_response ( self , response ) :
    """Parses the API response and raises appropriate errors if
 raise _ errors was set to True"""

implementation:
if not self . _raise_errors :
    return response
is_4xx_error = str ( response . status_code ) [ 0 ] == '4'
is_5xx_error = str ( response . status_code ) [ 0 ] == '5'
content = response . content
if response . status_code == 403 :
    raise AuthenticationError ( content )
elif is_4xx_error :
    raise APIError ( content )
elif is_5xx_error :
    raise ServerError ( content )
return response


signature:
def _api_request ( self , endpoint , http_method , * args , ** kwargs ) :
    """Private method for api requests"""

implementation:
logger . debug ( ' > Sending API request to endpoint: %s' % endpoint )
auth = self . _build_http_auth ( )
headers = self . _build_request_headers ( kwargs . get ( 'headers' ) )
logger . debug ( '\theaders: %s' % headers )
path = self . _build_request_path ( endpoint )
logger . debug ( '\tpath: %s' % path )
data = self . _build_payload ( kwargs . get ( 'payload' ) )
if not data :
    data = kwargs . get ( 'data' )
logger . debug ( '\tdata: %s' % data )
req_kw = dict ( auth = auth , headers = headers , timeout = kwargs . get ( 'timeout' , self . DEFAULT_TIMEOUT ) )
# do some error handling
if ( http_method == self . HTTP_POST ) :
    if ( data ) :
        r = requests . post ( path , data = data , ** req_kw )
    else :
        r = requests . post ( path , ** req_kw )
elif http_method == self . HTTP_PUT :
    if ( data ) :
        r = requests . put ( path , data = data , ** req_kw )
    else :
        r = requests . put ( path , ** req_kw )
elif http_method == self . HTTP_DELETE :
    r = requests . delete ( path , ** req_kw )
else :
    r = requests . get ( path , ** req_kw )
logger . debug ( '\tresponse code:%s' % r . status_code )
try :
    logger . debug ( '\tresponse: %s' % r . json ( ) )
except :
    logger . debug ( '\tresponse: %s' % r . content )
return self . _parse_response ( r )


signature:
def get_log ( self , log_id , timeout = None ) :
    """API call to get a specific log entry"""

implementation: return self . _api_request ( self . GET_LOG_ENDPOINT % log_id , self . HTTP_GET , timeout = timeout )


signature:
def get_log_events ( self , log_id , timeout = None ) :
    """API call to get a specific log entry"""

implementation: return self . _api_request ( self . GET_LOG_EVENTS_ENDPOINT % log_id , self . HTTP_GET , timeout = timeout )


signature:
def templates ( self , timeout = None ) :
    """API call to get a list of templates"""

implementation: return self . _api_request ( self . TEMPLATES_ENDPOINT , self . HTTP_GET , timeout = timeout )


signature:
def get_template ( self , template_id , version = None , timeout = None ) :
    """API call to get a specific template"""

implementation:
if ( version ) :
    return self . _api_request ( self . TEMPLATES_VERSION_ENDPOINT % ( template_id , version ) , self . HTTP_GET , timeout = timeout )
else :
    return self . _api_request ( self . TEMPLATES_SPECIFIC_ENDPOINT % template_id , self . HTTP_GET , timeout = timeout )


signature:
def create_email ( self , name , subject , html , text = '' ) :
    """[ DECPRECATED ] API call to create an email"""

implementation: return self . create_template ( name , subject , html , text )


signature:
def create_template ( self , name , subject , html , text = '' , timeout = None ) :
    """API call to create a template"""

implementation:
payload = { 'name' : name , 'subject' : subject , 'html' : html , 'text' : text }
return self . _api_request ( self . TEMPLATES_ENDPOINT , self . HTTP_POST , payload = payload , timeout = timeout )


signature:
def create_new_locale ( self , template_id , locale , version_name , subject , text = '' , html = '' , timeout = None ) :
    """API call to create a new locale and version of a template"""

implementation:
payload = { 'locale' : locale , 'name' : version_name , 'subject' : subject }
if html :
    payload [ 'html' ] = html
if text :
    payload [ 'text' ] = text
return self . _api_request ( self . TEMPLATES_LOCALES_ENDPOINT % template_id , self . HTTP_POST , payload = payload , timeout = timeout )