def put(self,<EOL>name,<EOL>value=None,<EOL>modify=False,<EOL>metadata=None,<EOL>description='<STR_LIT>',<EOL>encrypt=True,<EOL>lock=False,<EOL>key_type='<STR_LIT>',<EOL>add=False):
def assert_key_is_unlocked(existing_key):<EOL><INDENT>if existing_key and existing_key.get('<STR_LIT>'):<EOL><INDENT>raise GhostError(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'.format(name))<EOL><DEDENT><DEDENT>def assert_value_provided_for_new_key(value, existing_key):<EOL><INDENT>if not value and not existing_key.get('<STR_LIT:value>'):<EOL><INDENT>raise GhostError('<STR_LIT>')<EOL><DEDENT><DEDENT>self._assert_valid_stash()<EOL>self._validate_key_schema(value, key_type)<EOL>if value and encrypt and not isinstance(value, dict):<EOL><INDENT>raise GhostError('<STR_LIT>')<EOL><DEDENT>key = self._handle_existing_key(name, modify or add)<EOL>assert_key_is_unlocked(key)<EOL>assert_value_provided_for_new_key(value, key)<EOL>new_key = dict(name=name, lock=lock)<EOL>if value:<EOL><INDENT>if add:<EOL><INDENT>value = self._update_existing_key(key, value)<EOL><DEDENT>new_key['<STR_LIT:value>'] = self._encrypt(value) if encrypt else value<EOL><DEDENT>else:<EOL><INDENT>new_key['<STR_LIT:value>'] = key.get('<STR_LIT:value>')<EOL><DEDENT>new_key['<STR_LIT:description>'] = description or key.get('<STR_LIT:description>')<EOL>new_key['<STR_LIT>'] = key.get('<STR_LIT>') or _get_current_time()<EOL>new_key['<STR_LIT>'] = _get_current_time()<EOL>new_key['<STR_LIT>'] = metadata or key.get('<STR_LIT>')<EOL>new_key['<STR_LIT>'] = key.get('<STR_LIT>') or str(uuid.uuid4())<EOL>new_key['<STR_LIT:type>'] = key.get('<STR_LIT:type>') or key_type<EOL>key_id = self._storage.put(new_key)<EOL>audit(<EOL>storage=self._storage.db_path,<EOL>action='<STR_LIT>' if (modify or add) else '<STR_LIT>',<EOL>message=json.dumps(dict(<EOL>key_name=new_key['<STR_LIT:name>'],<EOL>value='<STR_LIT>',<EOL>description=new_key['<STR_LIT:description>'],<EOL>uid=new_key['<STR_LIT>'],<EOL>metadata=json.dumps(new_key['<STR_LIT>']),<EOL>lock=new_key['<STR_LIT>'],<EOL>type=new_key['<STR_LIT:type>'])))<EOL>return key_id<EOL>
Put a key inside the stash

        if key exists and modify true: delete and create
        if key exists and modify false: fail
        if key doesn't exist and modify true: fail
        if key doesn't exist and modify false: create

        `name` is unique and cannot be changed.

        `value` must be provided if the key didn't already exist, otherwise,
        the previous value will be retained.

        `created_at` will be left unmodified if the key
        already existed. Otherwise, the current time will be used.

        `modified_at` will be changed to the current time
        if the field is being modified.

        `metadata` will be updated if provided. If it wasn't
        provided the field from the existing key will be used and the
        same goes for the `uid` which will be generated if it didn't
        previously exist.

        `lock` will lock the key to prevent it from being modified or deleted

        `add` allows to add values to an existing key instead of overwriting.

        Returns the id of the key in the database