This repository has been archived by the owner on Aug 7, 2023. It is now read-only.
What is this chunked upload
?
#380
Answered
by
jnsougata
AyushSehrawat
asked this question in
Help
-
I was going through http docs of Deta and found https://docs.deta.sh/docs/drive/http#initialize-chunked-upload... Can anyone tell what this is about ? Something like uploading a file larger than x mb chunks by chunks via multiple requests ? |
Beta Was this translation helpful? Give feedback.
Answered by
jnsougata
Aug 14, 2022
Replies: 1 comment 8 replies
-
Yes you got it right! async def _push_file(self, drive_name: str, remote_path: str, path: PathLike):
if isinstance(path, str):
file = open(path, 'rb')
elif isinstance(path, bytes):
file = io.BytesIO(path)
else:
raise ValueError('path must be a string or bytes')
chunks = file.read()
if not len(chunks) > self.__SINGLE_REQ_UPLOAD_SIZE:
ep = self.__drive_root + drive_name + '/files?name=' + quote_plus(remote_path)
resp = await self.__session.post(ep, headers=self.__drive_headers, data=chunks)
file.close()
if resp.status == 201:
return await resp.json()
elif resp.status == 400:
raise BadRequest(self.__err(await resp.json()))
else:
raise Exception(self.__err(await resp.json()))
ep = self.__drive_root + drive_name + '/uploads?name=' + quote_plus(remote_path)
resp = await self.__session.post(ep, headers=self.__drive_headers)
if resp.status == 202:
upload_id = (await resp.json())['upload_id']
chunked = [
chunks[i:i+self.__SINGLE_REQ_UPLOAD_SIZE]
for i in range(0, len(chunks), self.__SINGLE_REQ_UPLOAD_SIZE)
]
uploads = []
for i, chunk in enumerate(chunked[:-1]):
post_ep = (
f"{self.__drive_root}{drive_name}/uploads/{upload_id}/parts?name={remote_path}&part={i+1}"
)
uploads.append(
asyncio.create_task(self.__session.post(post_ep, headers=self.__drive_headers, data=chunk))
)
gathered = await asyncio.gather(*uploads)
file.close()
for item in gathered:
if isinstance(item, Exception):
abort_ep = f"{self.__drive_root}{drive_name}/uploads/{upload_id}?name={remote_path}"
resp = await self.__session.delete(abort_ep, headers=self.__drive_headers)
if resp.status == 200:
return await resp.json()
if resp.status == 400:
raise BadRequest(self.__err(await resp.json()))
if resp.status == 404:
raise NotFound(self.__err(await resp.json()))
patch_ep = f"{self.__drive_root}{drive_name}/uploads/{upload_id}?name={remote_path}"
resp = await self.__session.patch(patch_ep, headers=self.__drive_headers, data=chunked[-1])
if resp.status == 200:
return await resp.json()
if resp.status == 400:
raise BadRequest(self.__err(await resp.json()))
if resp.status == 404:
raise NotFound(self.__err(await resp.json())) |
Beta Was this translation helpful? Give feedback.
8 replies
Answer selected by
AyushSehrawat
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Yes you got it right!
Here's an example how I implemented it my async deta library! the quality of the code is a bit nasty...though