Skip to content

Commit ae37481

Browse files
authored
Merge pull request #603 from xcp-ng/vml/concurrent-url-download
Allow concurrent use of url_download
2 parents d6deac9 + 88de4aa commit ae37481

1 file changed

Lines changed: 26 additions & 7 deletions

File tree

lib/common.py

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@
1010
import random
1111
import string
1212
import sys
13+
import tempfile
1314
import time
1415
import traceback
1516
from datetime import datetime
1617
from enum import Enum
1718
from functools import lru_cache
19+
from pathlib import Path
1820
from uuid import UUID
1921

2022
import requests
@@ -319,13 +321,30 @@ def strtobool(val: str | None) -> bool:
319321
raise ValueError("invalid truth value '{}'".format(val))
320322

321323
def url_download(url: str, filename: str) -> None:
322-
r = requests.get(url, stream=True)
323-
r.raise_for_status()
324-
tempfilename = filename + ".part"
325-
with open(tempfilename, 'wb') as fd:
326-
for chunk in r.iter_content(chunk_size=128):
327-
fd.write(chunk)
328-
os.rename(tempfilename, filename)
324+
"""
325+
Download the content of `url` to the `filename` destination.
326+
327+
A randomized filename is used during download to prevent file corruption on
328+
concurrent use. If the download fails then the temporary file is removed.
329+
"""
330+
destination = Path(filename)
331+
destination.parent.mkdir(parents=True, exist_ok=True)
332+
with requests.get(url, stream=True) as r:
333+
r.raise_for_status()
334+
temp_name: str | None = None
335+
try:
336+
with tempfile.NamedTemporaryFile(
337+
dir=destination.parent, prefix=f"{destination.name}.", suffix=".part", delete=False
338+
) as fd:
339+
temp_name = fd.name
340+
for chunk in r.iter_content(chunk_size=64 * 1024):
341+
fd.write(chunk)
342+
except BaseException:
343+
if temp_name is not None:
344+
os.unlink(temp_name)
345+
raise
346+
else:
347+
os.rename(temp_name, filename)
329348

330349
def randid(length: int = 6) -> str:
331350
"""

0 commit comments

Comments
 (0)