Ecco una versione che si scarica il file in un bytearray
in un thread separato.
Come già detto in altre risposte e commenti, ci sono altri alternativs che sono sviluppati con operazioni asincrone in mente, in modo da non leggere troppo in la decisione di andare con threading
, è solo per dimostrare che il concetto (e a causa della convenienza, in quanto si tratta con python).
Nel codice qui sotto, se la dimensione del file è noto, ogni .
corrisponde all ' 1%. Come bonus, scaricato e numero totale di byte verrà stampato all'inizio della linea (1234 B / 1234567 B)
. Se la dimensione non è noto, la soluzione di ripiego è quello di avere ogni .
rappresentano un pezzo.
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()
Non tenere a mente che ho lasciato fuori il blocco per la protezione contro l'accesso simultaneo a stdout
per ridurre il rumore. Ho anche lasciato fuori la scrittura bytarray
per file alla fine (o la scrittura dei pezzi di file ricevuto, se il file è di grandi dimensioni), ma tenete a mente che si desidera utilizzare un lucchetto per questo e se si di leggere e/o scrivere lo stesso file in qualsiasi altra parte del vostro script.