(url: str, dest: Path, *, timeout: float)
| 86 | |
| 87 | |
| 88 | def _download(url: str, dest: Path, *, timeout: float) -> int: |
| 89 | dest.parent.mkdir(parents=True, exist_ok=True) |
| 90 | try: |
| 91 | with urllib.request.urlopen(url, timeout=timeout) as resp, dest.open("wb") as fh: |
| 92 | total = 0 |
| 93 | while True: |
| 94 | chunk = resp.read(1024 * 1024) |
| 95 | if not chunk: |
| 96 | return total |
| 97 | fh.write(chunk) |
| 98 | total += len(chunk) |
| 99 | except urllib.error.HTTPError as exc: |
| 100 | detail = exc.read().decode("utf-8", errors="replace") |
| 101 | raise ModlyCliError(f"HTTP {exc.code} while downloading {url}: {detail}", code=f"HTTP_{exc.code}", http_status=exc.code) from exc |
| 102 | except urllib.error.URLError as exc: |
| 103 | raise ModlyCliError(f"Cannot download {url}: {exc.reason}", code="DOWNLOAD_FAILED") from exc |
| 104 | except OSError as exc: |
| 105 | raise ModlyCliError(f"Cannot write to {dest}: {exc}", code="WRITE_FAILED") from exc |
| 106 | |
| 107 | |
| 108 | def _multipart_form(fields: dict[str, str], file_field: str, file_path: Path) -> tuple[bytes, str]: |
no test coverage detected