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
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])
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)
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)
def add_step(name, func): return orca.add_step(name, func)