def create_file(self, path, fp, force=False, update=False):
if '<STR_LIT:b>' not in fp.mode:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>path = norm_remote_path(path)<EOL>directory, fname = os.path.split(path)<EOL>directories = directory.split(os.path.sep)<EOL>parent = self<EOL>for directory in directories:<EOL><INDENT>if directory:<EOL><INDENT>parent = parent.create_folder(directory, exist_ok=True)<EOL><DEDENT><DEDENT>url = parent._new_file_url<EOL>connection_error = False<EOL>if file_empty(fp):<EOL><INDENT>response = self._put(url, params={'<STR_LIT:name>': fname}, data=b'<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>try:<EOL><INDENT>response = self._put(url, params={'<STR_LIT:name>': fname}, data=fp)<EOL><DEDENT>except ConnectionError:<EOL><INDENT>connection_error = True<EOL><DEDENT><DEDENT>if connection_error or response.status_code == <NUM_LIT>:<EOL><INDENT>if not force and not update:<EOL><INDENT>file_size_bytes = get_local_file_size(fp)<EOL>large_file_cutoff = <NUM_LIT:2>**<NUM_LIT:20> <EOL>if connection_error and file_size_bytes < large_file_cutoff:<EOL><INDENT>msg = (<EOL>"<STR_LIT>" +<EOL>"<STR_LIT>" +<EOL>"<STR_LIT>"<EOL>).format(path)<EOL>raise RuntimeError(msg)<EOL><DEDENT>else:<EOL><INDENT>raise FileExistsError(path)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>for file_ in self.files:<EOL><INDENT>if norm_remote_path(file_.path) == path:<EOL><INDENT>if not force:<EOL><INDENT>if checksum(path) == file_.hashes.get('<STR_LIT>'):<EOL><INDENT>break<EOL><DEDENT><DEDENT>fp.seek(<NUM_LIT:0>)<EOL>file_.update(fp)<EOL>break<EOL><DEDENT><DEDENT>else:<EOL><INDENT>raise RuntimeError("<STR_LIT>"<EOL>"<STR_LIT>".format(path))<EOL><DEDENT><DEDENT><DEDENT>
Store a new file at `path` in this storage.

        The contents of the file descriptor `fp` (opened in 'rb' mode)
        will be uploaded to `path` which is the full path at
        which to store the file.

        To force overwrite of an existing file, set `force=True`.
        To overwrite an existing file only if the files differ, set `update=True`