downloader.py 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. from os.path import abspath as absolute_path
  2. from time import time
  3. import aiofiles
  4. from wbb import aiohttpsession as session
  5. from wbb.core.tasks import add_task
  6. def ensure_status(status_code: int):
  7. if status_code < 200 or status_code >= 300:
  8. raise Exception(f"HttpProcessingError: {status_code}")
  9. async def download_url(
  10. url,
  11. file_path,
  12. chunk_size,
  13. ):
  14. file_path = file_path or url.split("/")[-1][:20]
  15. async with session.get(url) as response:
  16. ensure_status(response.status)
  17. async with aiofiles.open(file_path, "wb") as f:
  18. # Save content in file using aiohttp streamReader.
  19. async for chunk in response.content.iter_chunked(
  20. chunk_size
  21. ):
  22. await f.write(chunk)
  23. return absolute_path(file_path)
  24. async def download(
  25. url: str,
  26. file_path: str = None,
  27. chunk_size: int = 1000000, # 1MB chunk
  28. task_id: int = int(time()),
  29. ):
  30. """
  31. :url: url where the file is located
  32. :file_path: path/to/file
  33. :chunk_size: size of a single chunk
  34. Returns:
  35. (asyncio.Task, task_id), With which you can await
  36. the task, track task progress or cancel it.
  37. """
  38. # Create a task and add it to main tasks dict
  39. # So we can cancel it using .cancelTask
  40. task, task_id = await add_task(
  41. download_url,
  42. "Downloader",
  43. url=url,
  44. file_path=file_path,
  45. chunk_size=chunk_size,
  46. )
  47. return task, task_id