Skip to content

Reference for ultralytics/utils/uploads.py

Improvements

This page is sourced from https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/uploads.py. Have an improvement or example to add? Open a Pull Request — thank you! 🙏


class ultralytics.utils.uploads._ProgressReader

_ProgressReader(self, file_path, pbar)

File wrapper that reports read progress for upload monitoring.

Args

NameTypeDescriptionDefault
file_pathrequired
pbarrequired

Methods

NameDescription
__len__Return file size for Content-Length header.
closeClose the file.
readRead data and update progress bar.
Source code in ultralytics/utils/uploads.pyView on GitHub
class _ProgressReader:
    """File wrapper that reports read progress for upload monitoring."""

    def __init__(self, file_path, pbar):
        self.file = open(file_path, "rb")
        self.pbar = pbar
        self._size = os.path.getsize(file_path)


method ultralytics.utils.uploads._ProgressReader.__len__

def __len__(self)

Return file size for Content-Length header.

Source code in ultralytics/utils/uploads.pyView on GitHub
def __len__(self):
    """Return file size for Content-Length header."""
    return self._size


method ultralytics.utils.uploads._ProgressReader.close

def close(self)

Close the file.

Source code in ultralytics/utils/uploads.pyView on GitHub
def close(self):
    """Close the file."""
    self.file.close()


method ultralytics.utils.uploads._ProgressReader.read

def read(self, size = -1)

Read data and update progress bar.

Args

NameTypeDescriptionDefault
size-1
Source code in ultralytics/utils/uploads.pyView on GitHub
def read(self, size=-1):
    """Read data and update progress bar."""
    data = self.file.read(size)
    if data and self.pbar:
        self.pbar.update(len(data))
    return data





function ultralytics.utils.uploads.safe_upload

def safe_upload(
    file: str | Path,
    url: str,
    headers: dict | None = None,
    retry: int = 2,
    timeout: int = 600,
    progress: bool = False,
) -> bool

Upload a file to a URL with retry logic and optional progress bar.

Args

NameTypeDescriptionDefault
filestr | PathPath to the file to upload.required
urlstrThe URL endpoint to upload the file to (e.g., signed GCS URL).required
headersdict, optionalAdditional headers to include in the request.None
retryint, optionalNumber of retry attempts on failure (default: 2 for 3 total attempts).2
timeoutint, optionalRequest timeout in seconds.600
progressbool, optionalWhether to display a progress bar during upload.False

Returns

TypeDescription
boolTrue if upload succeeded, False otherwise.

Examples

>>> from ultralytics.utils.uploads import safe_upload
>>> success = safe_upload("model.pt", "https://storage.googleapis.com/...", progress=True)
Source code in ultralytics/utils/uploads.pyView on GitHub
def safe_upload(
    file: str | Path,
    url: str,
    headers: dict | None = None,
    retry: int = 2,
    timeout: int = 600,
    progress: bool = False,
) -> bool:
    """Upload a file to a URL with retry logic and optional progress bar.

    Args:
        file (str | Path): Path to the file to upload.
        url (str): The URL endpoint to upload the file to (e.g., signed GCS URL).
        headers (dict, optional): Additional headers to include in the request.
        retry (int, optional): Number of retry attempts on failure (default: 2 for 3 total attempts).
        timeout (int, optional): Request timeout in seconds.
        progress (bool, optional): Whether to display a progress bar during upload.

    Returns:
        (bool): True if upload succeeded, False otherwise.

    Examples:
        >>> from ultralytics.utils.uploads import safe_upload
        >>> success = safe_upload("model.pt", "https://storage.googleapis.com/...", progress=True)
    """
    import requests

    file = Path(file)
    if not file.exists():
        raise FileNotFoundError(f"File not found: {file}")

    file_size = file.stat().st_size
    desc = f"Uploading {file.name}"

    # Prepare headers (Content-Length set automatically from file size)
    upload_headers = {"Content-Type": "application/octet-stream"}
    if headers:
        upload_headers.update(headers)

    last_error = None
    for attempt in range(retry + 1):
        pbar = None
        reader = None
        try:
            if progress:
                pbar = TQDM(total=file_size, desc=desc, unit="B", unit_scale=True, unit_divisor=1024)
            reader = _ProgressReader(file, pbar)

            r = requests.put(url, data=reader, headers=upload_headers, timeout=timeout)
            r.raise_for_status()
            reader.close()
            reader = None  # Prevent double-close in finally
            if pbar:
                pbar.close()
                pbar = None
            LOGGER.info(f"Uploaded {file.name} ✅")
            return True

        except requests.exceptions.HTTPError as e:
            status = e.response.status_code if e.response is not None else 0
            if 400 <= status < 500 and status not in {408, 429}:
                LOGGER.warning(f"{desc} failed: {status} {getattr(e.response, 'reason', '')}")
                return False
            last_error = f"HTTP {status}"
        except Exception as e:
            last_error = str(e)
        finally:
            if reader:
                reader.close()
            if pbar:
                pbar.close()

        if attempt < retry:
            wait_time = 2 ** (attempt + 1)
            LOGGER.warning(f"{desc} failed ({last_error}), retrying {attempt + 1}/{retry} in {wait_time}s...")
            sleep(wait_time)

    LOGGER.warning(f"{desc} failed after {retry + 1} attempts: {last_error}")
    return False





📅 Created 0 days ago ✏️ Updated 0 days ago
glenn-jocher