<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def gpg_app_put_key( blockchain_id, appname, keyname, key_data, txid=None, immutable=False, proxy=None, wallet_keys=None, config_dir=None ):
 """ Put an application GPG key. Stash the private key locally to an app-specific keyring. If immutable is True, then store the data as an immutable entry (e.g. update the zonefile with the key hash) This is a time-consuming operation (on the order of an hour), and you will get back the transaction ID on a successful execution. It is up to you to wait until the transaction is confirmed before using the key. Otherwise, the key is stored to mutable storage. """


    assert is_valid_appname(appname)
    assert is_valid_keyname(keyname)

    try:
        keydir = make_gpg_home( appname, config_dir=config_dir )
        key_id = gpg_stash_key( appname, key_data, config_dir=config_dir, gpghome=keydir )
        assert key_id is not None, "Failed to stash key"
        log.debug("Stashed app key '%s:%s' (%s) under '%s'" % (appname, keyname, key_id, keydir))
    except Exception, e:
        log.exception(e)
        log.error("Failed to store GPG key '%s'" % keyname)
        return {'error': "Failed to store GPG key locally"}

    # get public key... 
    assert is_valid_appname(appname)
    try:
        pubkey_data = gpg_export_key( appname, key_id, config_dir=config_dir ) 
    except:
        return {'error': 'Failed to load key'}

    fq_key_name = "gpg.%s.%s" % (appname, keyname)
    key_url = None

    if not immutable:
        res = client.put_mutable( blockchain_id, fq_key_name, {fq_key_name: pubkey_data}, txid=txid, proxy=proxy, wallet_keys=wallet_keys )
        if 'error' in res:
            return res

        key_url = client.make_mutable_data_url( blockchain_id, fq_key_name, res['version'] )
    
    else:
        res = client.put_immutable( blockchain_id, fq_key_name, {fq_key_name: pubkey_data}, txid=txid, proxy=proxy, wallet_keys=wallet_keys )
        if 'error' in res:
            return res 

        key_url = client.make_immutable_data_url( blockchain_id, fq_key_name, res['immutable_data_hash'] )

    res['key_url'] = key_url
    res['key_data'] = pubkey_data
    res['key_id'] = gpg_key_fingerprint( pubkey_data, config_dir=config_dir )
    log.debug("Put key %s:%s (%s) to %s" % (appname, keyname, res['key_id'], key_url))
    return res