Potrzebuję pobierać pliki około 10gb każdy, następnie sprawdzać czy pobrały się poprawnie.
Za pomocą biblioteki requests
nie działa to zawsze (w zależności od łącza działa albo nie działa)
Przykład z użyciem requests
:
r = requests.get(url, stream=True)
print(url)
with open(save_product_name, 'wb') as fd:
for chunk in r.iter_content(chunk_size=512):
fd.write(chunk)
Szukając rozwiązania natknąłem się na post:
https://github.com/aio-libs/aiohttp/issues/2249#issuecomment-327896106
Zgodnie z zasadą copy-pasty-programmingu poczyniłem odpowiednie zmiany:
import asyncio
import sys
from time import time
import aiohttp
async def async_download(file_url: str):
total_size = 0
start = time()
print("start download " + file_url)
file = open("test.zip", 'wb')
async with aiohttp.ClientSession() as session:
async with session.get(file_url, timeout=None) as r:
while True:
chunk = await r.content.read(16144)
if not chunk:
break
total_size += len(chunk)
file.write(chunk)
message = f'{time() - start:0.2f}s, downloaded: {total_size / (1024 * 1024):0.0f}MB'
sys.stdout.write('\r' + message)
file.close()
sys.stdout.flush()
url = "http://speedtest.tele2.net/10GB.zip"
loop = asyncio.get_event_loop()
loop.run_until_complete(async_download(file_url=url))
Po uruchomieniu z innymi plikami (do których dostęp jest już za pomocą generowatnego tokena)
otrzymuję błąd:
Traceback (most recent call last):
File "C:\Users\Admin\Desktop\fsadas\test.py", line 28, in <module>
loop.run_until_complete(async_download(file_url=url))
File "C:\Users\Admin\AppData\Local\Programs\Python\Python38-32\lib\asyncio\base_events.py", line 616, in run_until_complete
return future.result()
File "C:\Users\Admin\Desktop\fsadas\test.py", line 16, in async_download
chunk = await r.content.read(16144)
File "C:\Users\Admin\AppData\Local\Programs\Python\Python38-32\lib\site-packages\aiohttp\streams.py", line 368, in read
await self._wait('read')
File "C:\Users\Admin\AppData\Local\Programs\Python\Python38-32\lib\site-packages\aiohttp\streams.py", line 296, in _wait
await waiter
aiohttp.client_exceptions.ClientPayloadError: Response payload is not completed
Moje pytania:
- Jak pobierać tak duże pliki?
- W jaki sposób napisać tą funkcję tak, aby można było otworzyć około 20 sesji pobierania jednocześnie, każdy w innym wątku (może lepiej subprocess)?
- W jaki sposób sprawdzać czy plik pobrał się poprawnie?
Chciałbym napisać testy do tej funkcji - będę wdzięczny za podpowiedzi