Skip to main content
4 of 4
Correcting statements confusing keyblock with keyblock's driver.

I had to rely on an existing answer, but modify it as the formatting wasn't working for me.

import bpy

selected_obj = bpy.context.selected_objects
selected_obj.remove(bpy.context.active_object)

active_obj = bpy.context.active_object
shapekey_list_string = str(active_obj.data.shape_keys.key_blocks.keys()).lower()


for obj in selected_obj:
    for key in obj.data.shape_keys.key_blocks:
        if key.name.lower().lstrip(obj.name.lower()) in shapekey_list_string:
            if not key.name == "Basis":
                skey_driver = key.driver_add('value')
                skey_driver.driver.type = 'AVERAGE'
                if skey_driver.driver.variables:
                    for v in skey_driver.driver.variables:
                        skey_driver.driver.variables.remove(v)
                newVar = skey_driver.driver.variables.new()
                newVar.name = "value"
                newVar.type = 'SINGLE_PROP'
                newVar.targets[0].id_type = 'KEY'
                newVar.targets[0].id = active_obj.data.shape_keys
                newVar.targets[0].data_path = 'key_blocks["' + key.name.lstrip(obj.name.lower())+ '"].value'
                skey_driver.driver.type = 'AVERAGE'
                if skey_driver.driver.variables:
                    for v in skey_driver.driver.variables:
                        skey_driver.driver.variables.remove(v)
                newVar = skey_driver.driver.variables.new()
                newVar.name = "hide"
                newVar.type = 'SINGLE_PROP'
                newVar.targets[0].id_type = 'KEY'
                newVar.targets[0].id = active_obj.data.shape_keys
                newVar.targets[0].data_path = 'key_blocks["' + key.name.lstrip(obj.name.lower())+ '"].value'

The part that seems the hardest to research on API documentation alone is the argument following newVar. I'd like to contextualize that to help others not get as caught up as I had:

newVar = obj.data.shape_keys.key_blocks['Key'].driver_add.driver.variables.new()
newVar.name
newVar.type

.name and .type represent the variables of the driver being added. .type specifies either a single property (what we're using), a transform channel, rotational difference or distance.

Whereas, following that:

newVar.targets[0].id_type
newVar.targets[0].id
newVar.targets[0].data_path

These represent:

  1. 'KEY' used as input for the driver (As in "Key' or 'Key.001' in my sample question.)
  2. Source Object: bpy.data.objects['Source_Mesh'].data.shape_keys This represents the object containing the key in item 1.
  3. Data Path: This represents the exact name you would see were you to copy the shape key as driver and paste it into the "Path" field of the driver editor.

Specifically, not knowing the formatting of this argument, or understanding how the key, key's owner, and data path were separately defined, was what made this solution take hours to find, despite many similar questions being available.

original post used as basis for solution