Source code for scopesim.server.download_utils

# -*- coding: utf-8 -*-
"""
Used only by the `database` and `github_utils` submodules.
"""

from zipfile import ZipFile
from pathlib import Path
from shutil import get_terminal_size

import requests
from requests.packages.urllib3.util.retry import Retry
from requests.adapters import HTTPAdapter
from requests_cache import CachedSession
from tqdm import tqdm
# from tqdm.contrib.logging import logging_redirect_tqdm
# put with logging_redirect_tqdm(loggers=all_loggers): around tqdm



HTTP_RETRY_CODES = [403, 404, 429, 500, 501, 502, 503]


def _make_tqdm_kwargs(desc: str = ""):
    width, _ = get_terminal_size((50, 20))
    bar_width = max(int(.8 * width) - 30 - len(desc), 10)
    tqdm_kwargs = {
        "bar_format": f"{{l_bar}}{{bar:{bar_width}}}{{r_bar}}{{bar:-{bar_width}b}}",
        "colour": "green",
        "desc": desc
        }
    return tqdm_kwargs


def _create_session(cached: bool = False, cache_name: str = ""):
    if cached:
        return CachedSession(cache_name)
    return requests.Session()


[docs] def initiate_download(pkg_url: str, cached: bool = False, cache_name: str = "", total: int = 5, backoff_factor: int = 2): retry_strategy = Retry(total=total, backoff_factor=backoff_factor, status_forcelist=HTTP_RETRY_CODES, allowed_methods=["GET"]) adapter = HTTPAdapter(max_retries=retry_strategy) with _create_session(cached, cache_name) as session: session.mount("https://", adapter) response = session.get(pkg_url, stream=True) return response
[docs] def handle_download(response, save_path: Path, pkg_name: str, padlen: int, chunk_size: int = 128, disable_bar=False) -> None: tqdm_kwargs = _make_tqdm_kwargs(f"Downloading {pkg_name:<{padlen}}") total = int(response.headers.get("content-length", 0)) # Turn this into non-nested double with block in Python 3.9 or 10 (?) with save_path.open("wb") as file_outer: with tqdm.wrapattr(file_outer, "write", miniters=1, total=total, **tqdm_kwargs, disable=disable_bar) as file_inner: for chunk in response.iter_content(chunk_size=chunk_size): file_inner.write(chunk)
[docs] def handle_unzipping(save_path: Path, save_dir: Path, pkg_name: str, padlen: int) -> None: with ZipFile(save_path, "r") as zip_ref: namelist = zip_ref.namelist() tqdm_kwargs = _make_tqdm_kwargs(f"Extracting {pkg_name:<{padlen}}") for file in tqdm(iterable=namelist, total=len(namelist), **tqdm_kwargs): zip_ref.extract(file, save_dir)