예제 #1
0
    def decorator(func):
        name = func.__name__

        logger.debug("inject step %s" % name)

        assert not _DECORATED_STEPS.get(name, False)
        _DECORATED_STEPS[name] = func

        orca.add_step(name, func)

        return func
예제 #2
0
def register(step, save_to_disk=True):
    """
    Register a model step with ModelManager and Orca. This includes saving it to disk,
    optionally, so it can be automatically loaded in the future.
    
    Registering a step will overwrite any previously loaded step with the same name. If a 
    name has not yet been assigned, one will be generated from the template name and a 
    timestamp.
    
    If the model step includes an attribute 'autorun' that's set to True, the step will 
    run after being registered.
    
    Parameters
    ----------
    step : object
    
    Returns
    -------
    None
    
    """
    # Currently supporting both step.name and step.meta.name
    if hasattr(step, 'meta'):
        # TO DO: move the name updating to CoreTemplateSettings?
        step.meta.name = update_name(step.meta.template, step.meta.name)
        name = step.meta.name
    
    else:
        step.name = update_name(step.template, step.name)
        name = step.name
    
    if save_to_disk:
        save_step_to_disk(step)
    
    print("Registering model step '{}'".format(name))
    
    _steps[name] = step
    
    # Create a callable that runs the model step, and register it with orca
    def run_step():
        return step.run()
        
    orca.add_step(name, run_step)
    
    if hasattr(step, 'meta'):
        if step.meta.autorun:
            orca.run([name])
    
    elif hasattr(step, 'autorun'):
        if step.autorun:
            orca.run([name]) 
예제 #3
0
def add_step(d):
    """
    Register a model step from a dictionary representation. This will override any 
    previously registered step with the same name. The step will be registered with Orca 
    and written to persistent storage.
    
    Parameters
    ----------
    d : dict
    
    """
    # TO DO - A long-term architecture issue here is that in order to create a class
    # object, we need to have already loaded the template definition. This is no problem
    # as long as all the templates are defined within `urbansim_templates`, because we can
    # import them manually. But how should we handle it when we have arbitrary templates
    # defined elsewhere? One approach would be to include the template location as an
    # attribute in the yaml, and then import the necessary classes using `eval()`. But
    # this opens us up to arbitrary code execution, which may not be very safe for a web
    # service. Another approach would be to require users to import all the templates
    # they'll be using, before importing `modelmanager`. Then we can look them up using
    # `globals()[class_name]`. Safer, but less convenient. Must be other solutions too.

    reserved_names = ['modelmanager_version']
    if (d['name'] in reserved_names):
        raise ValueError(
            'Step cannot be registered with ModelManager because "%s" is a reserved name'
            % (d['name']))

    if (d['name'] in _STEPS):
        remove_step(d['name'])

    _STEPS[d['name']] = d

    if (len(_STARTUP_QUEUE) == 0):
        save_steps_to_disk()

    # Create a callable that builds and runs the model step
    def run_step():
        return globals()[d['type']].from_dict(d).run()

    # Register it with Orca
    orca.add_step(d['name'], run_step)
예제 #4
0
def add_step(d, save_to_disk=True):
    """
    Register a model step from a dictionary representation. This will override any 
    previously registered step with the same name. The step will be registered with Orca 
    and (if save_to_disk==True) written to persistent storage.
    
    Note: This function is intended for internal use. In a model building workflow, it's 
    better to use an object's `register()` method to register it with ModelManager and 
    save it to disk at the same time.
    
    Parameters
    ----------
    d : dict
    save_to_disk : bool
    
    """
    # TO DO - A long-term architecture issue here is that in order to create a class
    # object, we need to have already loaded the template definition. This is no problem
    # as long as all the templates are defined within `urbansim_templates`, because we can 
    # import them manually. But how should we handle it when we have arbitrary templates 
    # defined elsewhere? One approach would be to include the template location as an 
    # attribute in the yaml, and then import the necessary classes using `eval()`. But 
    # this opens us up to arbitrary code execution, which may not be very safe for a web 
    # service. Another approach would be to require users to import all the templates
    # they'll be using, before importing `modelmanager`. Then we can look them up using
    # `globals()[class_name]`. Safer, but less convenient. Must be other solutions too.
    
    if save_to_disk:
        save_step(d)
    
    print("Loading model step '{}'".format(d['name']))
    
    _STEPS[d['name']] = d
    
    # Create a callable that builds and runs the model step
    def run_step():
        return globals()[d['type']].from_dict(d).run()
        
    # Register it with Orca
    orca.add_step(d['name'], run_step)
예제 #5
0
def add_step(name, func):
    return orca.add_step(name, func)