Instruction:
Can you create a Python 3 function that
creates revocation registry artifacts and new tails file.

Response:
async def create_rev_reg(self, rr_id: str, rr_size: int = None) -> None:
        """
        Create revocation registry artifacts and new tails file (with association to
        corresponding revocation registry identifier via symbolic link name)
        for input revocation registry identifier. Symbolic link presence signals completion.
        If revocation registry builder operates in a process external to its Issuer's,
        target directory is hopper directory.

        Raise WalletState for closed wallet.

        :param rr_id: revocation registry identifier
        :param rr_size: revocation registry size (defaults to 64)
        """

        LOGGER.debug('RevRegBuilder.create_rev_reg >>> rr_id: %s, rr_size: %s', rr_id, rr_size)

        if not self.wallet.handle:
            LOGGER.debug('RevRegBuilder.create_rev_reg <!< Wallet %s is closed', self.name)
            raise WalletState('Wallet {} is closed'.format(self.name))

        if not ok_rev_reg_id(rr_id):
            LOGGER.debug('RevRegBuilder.create_rev_reg <!< Bad rev reg id %s', rr_id)
            raise BadIdentifier('Bad rev reg id {}'.format(rr_id))

        rr_size = rr_size or 64

        (cd_id, tag) = rev_reg_id2cred_def_id_tag(rr_id)

        dir_tails = self.dir_tails_top(rr_id)
        dir_target = self.dir_tails_target(rr_id)
        if self.external:
            try:
                makedirs(dir_target, exist_ok=False)
            except FileExistsError:
                LOGGER.warning(
                    'RevRegBuilder.create_rev_reg found dir %s, but task not in progress: rebuilding rev reg %s',
                    dir_target,
                    rr_id)
                rmtree(dir_target)
                makedirs(dir_target, exist_ok=False)

        LOGGER.info('Creating revocation registry (capacity %s) for rev reg id %s', rr_size, rr_id)
        tails_writer_handle = await blob_storage.open_writer(
            'default',
            json.dumps({
                'base_dir': dir_target,
                'uri_pattern': ''
            }))

        (created_rr_id, rr_def_json, rr_ent_json) = await anoncreds.issuer_create_and_store_revoc_reg(
            self.wallet.handle,
            self.did,
            'CL_ACCUM',
            tag,
            cd_id,
            json.dumps({
                'max_cred_num': rr_size,
                'issuance_type': 'ISSUANCE_BY_DEFAULT'
            }),
            tails_writer_handle)

        tails_hash = basename(Tails.unlinked(dir_target).pop())
        with open(join(dir_target, 'rr_def.json'), 'w') as rr_def_fh:
            print(rr_def_json, file=rr_def_fh)
        with open(join(dir_target, 'rr_ent.json'), 'w') as rr_ent_fh:
            print(rr_ent_json, file=rr_ent_fh)
        Tails.associate(dir_tails, created_rr_id, tails_hash)  # associate last: symlink signals completion

        LOGGER.debug('RevRegBuilder.create_rev_reg <<<')


Instruction:
Can you create a Python 3 function that
bases on Django s default cache template tag

Response:
def do_ultracache(parser, token):
    """Based on Django's default cache template tag"""
    nodelist = parser.parse(("endultracache",))
    parser.delete_first_token()
    tokens = token.split_contents()
    if len(tokens) < 3:
        raise TemplateSyntaxError(""%r" tag requires at least 2 arguments." % tokens[0])
    return UltraCacheNode(nodelist,
        parser.compile_filter(tokens[1]),
        tokens[2], # fragment_name can"t be a variable.
        [parser.compile_filter(token) for token in tokens[3:]])


Instruction:
Make a summary of the following Python 3 code
def ppjson(dumpit: Any, elide_to: int = None) -> str:

    if elide_to is not None:
        elide_to = max(elide_to, 3) # make room for ellipses '...'
    try:
        rv = json.dumps(json.loads(dumpit) if isinstance(dumpit, str) else dumpit, indent=4)
    except TypeError:
        rv = '{}'.format(pformat(dumpit, indent=4, width=120))
    return rv if elide_to is None or len(rv) <= elide_to else '{}...'.format(rv[0 : elide_to - 3])

Response: Pretty - print a node s hierarchy in json format.


Instruction:
How would you code a function in Python 3 to
perform a synchronous operation ; await then return the result.

Response:
def do_wait(coro: Callable) -> Any:
    """
    Perform aynchronous operation; await then return the result.

    :param coro: coroutine to await
    :return: coroutine result
    """

    event_loop = None
    try:
        event_loop = asyncio.get_event_loop()
    except RuntimeError:
        event_loop = asyncio.new_event_loop()
        asyncio.set_event_loop(event_loop)
    return event_loop.run_until_complete(coro)


Instruction:
How would you code a function in Python 3 to
take one or more ini files and return a dict with configuration from all. ini files.

Response:
def inis2dict(ini_paths: Union[str, Sequence[str]]) -> dict:
    """
    Take one or more ini files and return a dict with configuration from all,
    interpolating bash-style variables ${VAR} or ${VAR:-DEFAULT}.

    :param ini_paths: path or paths to .ini files
    """

    var_dflt = r'\${(.*?):-(.*?)}'
    def _interpolate(content):
        rv = expandvars(content)
        while True:
            match = re.search(var_dflt, rv)
            if match is None:
                break
            bash_var = '${{{}}}'.format(match.group(1))
            value = expandvars(bash_var)
            rv = re.sub(var_dflt, match.group(2) if value == bash_var else value, rv, count=1)

        return rv

    parser = ConfigParser()

    for ini in [ini_paths] if isinstance(ini_paths, str) else ini_paths:
        if not isfile(ini):
            raise FileNotFoundError('No such file: {}'.format(ini))
        with open(ini, 'r') as ini_fh:
            ini_text = _interpolate(ini_fh.read())
            parser.read_string(ini_text)

    return {s: dict(parser[s].items()) for s in parser.sections()}


Instruction:
Here you have a function in Python 3, explain what it does
def mark(self, digits: int = None) -> float:

        self._mark[:] = [self._mark[1], time()]
        rv = self._mark[1] - self._mark[0]

        if digits is not None and digits > 0:
            rv = round(rv, digits)
        elif digits == 0 or self._digits == 0:
            rv = int(rv)
        elif self._digits is not None and self._digits > 0:
            rv = round(rv, self._digits)

        return rv

Response: Return time in seconds since last mark reset or construction.


Instruction:
Write a Python 3 function that can
begin the search operation.

Response:
async def open(self) -> None:
        """
        Begin the search operation.
        """

        LOGGER.debug('StorageRecordSearch.open >>>')

        if self.opened:
            LOGGER.debug('StorageRecordSearch.open <!< Search is already opened')
            raise BadSearch('Search is already opened')

        if not self._wallet.opened:
            LOGGER.debug('StorageRecordSearch.open <!< Wallet %s is closed', self._wallet.name)
            raise WalletState('Wallet {} is closed'.format(self._wallet.name))

        self._handle = await non_secrets.open_wallet_search(
            self._wallet.handle,
            self._type,
            self._query_json,
            StorageRecordSearch.OPTIONS_JSON)

        LOGGER.debug('StorageRecordSearch.open <<<')


Instruction:
Write a Python 3 script for
returning archivable cache identifier for this pool.

Response:
def cache_id(self) -> str:
        """
        Return identifier for archivable caches, computing it first and retaining it if need be.
        Raise AbsentPool if ledger configuration is not yet available.

        :param name: pool name
        :return: archivable cache identifier
        """

        if self._cache_id:
            return self._cache_id

        with open(join(expanduser('~'), '.indy_client', 'pool', self.name, '{}.txn'.format(self.name))) as fh_genesis:
            genesis = [json.loads(line) for line in fh_genesis.readlines() if line]

        hps = []
        for gen_txn in genesis:
            hps.append(self.protocol.genesis_host_port(gen_txn))
        hps.sort()  # canonicalize to make order irrelevant
        self._cache_id = ':'.join('{}:{}'.format(hp[0], hp[1]) for hp in hps)

        return self._cache_id


Instruction:
How would you code a function in Python 3 to
open pool with given configuration.

Response:
async def open(self) -> 'NodePool':
        """
        Explicit entry. Opens pool as configured, for later closure via close().
        Creates pool if it does not yet exist, using configured genesis transaction file.
        For use when keeping pool open across multiple calls.

        Raise any AbsentPool if node pool ledger configuration is not available.

        :return: current object
        """

        LOGGER.debug('NodePool.open >>>')

        await pool.set_protocol_version(self.protocol.indy())
        LOGGER.info('Pool ledger %s set protocol %s', self.name, self.protocol)

        try:
            self._handle = await pool.open_pool_ledger(self.name, json.dumps(self.config))
        except IndyError as x_indy:
            if x_indy.error_code == ErrorCode.PoolLedgerNotCreatedError:
                LOGGER.debug('NodePool.open <!< Absent node pool %s ledger configuration', self.name)
                raise AbsentPool('Absent node pool {} ledger configuration'.format(self.name))
            LOGGER.debug(
                'NodePool.open <!< cannot open node pool %s: indy error code %s',
                self.name,
                x_indy.error_code)
            raise

        LOGGER.debug('NodePool.open <<<')
        return self


Instruction:
Given the following Python 3 function, write the documentation
async def close(self) -> None:

        LOGGER.debug('NodePool.close >>>')

        if not self.handle:
            LOGGER.warning('Abstaining from closing pool %s: already closed', self.name)
        else:
            await pool.close_pool_ledger(self.handle)
        self._handle = None

        LOGGER.debug('NodePool.close <<<')

Response: Explicit exit. Closes pool. For use when keeping pool open across multiple calls.


Instruction:
How would you implement a function in Python 3 that
refreshes local copy of pool ledger and update node pool connections.

Response:
async def refresh(self) -> None:
        """
        Refresh local copy of pool ledger and update node pool connections.
        """

        LOGGER.debug('NodePool.refresh >>>')

        await pool.refresh_pool_ledger(self.handle)

        LOGGER.debug('NodePool.refresh <<<')


Instruction:
Make a summary of the following Python 3 code
async def reseed(self, seed: str = None) -> None:

        LOGGER.debug('BaseAnchor.reseed >>> seed: [SEED]')

        verkey = await self.wallet.reseed_init(seed)
        req_json = await ledger.build_nym_request(
            self.did,
            self.did,
            verkey,
            self.name,
            (await self.get_nym_role()).token())
        await self._sign_submit(req_json)
        await self.wallet.reseed_apply()

        LOGGER.debug('BaseAnchor.reseed <<<')

Response: Reseed the current key pair.


Instruction:
Implement a function in Python 3 to
get json cryptonym for input ( anchor ) DID.

Response:
async def get_nym(self, target_did: str = None) -> str:
        """
        Get json cryptonym (including current verification key) for input (anchor) DID from ledger.
        Return empty production {} if the ledger has no such cryptonym.

        Raise BadLedgerTxn on failure. Raise WalletState if target DID is default (own DID) value but
        wallet does not have it (neither created nor opened since initialization).

        :param target_did: DID of cryptonym to fetch (default own DID)
        :return: cryptonym json
        """

        LOGGER.debug('BaseAnchor.get_nym >>> target_did: %s', target_did)

        if target_did and not ok_did(target_did):
            LOGGER.debug('BaseAnchor.get_nym <!< Bad DID %s', target_did)
            raise BadIdentifier('Bad DID {}'.format(target_did))

        if not (target_did or self.did):
            LOGGER.debug('BaseAnchor.get_nym <!< Bad wallet state: DID for %s unavailable', self.name)
            raise WalletState('Bad wallet state: DID for {} unavailable'.format(self.name))

        rv = json.dumps({})
        get_nym_req = await ledger.build_get_nym_request(self.did, target_did or self.did)
        resp_json = await self._submit(get_nym_req)

        data_json = (json.loads(resp_json))['result']['data']  # it's double-encoded on the ledger
        if data_json:
            rv = data_json

        LOGGER.debug('BaseAnchor.get_nym <<< %s', rv)
        return rv


Instruction:
Can you tell what is the following Python 3 function doing
async def get_nym_role(self, target_did: str = None) -> Role:

        LOGGER.debug('BaseAnchor.get_nym_role >>> target_did: %s', target_did)

        nym = json.loads(await self.get_nym(target_did))
        if not nym:
            LOGGER.debug('BaseAnchor.get_nym_role <!< Ledger has no cryptonym for anchor %s', self.name)
            raise AbsentNym('Ledger has no cryptonym for anchor {}'.format(self.name))

        rv = Role.get(nym['role'])

        LOGGER.debug('BaseAnchor.get_nym_role <<< %s', rv)
        return rv

Response: Get the cryptonym role for the input did.


Instruction:
Make a summary of the following Python 3 code
def least_role() -> Role:

        LOGGER.debug('BaseAnchor.least_role >>>')

        rv = Role.TRUST_ANCHOR

        LOGGER.debug('BaseAnchor.least_role <<< %s', rv)
        return rv

Response: Return the indy - sdk role of the least privilege for an anchor class in building


Instruction:
Given the following Python 3 function, write the documentation
async def set_did_endpoint(self, remote_did: str, did_endpoint: str) ->  EndpointInfo:

        LOGGER.debug('BaseAnchor.set_did_endpoint >>> remote_did: %s, did_endpoint: %s', remote_did, did_endpoint)

        if not ok_did(remote_did):
            LOGGER.debug('BaseAnchor.set_did_endpoint <!< Bad DID %s', remote_did)
            raise BadIdentifier('Bad DID {}'.format(remote_did))

        pairwise_info = (await self.wallet.get_pairwise(remote_did)).get(remote_did, None)
        if not pairwise_info:
            LOGGER.debug(
                'BaseAnchor.set_did_endpoint <!< Anchor %s has no pairwise relation for remote DID %s',
                self.name,
                remote_did)
            raise AbsentRecord('Anchor {} has no pairwise relation for remote DID {}'.format(
                self.name,
                remote_did))

        await self.wallet.write_pairwise(
            pairwise_info.their_did,
            pairwise_info.their_verkey,
            pairwise_info.my_did,
            {'did_endpoint': did_endpoint})

        rv = EndpointInfo(did_endpoint, pairwise_info.their_verkey)

        LOGGER.debug('BaseAnchor.set_did_endpoint <<< %s', rv)
        return rv

Response: Set endpoint for remote DID in wallet and return it.


Instruction:
Can you generate the documentation for the following Python 3 function
async def send_endpoint(self, endpoint: str) -> None:

        LOGGER.debug('BaseAnchor.send_endpoint >>> endpoint: %s', endpoint)

        ledger_endpoint = await self.get_endpoint()
        if ledger_endpoint == endpoint:
            LOGGER.info('%s endpoint already set as %s', self.name, endpoint)
            LOGGER.debug('BaseAnchor.send_endpoint <<< (%s already set for %s )')
            return

        attr_json = json.dumps({
            'endpoint': {
                'endpoint': endpoint  # indy-sdk likes 'ha' here but won't map 'ha' to a URL, only ip:port
            }
        })
        req_json = await ledger.build_attrib_request(self.did, self.did, None, attr_json, None)
        await self._sign_submit(req_json)

        for _ in range(16):  # reasonable timeout
            if await self.get_endpoint(None, False) == endpoint:
                break
            await asyncio.sleep(1)
            LOGGER.info('Sent endpoint %s to ledger, waiting 1s for its confirmation', endpoint)
        else:
            LOGGER.debug('BaseAnchor.send_endpoint <!< timed out waiting on send endpoint %s', endpoint)
            raise BadLedgerTxn('Timed out waiting on sent endpoint {}'.format(endpoint))

        LOGGER.debug('BaseAnchor.send_endpoint <<<')

Response: Send endpoint to ledger and return local cache entry.


Instruction:
Can you generate a brief explanation for the following Python 3 code
async def get_endpoint(self, target_did: str = None, from_cache: bool = True) -> str:

        LOGGER.debug('BaseAnchor.get_endpoint >>> target_did: %s, from_cache: %s', target_did, from_cache)

        rv = None

        if not (target_did or self.did):
            LOGGER.debug('BaseAnchor.get_endpoint <!< Bad wallet state: DID for %s unavailable', self.name)
            raise WalletState('Bad wallet state: DID for {} unavailable'.format(self.name))

        target_did = target_did or self.did
        if not ok_did(target_did):
            LOGGER.debug('BaseAnchor.get_endpoint <!< Bad DID %s', target_did)
            raise BadIdentifier('Bad DID {}'.format(target_did))

        if from_cache:
            with ENDPOINT_CACHE.lock:
                if target_did in ENDPOINT_CACHE:
                    LOGGER.info('BaseAnchor.get_endpoint: got endpoint for %s from cache', target_did)
                    rv = ENDPOINT_CACHE[target_did]
                    LOGGER.debug('BaseAnchor.get_endpoint <<< %s', rv)
                    return rv

        req_json = await ledger.build_get_attrib_request(
            self.did,
            target_did,
            'endpoint',
            None,
            None)
        resp_json = await self._submit(req_json)

        data_json = (json.loads(resp_json))['result']['data']  # it's double-encoded on the ledger
        if data_json:
            rv = json.loads(data_json)['endpoint'].get('endpoint', None)
        else:
            LOGGER.info('_AgentCore.get_endpoint: ledger query returned response with no data')

        with ENDPOINT_CACHE.lock:
            if rv:
                ENDPOINT_CACHE[target_did] = rv
            else:
                ENDPOINT_CACHE.pop(target_did, None)
                assert target_did not in ENDPOINT_CACHE

        LOGGER.debug('BaseAnchor.get_endpoint <<< %s', rv)
        return rv

Response: Get endpoint attribute for target DID.


Instruction:
Create a Python 3 function for
retrieving a verification key for a target DID.

Response:
async def _verkey_for(self, target: str) -> str:
        """
        Given a DID, retrieve its verification key, looking in wallet, then pool.
        Given a verification key or None, return input.

        Raise WalletState if the wallet is closed. Given a recipient DID not in the wallet,
        raise AbsentPool if the instance has no pool or ClosedPool if its pool is closed.
        If no such verification key is on the ledger, raise AbsentNym.

        :param target: verification key, or DID to resolve to such
        :return: verification key
        """

        LOGGER.debug('BaseAnchor._verkey_for >>> target: %s', target)

        rv = target
        if rv is None or not ok_did(rv):  # it's None or already a verification key
            LOGGER.debug('BaseAnchor._verkey_for <<< %s', rv)
            return rv

        if self.wallet.handle:
            try:
                rv = await did.key_for_local_did(self.wallet.handle, target)
                LOGGER.info('Anchor %s got verkey for DID %s from wallet', self.name, target)
                LOGGER.debug('BaseAnchor._verkey_for <<< %s', rv)
                return rv
            except IndyError as x_indy:
                if x_indy.error_code != ErrorCode.WalletItemNotFound:  # on not found, try the pool
                    LOGGER.debug(
                        'BaseAnchor._verkey_for <!< key lookup for local DID %s raised indy error code %s',
                        target,
                        x_indy.error_code)
                    raise

        nym = json.loads(await self.get_nym(target))
        if not nym:
            LOGGER.debug(
                'BaseAnchor._verkey_for <!< Wallet %s closed and ledger has no cryptonym for DID %s',
                self.name,
                target)
            raise AbsentNym('Wallet {} closed, and ledger has no cryptonym for DID {}'.format(self.name, target))

        rv = json.loads(await self.get_nym(target))['verkey']
        LOGGER.info('Anchor %s got verkey for DID %s from pool %s', self.name, target, self.pool.name)

        LOGGER.debug('BaseAnchor._verkey_for <<< %s', rv)
        return rv


Instruction:
How would you code a function in Python 3 to
encrypt plaintext for owner of DID or verification key.

Response:
async def encrypt(self, message: bytes, authn: bool = False, recip: str = None) -> bytes:
        """
        Encrypt plaintext for owner of DID or verification key, anonymously or via
        authenticated encryption scheme. If given DID, first check wallet and then pool
        for corresponding verification key.

        Raise WalletState if the wallet is closed. Given a recipient DID not in the wallet,
        raise AbsentPool if the instance has no pool or ClosedPool if its pool is closed.

        :param message: plaintext, as bytes
        :param authn: whether to use authenticated encryption scheme
        :param recip: DID or verification key of recipient, None for anchor's own
        :return: ciphertext, as bytes
        """

        LOGGER.debug('BaseAnchor.encrypt >>> message: %s, authn: %s, recip: %s', message, authn, recip)

        if not self.wallet.handle:
            LOGGER.debug('BaseAnchor.encrypt <!< Wallet %s is closed', self.name)
            raise WalletState('Wallet {} is closed'.format(self.name))

        rv = await self.wallet.encrypt(message, authn, await self._verkey_for(recip))

        LOGGER.debug('BaseAnchor.auth_encrypt <<< %s', rv)
        return rv


Instruction:
How would you explain what the following Python 3 function does
async def verify(self, message: bytes, signature: bytes, signer: str = None) -> bool:

        LOGGER.debug('BaseAnchor.verify >>> signer: %s, message: %s, signature: %s', signer, message, signature)

        if not self.wallet.handle:
            LOGGER.debug('BaseAnchor.verify <!< Wallet %s is closed', self.name)
            raise WalletState('Wallet {} is closed'.format(self.name))

        verkey = None
        if signer:
            verkey = await self._verkey_for(signer)
        rv = await self.wallet.verify(message, signature, verkey)

        LOGGER.debug('BaseAnchor.verify <<< %s', rv)
        return rv

Response: Verify signature with input signer verification key.


Instruction:
Can you create a Python 3 function that
finds a transaction on the distributed ledger by its sequence number.

Response:
async def get_txn(self, seq_no: int) -> str:
        """
        Find a transaction on the distributed ledger by its sequence number.

        :param seq_no: transaction number
        :return: json sequence number of transaction, null for no match
        """

        LOGGER.debug('BaseAnchor.get_txn >>> seq_no: %s', seq_no)

        rv_json = json.dumps({})
        req_json = await ledger.build_get_txn_request(self.did, None, seq_no)
        resp = json.loads(await self._submit(req_json))

        rv_json = self.pool.protocol.txn2data(resp)

        LOGGER.debug('BaseAnchor.get_txn <<< %s', rv_json)
        return rv_json


Instruction:
Can you generate the documentation for the following Python 3 function
def to_dict(self):

        rv = {
            'id': self.id,
            'type': self.type,
            'priority': self.priority
        }
        if self.recip_keys:
            rv['routingKeys'] = [canon_ref(k.did, k.id, '#') for k in  self.recip_keys]
        if self.routing_keys:
            rv['routingKeys'] = [canon_ref(k.did, k.id, '#') for k in self.routing_keys]
        rv['serviceEndpoint'] = self.endpoint

        return rv

Response: Return dict representation of a resource in DID document.


Instruction:
Write a Python 3 function that can
synchronize revocation registry identifier with tails file.

Response:
async def _sync_revoc_for_proof(self, rr_id: str) -> None:
        """
        Pick up tails file reader handle for input revocation registry identifier.  If no symbolic
        link is present, get the revocation registry definition to retrieve its tails file hash,
        then find the tails file and link it.

        Raise AbsentTails for missing corresponding tails file.

        :param rr_id: revocation registry identifier
        """

        LOGGER.debug('HolderProver._sync_revoc_for_proof >>> rr_id: %s', rr_id)

        if not ok_rev_reg_id(rr_id):
            LOGGER.debug('HolderProver._sync_revoc_for_proof <!< Bad rev reg id %s', rr_id)
            raise BadIdentifier('Bad rev reg id {}'.format(rr_id))

        (cd_id, tag) = rev_reg_id2cred_def_id_tag(rr_id)

        try:
            json.loads(await self.get_cred_def(cd_id))
        except AbsentCredDef:
            LOGGER.debug(
                'HolderProver._sync_revoc_for_proof <!< corrupt tails tree %s may be for another ledger',
                self._dir_tails)
            raise AbsentCredDef('Corrupt tails tree {} may be for another ledger'.format(self._dir_tails))
        except ClosedPool:
            pass  # carry on, may be OK from cache only

        with REVO_CACHE.lock:
            revo_cache_entry = REVO_CACHE.get(rr_id, None)
            tails = revo_cache_entry.tails if revo_cache_entry else None
            if tails is None:  #  it's not yet set in cache
                try:
                    tails = await Tails(self._dir_tails, cd_id, tag).open()
                except AbsentTails:  # get hash from ledger and check for tails file
                    rr_def = json.loads(await self.get_rev_reg_def(rr_id))
                    tails_hash = rr_def['value']['tailsHash']
                    path_tails = join(Tails.dir(self._dir_tails, rr_id), tails_hash)
                    if not isfile(path_tails):
                        LOGGER.debug('HolderProver._sync_revoc_for_proof <!< No tails file present at %s', path_tails)
                        raise AbsentTails('No tails file present at {}'.format(path_tails))
                    Tails.associate(self._dir_tails, rr_id, tails_hash)
                    tails = await Tails(self._dir_tails, cd_id, tag).open()  # OK now since tails file present

                if revo_cache_entry is None:
                    REVO_CACHE[rr_id] = RevoCacheEntry(None, tails)
                else:
                    REVO_CACHE[rr_id].tails = tails

        LOGGER.debug('HolderProver._sync_revoc_for_proof <<<')


Instruction:
How would you explain what the following Python 3 function does
def dir_tails(self, rr_id: str) -> str:

        LOGGER.debug('HolderProver.dir_tails >>>')

        if not ok_rev_reg_id(rr_id):
            LOGGER.debug('HolderProver.dir_tails <!< Bad rev reg id %s', rr_id)
            raise BadIdentifier('Bad rev reg id {}'.format(rr_id))

        rv = Tails.dir(self._dir_tails, rr_id)
        LOGGER.debug('HolderProver.dir_tails <<< %s', rv)
        return rv

Response: Return path to the correct directory for the tails file on input revocation registry identifier.


Instruction:
Here you have a function in Python 3, explain what it does
async def open(self) -> 'HolderProver':

        LOGGER.debug('HolderProver.open >>>')

        await super().open()
        if self.config.get('parse-caches-on-open', False):
            ArchivableCaches.parse(self.dir_cache)

        for path_rr_id in Tails.links(self._dir_tails):
            await self._sync_revoc_for_proof(basename(path_rr_id))

        LOGGER.debug('HolderProver.open <<<')
        return self

Response:
Explicit entry. Perform ancestor opening operations,
        then parse cache from archive if so configured, and
        synchronize revocation registry to tails tree content.

        :return: current object


Instruction:
Here you have a function in Python 3, explain what it does
async def close(self) -> None:

        LOGGER.debug('HolderProver.close >>>')

        if self.config.get('archive-holder-prover-caches-on-close', False):
            await self.load_cache_for_proof(True)
            ArchivableCaches.purge_archives(self.dir_cache, True)

        await BaseAnchor.close(self)
        for path_rr_id in Tails.links(self._dir_tails):
            rr_id = basename(path_rr_id)
            try:
                await self._sync_revoc_for_proof(rr_id)
            except ClosedPool:
                LOGGER.warning('HolderProver sync-revoc on close required ledger for %s but pool was closed', rr_id)

        LOGGER.debug('HolderProver.close <<<')

Response: Close the HolderProver instance.


Instruction:
How would you explain what the following Python 3 function does
async def rev_regs(self) -> list:

        LOGGER.debug('HolderProver.rev_regs >>>')

        for path_rr_id in Tails.links(self._dir_tails):
            await self._sync_revoc_for_proof(basename(path_rr_id))

        rv = [basename(f) for f in Tails.links(self._dir_tails)]
        LOGGER.debug('HolderProver.rev_regs <<< %s', rv)
        return rv

Response: Return list of revocation registry identifiers for which HolderProver has associated tails files.


Instruction:
Can you tell what is the following Python 3 function doing
async def offline_intervals(self, cd_ids: Union[str, Sequence[str]]) -> dict:

        LOGGER.debug('HolderProver.offline_intervals >>> cd_ids: %s', cd_ids)

        rv = {}
        for cd_id in [cd_ids] if isinstance(cd_ids, str) else cd_ids:
            if not ok_cred_def_id(cd_id):
                LOGGER.debug('HolderProver.offline_intervals <!< Bad cred def id %s', cd_id)
                raise BadIdentifier('Bad cred def id {}'.format(cd_id))

            try:
                cred_def = json.loads(await self.get_cred_def(cd_id))
            except ClosedPool:
                LOGGER.debug('HolderProver.offline_intervals <!< no such cred def %s in cred def cache', cd_id)
                raise CacheIndex('No cached delta for non-revoc interval on {}'.format(cd_id))

            rv[cd_id] = {}
            if 'revocation' in cred_def['value']:
                with REVO_CACHE.lock:
                    (fro, to) = REVO_CACHE.dflt_interval(cd_id)
                    if not (fro and to):
                        LOGGER.debug(
                            'HolderProver.offline_intervals <!< no cached delta for non-revoc interval on %s',
                            cd_id)
                        raise CacheIndex('No cached delta for non-revoc interval on {}'.format(cd_id))

                    rv[cd_id]['interval'] = to if fro == to else (fro, to)

        LOGGER.debug('HolderProver.offline_intervals <<< %s', rv)
        return rv

Response: Return default non - revocation intervals for input cred def ids.


Instruction:
Write a Python 3 script for
creating link secret in wallet.

Response:
async def create_link_secret(self, label: str) -> None:
        """
        Create link secret (a.k.a. master secret) used in proofs by HolderProver, if the
        current link secret does not already correspond to the input link secret label.

        Raise WalletState if wallet is closed, or any other IndyError causing failure
        to set link secret in wallet.

        :param label: label for link secret; indy-sdk uses label to generate link secret
        """

        LOGGER.debug('HolderProver.create_link_secret >>> label: %s', label)

        await self.wallet.create_link_secret(label)

        LOGGER.debug('HolderProver.create_link_secret <<<')


Instruction:
Write a Python 3 function that can
store credential in wallet as HolderProver.

Response:
async def store_cred(self, cred_json: str, cred_req_metadata_json: str) -> str:
        """
        Store cred in wallet as HolderProver, return its credential identifier as created in wallet.

        Raise AbsentTails if tails file not available for revocation registry for input credential.
        Raise WalletState if wallet is closed.

        :param cred_json: credential json as HolderProver created
        :param cred_req_metadata_json: credential request metadata json as HolderProver created via create_cred_req()
        :return: credential identifier within wallet
        """

        LOGGER.debug(
            'HolderProver.store_cred >>> cred_json: %s, cred_req_metadata_json: %s',
            cred_json,
            cred_req_metadata_json)

        if not self.wallet.handle:
            LOGGER.debug('HolderProver.store_cred <!< Wallet %s is closed', self.name)
            raise WalletState('Wallet {} is closed'.format(self.name))

        cred = json.loads(cred_json)
        cred_def_json = await self.get_cred_def(cred['cred_def_id'])
        rr_id = cred['rev_reg_id']
        rr_def_json = None
        if rr_id:
            await self._sync_revoc_for_proof(rr_id)
            rr_def_json = await self.get_rev_reg_def(rr_id)

        rv = await anoncreds.prover_store_credential(
            self.wallet.handle,
            None,  # cred_id, let indy-sdk generate random uuid
            cred_req_metadata_json,
            cred_json,
            cred_def_json,
            rr_def_json)

        LOGGER.debug('HolderProver.store_cred <<< %s', rv)
        return rv


Instruction:
Can you generate a brief explanation for the following Python 3 code
async def load_cache_for_proof(self, archive: bool = False) -> int:

        LOGGER.debug('HolderProver.load_cache_for_proof >>> archive: %s', archive)

        rv = int(time())
        box_ids = json.loads(await self.get_box_ids_held())
        for s_id in box_ids['schema_id']:
            with SCHEMA_CACHE.lock:
                await self.get_schema(s_id)
        for cd_id in box_ids['cred_def_id']:
            with CRED_DEF_CACHE.lock:
                await self.get_cred_def(cd_id)
        for rr_id in box_ids['rev_reg_id']:
            await self.get_rev_reg_def(rr_id)
            with REVO_CACHE.lock:
                revo_cache_entry = REVO_CACHE.get(rr_id, None)
                if revo_cache_entry:
                    try:
                        await revo_cache_entry.get_delta_json(self._build_rr_delta_json, rv, rv)
                    except ClosedPool:
                        LOGGER.warning(
                            'HolderProver %s is offline from pool %s, cannot update revo cache reg delta for %s to %s',
                            self.name,
                            self.pool.name,
                            rr_id,
                            rv)
                    except AbsentPool:
                        LOGGER.warning(
                            'HolderProver %s has no pool, cannot update revo cache reg delta for %s to %s',
                            self.name,
                            rr_id,
                            rv)

        if archive:
            ArchivableCaches.archive(self.dir_cache)
        LOGGER.debug('HolderProver.load_cache_for_proof <<< %s', rv)
        return rv

Response: Load schema cred def revocation cache and revocation cache delta for proof on all credentials in wallet.


Instruction:
Explain what the following Python 3 code does
async def get_box_ids_held(self) -> str:

        LOGGER.debug('HolderProver.get_box_ids_held >>>')

        if not self.wallet.handle:
            LOGGER.debug('HolderProver.get_box_ids_held <!< Wallet %s is closed', self.name)
            raise WalletState('Wallet {} is closed'.format(self.name))

        rr_ids = {basename(link) for link in Tails.links(self._dir_tails)}

        un_rr_ids = set()
        for rr_id in rr_ids:
            if not json.loads(await self.get_cred_infos_by_q(json.dumps({'rev_reg_id': rr_id}), 1)):
                un_rr_ids.add(rr_id)
        rr_ids -= un_rr_ids

        cd_ids = {cd_id for cd_id in listdir(self._dir_tails)
            if isdir(join(self._dir_tails, cd_id)) and ok_cred_def_id(cd_id)}
        s_ids = set()
        for cd_id in cd_ids:
            s_ids.add(json.loads(await self.get_schema(cred_def_id2seq_no(cd_id)))['id'])

        un_cd_ids = set()
        for cd_id in cd_ids:
            if not json.loads(await self.get_cred_infos_by_q(json.dumps({'cred_def_id': cd_id}), 1)):
                un_cd_ids.add(cd_id)
        cd_ids -= un_cd_ids

        un_s_ids = set()
        for s_id in s_ids:
            if not json.loads(await self.get_cred_infos_by_q(json.dumps({'schema_id': s_id}), 1)):
                un_s_ids.add(s_id)
        s_ids -= un_s_ids

        rv = json.dumps({
            'schema_id': list(s_ids),
            'cred_def_id': list(cd_ids),
            'rev_reg_id': list(rr_ids)
        })
        LOGGER.debug('HolderProver.get_box_ids_held <<< %s', rv)
        return rv

Response: Get all unique box identifiers for credentials in wallet.


Instruction:
How would you explain what the following Python 3 function does
async def get_cred_infos_by_q(self, query_json: str, limit: int = None) -> str:

        LOGGER.debug('HolderProver.get_cred_infos_by_q >>> query_json: %s, limit: %s', query_json, limit)

        if not self.wallet.handle:
            LOGGER.debug('HolderProver.get_cred_infos_by_q <!< Wallet %s is closed', self.name)
            raise WalletState('Wallet {} is closed'.format(self.name))

        infos = []
        if limit and limit < 0:
            limit = None

        (handle, cardinality) = await anoncreds.prover_search_credentials(
            self.wallet.handle,
            json.dumps(canon_cred_wql(json.loads(query_json))))  # indy-sdk requires attr name canonicalization
        chunk = min(cardinality, limit or cardinality, Wallet.DEFAULT_CHUNK)
        if limit:
            cardinality = min(limit, cardinality)
        try:
            while len(infos) != cardinality:
                batch = json.loads(await anoncreds.prover_fetch_credentials(handle, chunk))
                infos.extend(batch)
                if len(batch) < chunk:
                    break
            if len(infos) != cardinality:
                LOGGER.warning('Credential search/limit indicated %s results but fetched %s', cardinality, len(infos))
        finally:
            await anoncreds.prover_close_credentials_search(handle)

        rv_json = json.dumps(infos)
        LOGGER.debug('HolderProver.get_cred_infos_by_q <<< %s', rv_json)
        return rv_json

Response: Get cred - infos from wallet by WQL query.


Instruction:
Here you have a function in Python 3, explain what it does
async def get_cred_infos_by_filter(self, filt: dict = None) -> str:

        LOGGER.debug('HolderProver.get_cred_infos_by_filter >>> filt: %s', filt)

        if not self.wallet.handle:
            LOGGER.debug('HolderProver.get_cred_infos_by_filter <!< Wallet %s is closed', self.name)
            raise WalletState('Wallet {} is closed'.format(self.name))

        rv_json = await anoncreds.prover_get_credentials(self.wallet.handle, json.dumps(filt or {}))
        LOGGER.debug('HolderProver.get_cred_infos_by_filter <<< %s', rv_json)
        return rv_json

Response: Get credential info from wallet by input filter.


Instruction:
Here you have a function in Python 3, explain what it does
async def create_proof(self, proof_req: dict, briefs: Union[dict, Sequence[dict]], requested_creds: dict) -> str:

        LOGGER.debug(
            'HolderProver.create_proof >>> proof_req: %s, briefs: %s, requested_creds: %s',
            proof_req,
            briefs,
            requested_creds)

        if not self.wallet.handle:
            LOGGER.debug('HolderProver.create_proof <!< Wallet %s is closed', self.name)
            raise WalletState('Wallet {} is closed'.format(self.name))

        label = await self._assert_link_secret('create_proof')

        cd_ids = set()
        x_cd_ids = set()
        for brief in iter_briefs(briefs):
            cd_id = brief['cred_info']['cred_def_id']
            if cd_id in cd_ids and cd_id not in x_cd_ids:
                x_cd_ids.add(cd_id)
            cd_ids.add(cd_id)
            if x_cd_ids:
                LOGGER.debug('HolderProver.create_proof <!< briefs specification out of focus (non-uniqueness)')
                raise CredentialFocus('Briefs list repeats cred defs: {}'.format(x_cd_ids))

        s_id2schema = {}  # schema identifier to schema
        cd_id2cred_def = {}  # credential definition identifier to credential definition
        rr_id2timestamp = {}  # revocation registry of interest to timestamp of interest (or None)
        rr_id2cr_id = {}  # revocation registry of interest to credential revocation identifier
        for brief in iter_briefs(briefs):
            interval = brief.get('interval', None)
            cred_info = brief['cred_info']
            s_id = cred_info['schema_id']
            if not ok_schema_id(s_id):
                LOGGER.debug('HolderProver.create_proof <!< Bad schema id %s', s_id)
                raise BadIdentifier('Bad schema id {}'.format(s_id))

            if s_id not in s_id2schema:
                schema = json.loads(await self.get_schema(s_id))  # add to cache en passant
                if not schema:
                    LOGGER.debug(
                        'HolderProver.create_proof <!< absent schema %s, proof req may be for another ledger',
                        s_id)
                    raise AbsentSchema('Absent schema {}, proof req may be for another ledger'.format(s_id))
                s_id2schema[s_id] = schema

            cd_id = cred_info['cred_def_id']
            if not ok_cred_def_id(cd_id):
                LOGGER.debug('HolderProver.create_proof <!< Bad cred def id %s', cd_id)
                raise BadIdentifier('Bad cred def id {}'.format(cd_id))

            if cd_id not in cd_id2cred_def:
                cred_def = json.loads(await self.get_cred_def(cd_id))  # add to cache en passant
                cd_id2cred_def[cd_id] = cred_def

            rr_id = cred_info['rev_reg_id']
            if rr_id:
                if not ok_rev_reg_id(rr_id):
                    LOGGER.debug('HolderProver.create_proof <!< Bad rev reg id %s', rr_id)
                    raise BadIdentifier('Bad rev reg id {}'.format(rr_id))

                await self._sync_revoc_for_proof(rr_id)  # link tails file to its rr_id if it's new
                if interval:
                    if rr_id not in rr_id2timestamp:
                        if interval['to'] > int(time()):
                            LOGGER.debug(
                                'HolderProver.create_proof <!< interval to %s for rev reg %s is in the future',
                                interval['to'],
                                rr_id)
                            raise BadRevStateTime(
                                'Revocation registry {} timestamp {} is in the future'.format(rr_id, interval['to']))
                        rr_id2timestamp[rr_id] = interval['to']
                elif 'revocation' in cd_id2cred_def[cd_id]['value']:
                    LOGGER.debug(
                        'HolderProver.create_proof <!< brief on cred def id %s missing non-revocation interval',
                        cd_id)
                    raise AbsentInterval('Brief on cred def id {} missing non-revocation interval'.format(cd_id))
                if rr_id in rr_id2cr_id:
                    continue
                rr_id2cr_id[rr_id] = cred_info['cred_rev_id']

        rr_id2rev_state = {}  # revocation registry identifier to its state
        with REVO_CACHE.lock:
            for rr_id in rr_id2timestamp:
                revo_cache_entry = REVO_CACHE.get(rr_id, None)
                tails = revo_cache_entry.tails if revo_cache_entry else None
                if tails is None:  # missing tails file
                    LOGGER.debug('HolderProver.create_proof <!< missing tails file for rev reg id %s', rr_id)
                    raise AbsentTails('Missing tails file for rev reg id {}'.format(rr_id))
                rr_def_json = await self.get_rev_reg_def(rr_id)
                (rr_delta_json, ledger_timestamp) = await revo_cache_entry.get_delta_json(
                    self._build_rr_delta_json,
                    rr_id2timestamp[rr_id],
                    rr_id2timestamp[rr_id])
                rr_state_json = await anoncreds.create_revocation_state(
                    tails.reader_handle,
                    rr_def_json,
                    rr_delta_json,
                    ledger_timestamp,
                    rr_id2cr_id[rr_id])
                rr_id2rev_state[rr_id] = {
                    rr_id2timestamp[rr_id]: json.loads(rr_state_json)
                }

        rv = await anoncreds.prover_create_proof(
            self.wallet.handle,
            json.dumps(proof_req),
            json.dumps(requested_creds),
            label,
            json.dumps(s_id2schema),
            json.dumps(cd_id2cred_def),
            json.dumps(rr_id2rev_state))
        LOGGER.debug('HolderProver.create_proof <<< %s', rv)
        return rv

Response: Create a HolderProver proof for the given cred - id and briefs.


Instruction:
Here you have a function in Python 3, explain what it does
async def reset_wallet(self, seed: str = None) -> Wallet:

        LOGGER.debug('HolderProver.reset_wallet >>>')

        self.wallet = await WalletManager().reset(self.wallet, seed)

        rv = self.wallet
        LOGGER.debug('HolderProver.reset_wallet <<< %s', rv)
        return rv

Response:
Close and delete HolderProver wallet, then create and open a replacement on prior link secret.
        Note that this operation effectively destroys private keys for credential definitions. Its
        intended use is primarily for testing and demonstration.

        Raise AbsentLinkSecret if link secret not set. Raise WalletState if the wallet is closed.

        :param seed: seed to use for new wallet (default random)
        :return: replacement wallet


Instruction:
Can you generate a brief explanation for the following Python 3 code
def my_resolve_lookup(self, context):
        current = context
        try:  # catch-all for silent variable failures
            for bit in self.lookups:
                try:  # dictionary lookup
                    current = current[bit]
                    # ValueError/IndexError are for numpy.array lookup on
                    # numpy < 1.9 and 1.9+ respectively
                except (TypeError, AttributeError, KeyError, ValueError, IndexError):
                    try:  # attribute lookup
                        # Don"t return class attributes if the class is the context:
                        if isinstance(current, BaseContext) and getattr(type(current), bit):
                            raise AttributeError
                        current = getattr(current, bit)
                    except (TypeError, AttributeError) as e:
                        # Reraise an AttributeError raised by a @property
                        if (isinstance(e, AttributeError) and
                                not isinstance(current, BaseContext) and bit in dir(current)):
                            raise
                        try:  # list-index lookup
                            current = current[int(bit)]
                        except (IndexError,  # list index out of range
                                ValueError,  # invalid literal for int()
                                KeyError,    # current is a dict without `int(bit)` key
                                TypeError):  # unsubscriptable object
                            raise VariableDoesNotExist("Failed lookup for key "
                                                       "[%s] in %r",
                                                       (bit, current))  # missing attribute
                if callable(current):
                    if getattr(current, "do_not_call_in_templates", False):
                        pass
                    elif getattr(current, "alters_data", False):
                        try:
                            current = context.template.engine.string_if_invalid
                        except AttributeError:
                            current = settings.TEMPLATE_STRING_IF_INVALID
                    else:
                        try:  # method call (assuming no args required)
                            current = current()
                        except TypeError:
                            try:
                                inspect.getcallargs(current)
                            except TypeError:  # arguments *were* required
                                current = context.template.engine.string_if_invalid  # invalid method call
                            else:
                                raise
                elif isinstance(current, Model):
                    if ("request" in context) and hasattr(context["request"], "_ultracache"):
                        # get_for_model itself is cached
                        ct = ContentType.objects.get_for_model(current.__class__)
                        context["request"]._ultracache.append((ct.id, current.pk))

        except Exception as e:
            template_name = getattr(context, "template_name", None) or "unknown"
            if logger is not None:
                logger.debug(
                    "Exception while resolving variable \"%s\" in template \"%s\".",
                    bit,
                    template_name,
                    exc_info=True,
                )

            if getattr(e, "silent_variable_failure", False):
                current = context.template.engine.string_if_invalid
            else:
                raise

        return current

Response: This method is called by the lookup methods to resolve a real variable against the given context.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def index(self) -> dict:

        LOGGER.debug('SchemaCache.index >>>')

        rv = self._seq_no2schema_key
        LOGGER.debug('SchemaCache.index <<< %s', rv)
        return rv

Response: Return a dictionary mapping content sequence numbers to schema keys.


Instruction:
Explain what the following Python 3 code does
def schema_key_for(self, seq_no: int) -> SchemaKey:

        LOGGER.debug('SchemaCache.schema_key_for >>> seq_no: %s', seq_no)

        rv = self._seq_no2schema_key.get(seq_no, None)

        LOGGER.debug('SchemaCache.schema_key_for <<< %s', rv)
        return rv

Response: Return schema key for given sequence number.


Instruction:
Explain what the following Python 3 code does
def schemata(self) -> list:

        LOGGER.debug('SchemaCache.schemata >>>')

        LOGGER.debug('SchemaCache.schemata <<<')
        return [self._schema_key2schema[seq_no] for seq_no in self._schema_key2schema]

Response: Return list with schemata in cache.


Instruction:
Explain what the following Python 3 code does
async def _get_update(self, rr_builder: Callable, fro: int, to: int, delta: bool) -> (str, int):

        LOGGER.debug(
            'RevoCacheEntry.get_update >>> rr_builder: %s, fro: %s, to: %s, delta: %s',
            rr_builder.__name__,
            fro,
            to,
            delta)

        if fro > to:
            (fro, to) = (to, fro)

        now = int(time())
        if to > now:
            LOGGER.debug(
                'RevoCacheEntry._get_update <!< Cannot query a rev reg %s in the future (%s > %s)',
                'delta' if delta else 'state',
                to,
                now)
            raise BadRevStateTime('Cannot query a rev reg {} in the future ({} > {})'.format(
                'delta' if delta else 'state',
                to,
                now))

        cache_frame = None
        rr_update_json = None
        rr_frames = self.rr_delta_frames if delta else self.rr_state_frames

        frames = [frame for frame in rr_frames if frame.timestamp <= to <= frame.to]
        if frames:
            cache_frame = max(frames, key=lambda f: f.timestamp)  # should be unique in any case
            # do not update frame.to, it's already past asked-for 'to'
        else:
            frames = [frame for frame in rr_frames if (fro <= frame.to and frame.timestamp <= to)]
            if frames:
                cache_frame = max(frames, key=lambda f: f.timestamp)
                # do not update frame.to - another update might occur, but we don't care; fro < frame.to, good enough
        if not frames:
            frames = [frame for frame in rr_frames if frame.timestamp < to]  # frame.to < to since not frames coming in
            if frames:
                latest_cached = max(frames, key=lambda frame: frame.timestamp)
                if delta:
                    (rr_update_json, timestamp) = await rr_builder(
                        self.rev_reg_def['id'],
                        to=to,
                        fro=latest_cached.timestamp,
                        fro_delta=latest_cached.rr_update)
                else:
                    (rr_update_json, timestamp) = await rr_builder(self.rev_reg_def['id'], to)
                if timestamp == latest_cached.timestamp:
                    latest_cached.to = to  # this timestamp now known good through more recent 'to'
                    cache_frame = latest_cached
            else:
                (rr_update_json, timestamp) = await rr_builder(self.rev_reg_def['id'], to)

        if cache_frame is None:
            cache_frame = RevRegUpdateFrame(to, timestamp, json.loads(rr_update_json))  # sets qtime to now
            rr_frames.append(cache_frame)
            self.cull(delta)
        else:
            cache_frame.qtime = int(time())

        rv = (json.dumps(cache_frame.rr_update), cache_frame.timestamp)
        LOGGER.debug('RevoCacheEntry._get_update <<< %s', rv)
        return rv

Response: Get the update json and timestamp for a given delta and state.


Instruction:
Here you have a function in Python 3, explain what it does
async def get_delta_json(
            self,
            rr_delta_builder: Callable[['HolderProver', str, int, int, dict], Awaitable[Tuple[str, int]]],
            fro: int,
            to: int) -> (str, int):
        """
        Get rev reg delta json, and its timestamp on the distributed ledger,
        from cached rev reg delta frames list or distributed ledger,
        updating cache as necessary.

        Raise BadRevStateTime if caller asks for a delta to the future.

        On return of any previously existing rev reg delta frame, always update its query time beforehand.

        :param rr_delta_builder: callback to build rev reg delta if need be (specify anchor instance's
            _build_rr_delta())
        :param fro: least time (epoch seconds) of interest; lower-bounds 'to' on frame housing return data
        :param to: greatest time (epoch seconds) of interest; upper-bounds returned revocation delta timestamp
        :return: rev reg delta json and ledger timestamp (epoch seconds)
        """

        LOGGER.debug(
            'RevoCacheEntry.get_delta_json >>> rr_delta_builder: %s, fro: %s, to: %s',
            rr_delta_builder.__name__,
            fro,
            to)

        rv = await self._get_update(rr_delta_builder, fro, to, True)
        LOGGER.debug('RevoCacheEntry.get_delta_json <<< %s', rv)
        return rv

Response: Get revocation delta json and its timestamp on the distributed ledger and return it.


Instruction:
Explain what the following Python 3 code does
async def get_state_json(
            self,
            rr_state_builder: Callable[['Verifier', str, int], Awaitable[Tuple[str, int]]],
            fro: int,
            to: int) -> (str, int):
        """
        Get rev reg state json, and its timestamp on the distributed ledger,
        from cached rev reg state frames list or distributed ledger,
        updating cache as necessary.

        Raise BadRevStateTime if caller asks for a state in the future.

        On return of any previously existing rev reg state frame, always update its query time beforehand.

        :param rr_state_builder: callback to build rev reg state if need be (specify anchor instance's
            _build_rr_state())
        :param fro: least time (epoch seconds) of interest; lower-bounds 'to' on frame housing return data
        :param to: greatest time (epoch seconds) of interest; upper-bounds returned revocation state timestamp
        :return: rev reg state json and ledger timestamp (epoch seconds)
        """

        LOGGER.debug(
            'RevoCacheEntry.get_state_json >>> rr_state_builder: %s, fro: %s, to: %s',
            rr_state_builder.__name__,
            fro,
            to)

        rv = await self._get_update(rr_state_builder, fro, to, False)
        LOGGER.debug('RevoCacheEntry.get_state_json <<< %s', rv)
        return rv

Response: Get revocation state json and its timestamp on the distributed ledger.


Instruction:
Can you generate the documentation for the following Python 3 function
def clear() -> None:

        LOGGER.debug('clear >>>')

        with SCHEMA_CACHE.lock:
            SCHEMA_CACHE.clear()
        with CRED_DEF_CACHE.lock:
            CRED_DEF_CACHE.clear()
        with REVO_CACHE.lock:
            REVO_CACHE.clear()

        LOGGER.debug('clear <<<')

Response: Clear all archivable caches in memory.


Instruction:
Make a summary of the following Python 3 code
def archive(base_dir: str) -> int:

        LOGGER.debug('archive >>> base_dir: %s', base_dir)

        rv = int(time())
        timestamp_dir = join(base_dir, str(rv))
        makedirs(timestamp_dir, exist_ok=True)

        with SCHEMA_CACHE.lock:
            with open(join(timestamp_dir, 'schema'), 'w') as archive:
                print(json.dumps(SCHEMA_CACHE.schemata()), file=archive)

        with CRED_DEF_CACHE.lock:
            with open(join(timestamp_dir, 'cred_def'), 'w') as archive:
                print(json.dumps(CRED_DEF_CACHE), file=archive)

        with REVO_CACHE.lock:
            with open(join(timestamp_dir, 'revocation'), 'w') as archive:
                revo_cache_dict = {}
                for rr_id in REVO_CACHE:
                    revo_cache_dict[rr_id] = {
                        'rev_reg_def': REVO_CACHE[rr_id].rev_reg_def,
                        'rr_delta_frames': [vars(f) for f in REVO_CACHE[rr_id].rr_delta_frames],
                        'rr_state_frames': [vars(f) for f in REVO_CACHE[rr_id].rr_state_frames]
                    }
                print(json.dumps(revo_cache_dict), file=archive)

        LOGGER.debug('archive <<< %s', rv)
        return rv

Response: Archive schema cred def revocation caches to disk as json.


Instruction:
Can you create a Python 3 function that
purges all cache archives.

Response:
def purge_archives(base_dir: str, retain_latest: bool = False) -> None:
        """
        Erase all (or nearly all) cache archives.

        :param base_dir: archive base directory
        :param retain_latest: retain latest archive if present, purge all others
        """

        LOGGER.debug('purge_archives >>> base_dir: %s, retain_latest: %s', base_dir, retain_latest)

        if isdir(base_dir):
            timestamps = sorted([int(t) for t in listdir(base_dir) if t.isdigit()])
            if retain_latest and timestamps:
                timestamps.pop()
            for timestamp in timestamps:
                timestamp_dir = join(base_dir, str(timestamp))
                rmtree(timestamp_dir)
                LOGGER.info('Purged archive cache directory %s', timestamp_dir)

        LOGGER.debug('purge_archives <<<')


Instruction:
Can you generate a brief explanation for the following Python 3 code
def pairwise_info2tags(pairwise: PairwiseInfo) -> dict:

    rv = {
        canon_pairwise_tag(tag): raw(pairwise.metadata[tag]) for tag in pairwise.metadata or {}
    }
    rv['~their_did'] = pairwise.their_did
    rv['~their_verkey'] = pairwise.their_verkey
    rv['~my_did'] = pairwise.my_did
    rv['~my_verkey'] = pairwise.my_verkey

    if not StorageRecord.ok_tags(rv):
        raise BadRecord('Pairwise metadata {} must map strings to strings'.format(rv))

    return rv

Response:
Given a pairwise info with metadata mapping tags to values return corresponding
    indy - sdk non_secrets record tags dict to store same in wallet


Instruction:
How would you code a function in Python 3 to
give indy - sdk non - secrets implementation of pairwise storage record dict return corresponding PairwiseInfo.

Response:
def storage_record2pairwise_info(storec: StorageRecord) -> PairwiseInfo:
    """
    Given indy-sdk non_secrets implementation of pairwise storage record dict, return corresponding PairwiseInfo.

    :param storec: (non-secret) storage record to convert to PairwiseInfo
    :return: PairwiseInfo on record DIDs, verkeys, metadata
    """

    return PairwiseInfo(
        storec.id,  # = their did
        storec.value,  # = their verkey
        storec.tags['~my_did'],
        storec.tags['~my_verkey'],
        {
            tag[tag.startswith('~'):]: storec.tags[tag] for tag in (storec.tags or {})  # strip any leading '~'
        })


Instruction:
How would you implement a function in Python 3 that
gives a configuration dict with indy and possibly more configuration values return the corresponding indy wallet configuration dict from current default and input values.

Response:
def _config2indy(self, config: dict) -> dict:
        """
        Given a configuration dict with indy and possibly more configuration values, return the
        corresponding indy wallet configuration dict from current default and input values.

        :param config: input configuration
        :return: configuration dict for indy wallet
        """

        assert {'name', 'id'} & {k for k in config}
        return {
            'id': config.get('name', config.get('id')),
            'storage_type': config.get('storage_type', self.default_storage_type),
            'freshness_time': config.get('freshness_time', self.default_freshness_time)
        }


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _config2von(self, config: dict, access: str = None) -> dict:

        rv = {k: config.get(k, self._defaults[k]) for k in ('auto_create', 'auto_remove')}
        rv['access'] = access or self.default_access
        for key in ('seed', 'did', 'link_secret_label'):
            if key in config:
                rv[key] = config[key]
        return rv

Response: Given a configuration dict with indy and possibly more configuration values return the corresponding VON wallet configuration dict from current default and input values.


Instruction:
Explain what the following Python 3 code does
async def create(self, config: dict = None, access: str = None, replace: bool = False) -> Wallet:

        LOGGER.debug('WalletManager.create >>> config %s, access %s, replace %s', config, access, replace)

        assert {'name', 'id'} & {k for k in config}
        wallet_name = config.get('name', config.get('id'))
        if replace:
            von_wallet = self.get(config, access)
            if not await von_wallet.remove():
                LOGGER.debug('WalletManager.create <!< Failed to remove wallet %s for replacement', wallet_name)
                raise ExtantWallet('Failed to remove wallet {} for replacement'.format(wallet_name))

        indy_config = self._config2indy(config)
        von_config = self._config2von(config, access)
        rv = Wallet(indy_config, von_config)
        await rv.create()
        LOGGER.debug('WalletManager.create <<< %s', rv)
        return rv

Response: Create new wallet on input name with given configuration and access credential value.


Instruction:
Make a summary of the following Python 3 code
def get(self, config: dict, access: str = None) -> Wallet:

        LOGGER.debug('WalletManager.get >>> config %s, access %s', config, access)

        rv = Wallet(
            self._config2indy(config),
            self._config2von(config, access))

        LOGGER.debug('WalletManager.get <<< %s', rv)
        return rv

Response: Instantiate and return VON anchor wallet object on given configuration data.


Instruction:
How would you explain what the following Python 3 function does
async def reseed_local(self, local_wallet: Wallet, next_seed: str = None) -> DIDInfo:

        LOGGER.debug('WalletManager.reseed_local >>> local_wallet %s', local_wallet)

        await local_wallet.reseed_init(next_seed)

        rv = await local_wallet.reseed_apply()
        LOGGER.debug('WalletManager.reseed_local <<< %s', rv)
        return rv

Response: Generate and apply new verification key for local DID based on input seed.


Instruction:
Can you generate a brief explanation for the following Python 3 code
async def export_wallet(self, von_wallet: Wallet, path: str) -> None:

        LOGGER.debug('WalletManager.export_wallet >>> von_wallet %s, path %s', von_wallet, path)

        if not von_wallet.handle:
            LOGGER.debug('WalletManager.export_wallet <!< Wallet %s is closed', von_wallet.name)
            raise WalletState('Wallet {} is closed'.format(von_wallet.name))

        await wallet.export_wallet(
            von_wallet.handle,
            json.dumps({
                'path': path,
                **von_wallet.access_creds
            }))

        LOGGER.debug('WalletManager.export_wallet <<<')

Response: Export an existing VON anchor wallet. Raise WalletState if wallet is closed.


Instruction:
Given the following Python 3 function, write the documentation
async def import_wallet(self, indy_config: dict, path: str, access: str = None) -> None:

        LOGGER.debug('WalletManager.import_wallet >>> indy_config %s, path: %s', indy_config, path)

        try:
            await wallet.import_wallet(
                json.dumps(indy_config),
                json.dumps({'key': access or self.default_access}),
                json.dumps({'path': path, 'key': access or self.default_access}))
        except IndyError as x_indy:
            if x_indy.error_code == ErrorCode.CommonInvalidStructure:  # indy-sdk raises on bad access
                LOGGER.debug(
                    'WalletManager.import_wallet <!< bad access credential value for wallet %s',
                    indy_config.get('id', '(no id)'))
                raise BadAccess('Bad access credential value for wallet {}'.format(indy_config.get('id', '(no id)')))
            LOGGER.debug(
                'WalletManager.import_wallet <!< indy error code %s on wallet %s import',
                x_indy.error_code,
                indy_config.get('id', '(no id)'))
            raise

        LOGGER.debug('WalletManager.import_wallet <<<')

Response: Import a VON anchor wallet.


Instruction:
How would you implement a function in Python 3 that
resets wallet and return new wallet with new link secret.

Response:
async def reset(self, von_wallet: Wallet, seed: str = None) -> Wallet:
        """
        Close and delete (open) VON anchor wallet and then create, open, and return
        replacement on current link secret.

        Note that this operation effectively destroys private keys for keyed data
        structures such as credential offers or credential definitions.

        Raise WalletState if the wallet is closed.

        :param von_wallet: open wallet
        :param seed: seed to use for new wallet (default random)
        :return: replacement wallet
        """

        LOGGER.debug('WalletManager.reset >>> von_wallet %s', von_wallet)

        if not von_wallet.handle:
            LOGGER.debug('WalletManager.reset <!< Wallet %s is closed', von_wallet.name)
            raise WalletState('Wallet {} is closed'.format(von_wallet.name))

        w_config = von_wallet.config  # wallet under reset, no need to make copy
        w_config['did'] = von_wallet.did
        w_config['seed'] = seed
        w_config['auto_create'] = von_wallet.auto_create  # in case both auto_remove+auto_create set (create every open)
        w_config['auto_remove'] = von_wallet.auto_remove

        label = await von_wallet.get_link_secret_label()
        if label:
            w_config['link_secret_label'] = label

        await von_wallet.close()
        if not von_wallet.auto_remove:
            await self.remove(von_wallet)

        rv = await self.create(w_config, von_wallet.access)
        await rv.open()

        LOGGER.debug('WalletManager.reset <<< %s', rv)
        return rv


Instruction:
Can you generate a brief explanation for the following Python 3 code
async def register_storage_library(storage_type: str, c_library: str, entry_point: str) -> None:

        LOGGER.debug(
            'WalletManager.register_storage_library >>> storage_type %s, c_library %s, entry_point %s',
            storage_type,
            c_library,
            entry_point)

        try:
            stg_lib = CDLL(c_library)
            result = stg_lib[entry_point]()
            if result:
                LOGGER.debug(
                    'WalletManager.register_storage_library <!< indy error code %s on storage library entry at %s',
                    result,
                    entry_point)
                raise IndyError(result)
            LOGGER.info('Loaded storage library type %s (%s)', storage_type, c_library)
        except IndyError as x_indy:
            LOGGER.debug(
                'WalletManager.register_storage_library <!< indy error code %s on load of storage library %s %s',
                x_indy.error_code,
                storage_type,
                c_library)
            raise

        LOGGER.debug('WalletManager.register_storage_library <<<')

Response: Register a wallet storage library entry.


Instruction:
Implement a function in Python 3 to
expire ultracache cache keys affected by this object

Response:
def on_post_save(sender, **kwargs):
    """Expire ultracache cache keys affected by this object
    """
    if not invalidate:
        return
    if kwargs.get("raw", False):
        return
    if sender is MigrationRecorder.Migration:
        return
    if issubclass(sender, Model):
        obj = kwargs["instance"]
        if isinstance(obj, Model):
            # get_for_model itself is cached
            try:
                ct = ContentType.objects.get_for_model(sender)
            except RuntimeError:
                # This happens when ultracache is being used by another product
                # during a test run.
                return

            if kwargs.get("created", False):
                # Expire cache keys that contain objects of this content type
                key = "ucache-ct-%s" % ct.id
                to_delete = cache.get(key, [])
                if to_delete:
                    try:
                        cache.delete_many(to_delete)
                    except NotImplementedError:
                        for k in to_delete:
                            cache.delete(k)
                cache.delete(key)

                # Purge paths in reverse caching proxy that contain objects of
                # this content type.
                key = "ucache-ct-pth-%s" % ct.id
                if purger is not None:
                    for li in cache.get(key, []):
                        purger(li[0], li[1])
                cache.delete(key)

            else:
                # Expire cache keys
                key = "ucache-%s-%s" % (ct.id, obj.pk)
                to_delete = cache.get(key, [])
                if to_delete:
                    try:
                        cache.delete_many(to_delete)
                    except NotImplementedError:
                        for k in to_delete:
                            cache.delete(k)
                cache.delete(key)

                # Purge paths in reverse caching proxy
                key = "ucache-pth-%s-%s" % (ct.id, obj.pk)
                if purger is not None:
                    for li in cache.get(key, []):
                        purger(li[0], li[1])
                cache.delete(key)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def on_post_delete(sender, **kwargs):
    if not invalidate:
        return
    if kwargs.get("raw", False):
        return
    if sender is MigrationRecorder.Migration:
        return
    if issubclass(sender, Model):
        obj = kwargs["instance"]
        if isinstance(obj, Model):
            # get_for_model itself is cached
            try:
                ct = ContentType.objects.get_for_model(sender)
            except RuntimeError:
                # This happens when ultracache is being used by another product
                # during a test run.
                return

            # Expire cache keys
            key = "ucache-%s-%s" % (ct.id, obj.pk)
            to_delete = cache.get(key, [])
            if to_delete:
                try:
                    cache.delete_many(to_delete)
                except NotImplementedError:
                    for k in to_delete:
                        cache.delete(k)
            cache.delete(key)

            # Invalidate paths in reverse caching proxy
            key = "ucache-pth-%s-%s" % (ct.id, obj.pk)
            if purger is not None:
                for li in cache.get(key, []):
                    purger(li[0], li[1])
            cache.delete(key)

Response: Expire ultracache cache keys affected by this object


Instruction:
Can you generate a brief explanation for the following Python 3 code
async def create_signing_key(self, seed: str = None, metadata: dict = None) -> KeyInfo:

        LOGGER.debug('Wallet.create_signing_key >>> seed: [SEED], metadata: %s', metadata)

        if not self.handle:
            LOGGER.debug('Wallet.create_signing_key <!< Wallet %s is closed', self.name)
            raise WalletState('Wallet {} is closed'.format(self.name))

        try:
            verkey = await crypto.create_key(self.handle, json.dumps({'seed': seed} if seed else {}))
        except IndyError as x_indy:
            if x_indy.error_code == ErrorCode.WalletItemAlreadyExists:
                LOGGER.debug('Wallet.create_signing_key <!< Verification key already present in wallet %s', self.name)
                raise ExtantRecord('Verification key already present in wallet {}'.format(self.name))
            LOGGER.debug('Wallet.create_signing_key <!< indy-sdk raised error %s', x_indy.error_code)
            raise

        await crypto.set_key_metadata(self.handle, verkey, json.dumps(metadata or {}))  # coerce None to empty

        rv = KeyInfo(verkey, metadata or {})
        LOGGER.debug('Wallet.create_signing_key <<< %s', rv)
        return rv

Response: Create a new signing key pair.


Instruction:
Can you implement a function in Python 3 that
creates and store a new local DID for use in pairwise DID relations.

Response:
async def create_local_did(self, seed: str = None, loc_did: str = None, metadata: dict = None) -> DIDInfo:
        """
        Create and store a new local DID for use in pairwise DID relations.

        :param seed: seed from which to create (default random)
        :param loc_did: local DID value (default None to let indy-sdk generate)
        :param metadata: metadata to associate with the local DID
            (operation always sets 'since', 'modified' epoch timestamps)
        :return: DIDInfo for new local DID
        """

        LOGGER.debug('Wallet.create_local_did >>> seed: [SEED] loc_did: %s metadata: %s', loc_did, metadata)

        cfg = {}
        if seed:
            cfg['seed'] = seed
        if loc_did:
            cfg['did'] = loc_did

        if not self.handle:
            LOGGER.debug('Wallet.create_local_did <!< Wallet %s is closed', self.name)
            raise WalletState('Wallet {} is closed'.format(self.name))

        try:
            (created_did, verkey) = await did.create_and_store_my_did(self.handle, json.dumps(cfg))
        except IndyError as x_indy:
            if x_indy.error_code == ErrorCode.DidAlreadyExistsError:
                LOGGER.debug('Wallet.create_local_did <!< DID %s already present in wallet %s', loc_did, self.name)
                raise ExtantRecord('Local DID {} already present in wallet {}'.format(loc_did, self.name))
            LOGGER.debug('Wallet.create_local_did <!< indy-sdk raised error %s', x_indy.error_code)
            raise

        now = int(time())
        loc_did_metadata = {**(metadata or {}), 'since': now, 'modified': now}
        await did.set_did_metadata(self.handle, created_did, json.dumps(loc_did_metadata))

        rv = DIDInfo(created_did, verkey, loc_did_metadata)

        LOGGER.debug('Wallet.create_local_did <<< %s', rv)
        return rv


Instruction:
How would you code a function in Python 3 to
replace the metadata associated with a local DID with new metadata.

Response:
async def replace_local_did_metadata(self, loc_did: str, metadata: dict) -> DIDInfo:
        """
        Replace the metadata associated with a local DID.

        Raise WalletState if wallet is closed, AbsentRecord for no such local DID.

        :param loc_did: local DID of interest
        :param metadata: new metadata to store
        :return: DIDInfo for local DID after write
        """

        LOGGER.debug('Wallet.replace_local_did_metadata >>> loc_did: %s, metadata: %s', loc_did, metadata)

        old = await self.get_local_did(loc_did)  # raises exceptions if applicable
        now = int(time())
        loc_did_metadata = {**(metadata or {}), 'since': (old.metadata or {}).get('since', now), 'modified': now}
        try:
            await did.set_did_metadata(self.handle, loc_did, json.dumps(loc_did_metadata))
        except IndyError as x_indy:
            LOGGER.debug('Wallet.replace_local_did_metadata <!< indy-sdk raised error %s', x_indy.error_code)
            raise

        rv = await self.get_local_did(loc_did)
        LOGGER.debug('Wallet.replace_local_did_metadata <<< %s', rv)
        return rv


Instruction:
Given the following Python 3 function, write the documentation
async def get_local_dids(self) -> Sequence[DIDInfo]:

        LOGGER.debug('Wallet.get_local_dids >>>')

        dids_with_meta = json.loads(did.list_my_dids_with_meta(self.handle))  # list

        rv = []
        for did_with_meta in dids_with_meta:
            meta = json.loads(did_with_meta['metadata']) if did_with_meta['metadata'] else {}
            if meta.get('anchor', False):
                continue  # exclude anchor DIDs past and present
            rv.append(DIDInfo(did_with_meta['did'], did_with_meta['verkey'], meta))

        LOGGER.debug('Wallet.get_local_dids <<< %s', rv)
        return rv

Response: Get list of local DIDInfos for local DIDs.


Instruction:
Write a Python 3 script for
getting current anchor DID by metadata.

Response:
async def get_anchor_did(self) -> str:
        """
        Get current anchor DID by metadata, None for not yet set.

        :return: DID
        """

        LOGGER.debug('Wallet.get_anchor_did >>>')

        if not self.handle:
            LOGGER.debug('Wallet.get_anchor_did <!< Wallet %s is closed', self.name)
            raise WalletState('Wallet {} is closed'.format(self.name))

        rv = None
        dids_with_meta = json.loads(await did.list_my_dids_with_meta(self.handle))  # list

        latest = 0
        for did_with_meta in dids_with_meta:
            try:
                meta = json.loads(did_with_meta['metadata']) if did_with_meta['metadata'] else {}
                if not meta.get('anchor', False):
                    continue
                if isinstance(meta, dict) and meta.get('since', -1) > latest:
                    rv = did_with_meta.get('did')
            except json.decoder.JSONDecodeError:
                continue  # it's not an anchor DID, carry on

        LOGGER.debug('Wallet.get_anchor_did <<< %s', rv)
        return rv


Instruction:
Explain what the following Python 3 code does
async def create_link_secret(self, label: str) -> None:

        LOGGER.debug('Wallet.create_link_secret >>> label: %s', label)

        if not self.handle:
            LOGGER.debug('Wallet.create_link_secret <!< Wallet %s is closed', self.name)
            raise WalletState('Wallet {} is closed'.format(self.name))

        try:
            await anoncreds.prover_create_master_secret(self.handle, label)
            await self._write_link_secret_label(label)
        except IndyError as x_indy:
            if x_indy.error_code == ErrorCode.AnoncredsMasterSecretDuplicateNameError:
                LOGGER.warning(
                    'Wallet %s link secret already current: abstaining from updating label record', self.name)
                await self._write_link_secret_label(label)
            else:
                LOGGER.debug(
                    'Wallet.create_link_secret <!< cannot create link secret for wallet %s, indy error code %s',
                    self.name,
                    x_indy.error_code)
                raise

        LOGGER.debug('Wallet.create_link_secret <<<')

Response: Create link secret in wallet.


Instruction:
Implement a function in Python 3 to
update non - secret storage record with link secret label.

Response:
async def _write_link_secret_label(self, label) -> None:
        """
        Update non-secret storage record with link secret label.

        :param label: link secret label
        """

        LOGGER.debug('Wallet._write_link_secret_label <<< %s', label)

        if await self.get_link_secret_label() == label:
            LOGGER.info('Wallet._write_link_secret_label abstaining - already current')
        else:
            await self.write_non_secret(StorageRecord(
                TYPE_LINK_SECRET_LABEL,
                label,
                tags=None,
                ident=str(int(time()))))  # indy requires str

        LOGGER.debug('Wallet._write_link_secret_label <<<')


Instruction:
Can you write a function in Python 3 where it
gets current link secret label from non - secret storage records ; return None for no match.

Response:
async def get_link_secret_label(self) -> str:
        """
        Get current link secret label from non-secret storage records; return None for no match.

        :return: latest non-secret storage record for link secret label
        """

        LOGGER.debug('Wallet.get_link_secret_label >>>')

        if not self.handle:
            LOGGER.debug('Wallet.get_link_secret <!< Wallet %s is closed', self.name)
            raise WalletState('Wallet {} is closed'.format(self.name))

        rv = None
        records = await self.get_non_secret(TYPE_LINK_SECRET_LABEL)
        if records:
            rv = records[str(max(int(k) for k in records))].value  # str to int, max, and back again

        LOGGER.debug('Wallet.get_link_secret_label <<< %s', rv)
        return rv


Instruction:
Explain what the following Python 3 code does
async def open(self) -> 'Wallet':

        LOGGER.debug('Wallet.open >>>')

        created = False
        while True:
            try:
                self._handle = await wallet.open_wallet(
                    json.dumps(self.config),
                    json.dumps(self.access_creds))
                LOGGER.info('Opened wallet %s on handle %s', self.name, self.handle)
                break
            except IndyError as x_indy:
                if x_indy.error_code == ErrorCode.WalletNotFoundError:
                    if created:
                        LOGGER.debug('Wallet.open() <!< Wallet %s not found after creation', self.name)
                        raise AbsentWallet('Wallet {} not found after creation'.format(self.name))
                    if self.auto_create:
                        await self.create()
                        continue
                    else:
                        LOGGER.debug('Wallet.open() <!< Wallet %s not found', self.name)
                        raise AbsentWallet('Wallet {} not found'.format(self.name))
                elif x_indy.error_code == ErrorCode.WalletAlreadyOpenedError:
                    LOGGER.debug('Wallet.open() <!< Wallet %s is already open', self.name)
                    raise WalletState('Wallet {} is already open'.format(self.name))
                elif x_indy.error_code == ErrorCode.WalletAccessFailed:
                    LOGGER.debug('Wallet.open() <!< Bad access credentials value for wallet %s', self.name)
                    raise BadAccess('Bad access credentials value for wallet {}'.format(self.name))

                LOGGER.debug('Wallet %s open raised indy error %s', self.name, x_indy.error_code)
                raise

        self.did = await self.get_anchor_did()
        self.verkey = await did.key_for_local_did(self.handle, self.did) if self.did else None
        LOGGER.info('Wallet %s got verkey %s for existing DID %s', self.name, self.verkey, self.did)

        LOGGER.debug('Wallet.open <<<')
        return self

Response: Open wallet and return current object.


Instruction:
Given the following Python 3 function, write the documentation
async def create(self) -> None:

        LOGGER.debug('Wallet.create >>>')

        try:
            await wallet.create_wallet(
                config=json.dumps(self.config),
                credentials=json.dumps(self.access_creds))
            LOGGER.info('Created wallet %s', self.name)
        except IndyError as x_indy:
            if x_indy.error_code == ErrorCode.WalletAlreadyExistsError:
                LOGGER.debug('Wallet.create <!< Wallet %s already exists', self.name)
                raise ExtantWallet('Wallet {} already exists'.format(self.name))
            LOGGER.debug(
                'Wallet.create <!< indy error code %s on creation of wallet %s',
                x_indy.error_code,
                self.name)
            raise

        auto_remove = self.auto_remove
        self.auto_remove = False  # defer past this creation process
        async with self:
            did_info = await self.create_local_did(
                self._von_config.get('seed', None),
                self._von_config.get('did', None),
                {'anchor': True})
            self.did = did_info.did
            self.verkey = did_info.verkey
            if 'link_secret_label' in self._von_config:
                await self.create_link_secret(self._von_config['link_secret_label'])
        self.auto_remove = auto_remove

        LOGGER.debug('Wallet.create <<<')

Response: Create the wallet and store it in self. did.


Instruction:
Create a Python 3 function to
close the wallet and delete if auto_remove is set to True.

Response:
async def close(self) -> None:
        """
        Explicit exit. Close wallet (and delete if so configured).
        """

        LOGGER.debug('Wallet.close >>>')

        if not self.handle:
            LOGGER.warning('Abstaining from closing wallet %s: already closed', self.name)
        else:
            LOGGER.debug('Closing wallet %s', self.name)
            await wallet.close_wallet(self.handle)
            self._handle = None
            if self.auto_remove:
                LOGGER.info('Automatically removing wallet %s', self.name)
                await self.remove()
        self._handle = None

        LOGGER.debug('Wallet.close <<<')


Instruction:
Write a Python 3 function that can
remove serialized wallet return whether wallet absent after operation

Response:
async def remove(self) -> bool:
        """
        Remove serialized wallet, best effort, if it exists. Return whether wallet absent after operation
        (removal successful or else not present a priori).

        Raise WalletState if wallet is open.

        :return: whether wallet gone from persistent storage
        """

        LOGGER.debug('Wallet.remove >>>')

        if self.handle:
            LOGGER.debug('Wallet.remove <!< Wallet %s is open', self.name)
            raise WalletState('Wallet {} is open'.format(self.name))

        rv = True
        try:
            LOGGER.info('Attempting to remove wallet: %s', self.name)
            await wallet.delete_wallet(
                json.dumps(self.config),
                json.dumps(self.access_creds))
        except IndyError as x_indy:
            if x_indy.error_code == ErrorCode.WalletNotFoundError:
                LOGGER.info('Wallet %s not present; abstaining from removal', self.name)
            else:
                LOGGER.info('Failed wallet %s removal; indy-sdk error code %s', self.name, x_indy.error_code)
                rv = False

        LOGGER.debug('Wallet.remove <<< %s', rv)
        return rv


Instruction:
How would you explain what the following Python 3 function does
async def write_pairwise(
            self,
            their_did: str,
            their_verkey: str = None,
            my_did: str = None,
            metadata: dict = None,
            replace_meta: bool = False) -> PairwiseInfo:
        """
        Store a pairwise DID for a secure connection. Use verification key for local DID in wallet if
        supplied; otherwise, create one first. If local DID specified but not present, raise AbsentRecord.

        With supplied metadata, replace or augment and overwrite any existing metadata for the pairwise
        relation if one already exists in the wallet. Always include local and remote DIDs and keys in
        metadata to allow for WQL search.

        Raise AbsentRecord on call to update a non-existent record. Raise BadRecord if metadata does not
        coerce into non-secrets API tags specification {str:str}.

        :param their_did: remote DID
        :param their_verkey: remote verification key (default None is OK if updating an existing pairwise DID)
        :param my_did: local DID
        :param metadata: metadata for pairwise connection
        :param replace_meta: whether to (True) replace or (False) augment and overwrite existing metadata
        :return: resulting PairwiseInfo
        """

        LOGGER.debug(
            'Wallet.write_pairwise >>> their_did: %s, their_verkey: %s, my_did: %s, metadata: %s, replace_meta: %s',
            their_did,
            their_verkey,
            my_did,
            metadata,
            replace_meta)

        if their_verkey is None:
            match = await self.get_pairwise(their_did)
            if not match:
                LOGGER.debug(
                    'Wallet.write_pairwise <!< Wallet %s has no pairwise DID on %s to update',
                    self.name,
                    their_did)
                raise AbsentRecord('Wallet {} has no pairwise DID on {} to update'.format(self.name, their_did))
            their_verkey = [pwise for pwise in match.values()][0].their_verkey

        try:
            await did.store_their_did(self.handle, json.dumps({'did': their_did, 'verkey': their_verkey}))
        except IndyError as x_indy:
            if x_indy.error_code == ErrorCode.WalletItemAlreadyExists:
                pass  # exists already, carry on
            else:
                LOGGER.debug(
                    'Wallet.write_pairwise <!< Wallet %s write of their_did %s raised indy error code %s',
                    self.name,
                    their_did,
                    x_indy.error_code)
                raise

        if my_did:
            my_did_info = await self.get_local_did(my_did)  # raises AbsentRecord if no such local did
        else:
            my_did_info = await self.create_local_did(None, None, {'pairwise_for': their_did})

        pairwise = PairwiseInfo(their_did, their_verkey, my_did_info.did, my_did_info.verkey, metadata)
        try:
            storec = await self.write_non_secret(
                StorageRecord(TYPE_PAIRWISE, their_verkey, tags=pairwise_info2tags(pairwise), ident=their_did),
                replace_meta)
        except BadRecord:
            LOGGER.debug(
                'Wallet.write_pairwise <!< Pairwise metadata %s does not coerce into flat {str:str} tags dict',
                pairwise.metadata)
            raise

        rv = storage_record2pairwise_info(storec)
        LOGGER.debug('Wallet.write_pairwise <<< %s', rv)
        return rv

Response: Write a pairwise connection to the wallet.


Instruction:
Can you tell what is the following Python 3 function doing
async def get_pairwise(self, pairwise_filt: str = None) -> dict:

        LOGGER.debug('Wallet.get_pairwise >>> pairwise_filt: %s', pairwise_filt)

        if not self.handle:
            LOGGER.debug('Wallet.get_pairwise <!< Wallet %s is closed', self.name)
            raise WalletState('Wallet {} is closed'.format(self.name))

        storecs = await self.get_non_secret(
            TYPE_PAIRWISE,
            pairwise_filt if ok_did(pairwise_filt) or not pairwise_filt else json.loads(pairwise_filt),
            canon_pairwise_wql)
        rv = {k: storage_record2pairwise_info(storecs[k]) for k in storecs}  # touch up tags, mute leading ~

        LOGGER.debug('Wallet.get_pairwise <<< %s', rv)
        return rv

Response: Get a dictionary mapping each remote DID of interest in wallet to its pairwise info or mapping them all. If wallet has no such item return empty dict.


Instruction:
Here you have a function in Python 3, explain what it does
async def write_non_secret(self, storec: StorageRecord, replace_meta: bool = False) -> StorageRecord:

        LOGGER.debug('Wallet.write_non_secret >>> storec: %s, replace_meta: %s', storec, replace_meta)

        if not self.handle:
            LOGGER.debug('Wallet.write_non_secret <!< Wallet %s is closed', self.name)
            raise WalletState('Wallet {} is closed'.format(self.name))

        if not StorageRecord.ok_tags(storec.tags):
            LOGGER.debug('Wallet.write_non_secret <!< bad storage record tags %s; use flat {str: str} dict', storec)
            raise BadRecord('Bad storage record tags {}; use flat {{str:str}} dict'.format(storec))

        try:
            record = json.loads(await non_secrets.get_wallet_record(
                self.handle,
                storec.type,
                storec.id,
                json.dumps({
                    'retrieveType': False,
                    'retrieveValue': True,
                    'retrieveTags': True
                })))
            if record['value'] != storec.value:
                await non_secrets.update_wallet_record_value(
                    self.handle,
                    storec.type,
                    storec.id,
                    storec.value)
        except IndyError as x_indy:
            if x_indy.error_code == ErrorCode.WalletItemNotFound:
                await non_secrets.add_wallet_record(
                    self.handle,
                    storec.type,
                    storec.id,
                    storec.value,
                    json.dumps(storec.tags) if storec.tags else None)
            else:
                LOGGER.debug(
                    'Wallet.write_non_secret <!< Wallet lookup raised indy error code %s',
                    x_indy.error_code)
                raise
        else:
            if (record['tags'] or None) != storec.tags:  # record maps no tags to {}, not None
                tags = (storec.tags or {}) if replace_meta else {**record['tags'], **(storec.tags or {})}

                await non_secrets.update_wallet_record_tags(
                    self.handle,
                    storec.type,
                    storec.id,
                    json.dumps(tags))  # indy-sdk takes '{}' instead of None for null tags

        record = json.loads(await non_secrets.get_wallet_record(
            self.handle,
            storec.type,
            storec.id,
            json.dumps({
                'retrieveType': False,
                'retrieveValue': True,
                'retrieveTags': True
            })))

        rv = StorageRecord(storec.type, record['value'], tags=record.get('tags', None), ident=record['id'])
        LOGGER.debug('Wallet.write_non_secret <<< %s', rv)
        return rv

Response: Write a non - secret storage record to the wallet.