assets/__init__.py (62 lines of code) (raw):

# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one # or more contributor license agreements. Licensed under the Elastic License; # you may not use this file except in compliance with the Elastic License. import os from pathlib import Path assets_dir = Path(__file__).parent branches = ("production", "staging", "snapshot") def walk(): """ Traverse all the local assets. :return: generator yielding (branch, package, version) of all the local assets """ for branch in branches: for asset_branch, packages, _ in os.walk(assets_dir / branch): for package in packages: if package.startswith("."): continue for _, versions, _ in os.walk(Path(asset_branch) / package): for version in versions: yield branch, package, version break break def get_meta(branch, package, version): """ Get the meta-data of a local asset. :param branch: one among 'production', 'staging', 'snapshot' :param package: package name, ex. 'endpoint' :param version: package version, ex. '8.3.0' :return: dictionary containing the meta-data """ import yaml meta_filename = assets_dir / branch / package / version / "meta.yml" if meta_filename.exists(): with open(meta_filename) as f: return yaml.safe_load(f) def get_local_assets(package, path): """ Retrieve the list of a package's local assets. :param package: name and version of the package, ex. 'endpoint/8.3.0' :param path: path on disk searched for the assets :return: generator yielding (path, content) pairs as they are traversed """ saved_cwd = os.getcwd() os.chdir(path) try: if not Path(package).exists(): raise ValueError(f"Package not found: {package}") for root, _, files in os.walk(package): for file in files: with open(Path(root) / file, "rb") as f: yield f.name, f.read() finally: os.chdir(saved_cwd) def get_remote_assets(package, repo): """ Retrieve the list of a package's remote assets. :param package: name and version of the package, ex. 'endpoint/8.3.0' :param repo: repository object searched for the assets :return: generator yielding the remote assets entries """ from github import GithubException for branch in branches: try: entries = repo.get_contents(package, ref=branch) except GithubException: continue while entries: entry = entries.pop(0) if entry.type == "dir": entries += repo.get_contents(entry.path, ref=branch) else: yield entry return raise ValueError(f"Package not found: {package}") def download_assets(entries): """ Download the assets of a package. :param entries: assets entries as generated by :py:func:`.get_assets` :return: generator yielding (path, content) pairs as they get ready """ from requests_futures.sessions import FuturesSession from concurrent.futures import as_completed session = FuturesSession() futures = [] for entry in entries: future = session.get(entry.download_url) future.entry = entry futures.append(future) for future in as_completed(futures): res = future.result() res.raise_for_status() yield future.entry.path, res.content session.close()