Aici e o versiune care va descărca fișiere într-un bytearray
într-un thread separat.
Așa cum am menționat în alte răspunsuri și comentarii, există și alte alternativs, care sunt dezvoltate cu async operațiuni în minte, așa că nu citesc prea mult în decizia de a merge cu threading
e doar pentru a demonstra conceptul (și din cauza de comoditate, deoarece acesta vine cu python).
În codul de mai jos, dacă dimensiunea fișierului este cunoscut, fiecare .
va corespunde la 1%. Ca un bonus, descărcat și numărul total de octeți vor fi tipărite la începutul linie de genul (1234 B / 1234567 B)
. Dacă dimensiunea nu este cunoscut, soluție de rezervă este de a avea fiecare .
reprezintă o bucată.
import requests
import threading
def download_file(url: str):
headers = {"<some_key>": "<some_value>"}
data = bytearray()
with requests.get(url, headers=headers, stream=True) as request:
if file_size := request.headers.get("Content-Length"):
file_size = int(file_size)
else:
file_size = None
received = 0
for chunk in request.iter_content(chunk_size=2**15):
received += len(chunk)
data += chunk
try:
num_dots = int(received * 100 / file_size)
print(
f"({received} B/{file_size} B) "
+ "." * num_dots, end="\r"
)
except TypeError:
print(".", end="")
print("\nDone!")
url = "<some_url>"
thread = threading.Thread(target=download_file, args=(url,))
thread.start()
# Do something in the meantime
thread.join()
Nu păstrați în minte că am plecat de blocare pentru a proteja împotriva accesul simultan la stdout
pentru a reduce zgomotul. De asemenea, am lăsat de scris bytarray
la dosar, la sfârșitul (sau scris pe bucăți de fișiere în care acestea sunt primite dacă fișierul este mare), dar păstrează în minte că, poate doriți să utilizați un sistem de blocare pentru că la fel de bine, dacă ai citit și/sau scrie la același fișier în orice altă parte a script-ul.