async def upload(self, source, destination="<STR_LIT>", *, write_into=False,<EOL>block_size=DEFAULT_BLOCK_SIZE):
source = pathlib.Path(source)<EOL>destination = pathlib.PurePosixPath(destination)<EOL>if not write_into:<EOL><INDENT>destination = destination / source.name<EOL><DEDENT>if await self.path_io.is_file(source):<EOL><INDENT>await self.make_directory(destination.parent)<EOL>async with self.path_io.open(source, mode="<STR_LIT:rb>") as file_in,self.upload_stream(destination) as stream:<EOL><INDENT>async for block in file_in.iter_by_block(block_size):<EOL><INDENT>await stream.write(block)<EOL><DEDENT><DEDENT><DEDENT>elif await self.path_io.is_dir(source):<EOL><INDENT>await self.make_directory(destination)<EOL>sources = collections.deque([source])<EOL>while sources:<EOL><INDENT>src = sources.popleft()<EOL>async for path in self.path_io.list(src):<EOL><INDENT>if write_into:<EOL><INDENT>relative = destination.name / path.relative_to(source)<EOL><DEDENT>else:<EOL><INDENT>relative = path.relative_to(source.parent)<EOL><DEDENT>if await self.path_io.is_dir(path):<EOL><INDENT>await self.make_directory(relative)<EOL>sources.append(path)<EOL><DEDENT>else:<EOL><INDENT>await self.upload(<EOL>path,<EOL>relative,<EOL>write_into=True,<EOL>block_size=block_size<EOL>)<EOL><DEDENT><DEDENT><DEDENT><DEDENT>
:py:func:`asyncio.coroutine`

High level upload method for uploading files and directories
recursively from file system.

:param source: source path of file or directory on client side
:type source: :py:class:`str` or :py:class:`pathlib.Path`

:param destination: destination path of file or directory on server
    side
:type destination: :py:class:`str` or :py:class:`pathlib.PurePosixPath`

:param write_into: write source into destination (if you want upload
    file and change it name, as well with directories)
:type write_into: :py:class:`bool`

:param block_size: block size for transaction
:type block_size: :py:class:`int`