POP 17 Release

POP 17 introduces dynamic subs. These are useful when you want to organize your code into subs, but want to reference those subs in a programmable way.

How to use:

def __init__(hub):
    hub.pop.sub.dynamic(hub.my.sub, hub._.get_version)


def get_version(hub, *args, **kwargs):
    # logic based on args/kwargs I might expect to be passed to a function under my dynamic function
    # Such as a "ctx" parameter or based on an arg populated into hub.OPT
    return hub.my.sub["The actual reference to the sub I want to use"]

Examples

idem

With idem-cloud, you may want to keep exec modules for your api in subfolders associated with a specific api version. You might want to specify that version with “acct” and have it be part of “ctx” and not the path on the hub. Let’s say your code exists in ‘my_idem_project_base/exec/my_cloud/version/sub/plugin.py’. Normally you would access a function in that plugin with “hub.exec.my_cloud.version.sub.plugin.func()”. We can use a dynamic sub to allow that version sub to be determined by acct’s ctx

my_idem_project_base/exec/my_cloud/init.py

def __init__(hub):
    hub.exec.my_cloud.ACCT = ["my_cloud"]

    # The getter should probably always use *args and **kwargs
    # It is called with the same parameters that the resulting function is called with
    # This is so that the same ctx variable or hub passed to a called function can be used in the getter logic
    def _get_version_sub(ctx, *args, **kwargs):
        api_version = ctx.acct.get("api_version", "latest")
        return hub.exec.vmc[api_version]

    hub.pop.sub.dynamic(hub.exec.my_cloud, _get_version_sub)

acct_creds.yaml

my_cloud:
  api_version: latest

Now you can access “hub.exec.my_cloud.sub.plugin.func()” with a configured version sub for your cloud profile! references under hub.exec.my_cloud will be called relative to hub.exec.my_cloud.version instead.

opt

An example of using the hub to get a sub based on a value in hub.OPT

def __init__(hub):
    hub.pop.sub.dynamic(hub.my_sub, hub._.get_version)


def get_version(hub, *args, **kwargs):
    api_version = hub.OPT.my_sub.get("api_version", "latest")
    return hub.my_sub[api_version]