CoolFace
Apppublic

VerokeAI/Object_tracking_boxmot

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes
utils.py249 linesDownload Raw Back to hub
1# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license2 3import os4import platform5import random6import threading7import time8from pathlib import Path9 10import requests11 12from ultralytics.utils import (13    ARGV,14    ENVIRONMENT,15    IS_COLAB,16    IS_GIT_DIR,17    IS_PIP_PACKAGE,18    LOGGER,19    ONLINE,20    RANK,21    SETTINGS,22    TESTS_RUNNING,23    TQDM,24    TryExcept,25    __version__,26    colorstr,27    get_git_origin_url,28)29from ultralytics.utils.downloads import GITHUB_ASSETS_NAMES30 31HUB_API_ROOT = os.environ.get("ULTRALYTICS_HUB_API", "https://api.ultralytics.com")32HUB_WEB_ROOT = os.environ.get("ULTRALYTICS_HUB_WEB", "https://hub.ultralytics.com")33 34PREFIX = colorstr("Ultralytics HUB: ")35HELP_MSG = "If this issue persists please visit https://github.com/ultralytics/hub/issues for assistance."36 37 38def request_with_credentials(url: str) -> any:39    """40    Make an AJAX request with cookies attached in a Google Colab environment.41 42    Args:43        url (str): The URL to make the request to.44 45    Returns:46        (Any): The response data from the AJAX request.47 48    Raises:49        OSError: If the function is not run in a Google Colab environment.50    """51    if not IS_COLAB:52        raise OSError("request_with_credentials() must run in a Colab environment")53    from google.colab import output  # noqa54    from IPython import display  # noqa55 56    display.display(57        display.Javascript(58            f"""59            window._hub_tmp = new Promise((resolve, reject) => {{60                const timeout = setTimeout(() => reject("Failed authenticating existing browser session"), 5000)61                fetch("{url}", {{62                    method: 'POST',63                    credentials: 'include'64                }})65                    .then((response) => resolve(response.json()))66                    .then((json) => {{67                    clearTimeout(timeout);68                    }}).catch((err) => {{69                    clearTimeout(timeout);70                    reject(err);71                }});72            }});73            """74        )75    )76    return output.eval_js("_hub_tmp")77 78 79def requests_with_progress(method, url, **kwargs):80    """81    Make an HTTP request using the specified method and URL, with an optional progress bar.82 83    Args:84        method (str): The HTTP method to use (e.g. 'GET', 'POST').85        url (str): The URL to send the request to.86        **kwargs (Any): Additional keyword arguments to pass to the underlying `requests.request` function.87 88    Returns:89        (requests.Response): The response object from the HTTP request.90 91    Notes:92        - If 'progress' is set to True, the progress bar will display the download progress for responses with a known93          content length.94        - If 'progress' is a number then progress bar will display assuming content length = progress.95    """96    progress = kwargs.pop("progress", False)97    if not progress:98        return requests.request(method, url, **kwargs)99    response = requests.request(method, url, stream=True, **kwargs)100    total = int(response.headers.get("content-length", 0) if isinstance(progress, bool) else progress)  # total size101    try:102        pbar = TQDM(total=total, unit="B", unit_scale=True, unit_divisor=1024)103        for data in response.iter_content(chunk_size=1024):104            pbar.update(len(data))105        pbar.close()106    except requests.exceptions.ChunkedEncodingError:  # avoid 'Connection broken: IncompleteRead' warnings107        response.close()108    return response109 110 111def smart_request(method, url, retry=3, timeout=30, thread=True, code=-1, verbose=True, progress=False, **kwargs):112    """113    Make an HTTP request using the 'requests' library, with exponential backoff retries up to a specified timeout.114 115    Args:116        method (str): The HTTP method to use for the request. Choices are 'post' and 'get'.117        url (str): The URL to make the request to.118        retry (int, optional): Number of retries to attempt before giving up.119        timeout (int, optional): Timeout in seconds after which the function will give up retrying.120        thread (bool, optional): Whether to execute the request in a separate daemon thread.121        code (int, optional): An identifier for the request, used for logging purposes.122        verbose (bool, optional): A flag to determine whether to print out to console or not.123        progress (bool, optional): Whether to show a progress bar during the request.124        **kwargs (Any): Keyword arguments to be passed to the requests function specified in method.125 126    Returns:127        (requests.Response): The HTTP response object. If the request is executed in a separate thread, returns None.128    """129    retry_codes = (408, 500)  # retry only these codes130 131    @TryExcept(verbose=verbose)132    def func(func_method, func_url, **func_kwargs):133        """Make HTTP requests with retries and timeouts, with optional progress tracking."""134        r = None  # response135        t0 = time.time()  # initial time for timer136        for i in range(retry + 1):137            if (time.time() - t0) > timeout:138                break139            r = requests_with_progress(func_method, func_url, **func_kwargs)  # i.e. get(url, data, json, files)140            if r.status_code < 300:  # return codes in the 2xx range are generally considered "good" or "successful"141                break142            try:143                m = r.json().get("message", "No JSON message.")144            except AttributeError:145                m = "Unable to read JSON."146            if i == 0:147                if r.status_code in retry_codes:148                    m += f" Retrying {retry}x for {timeout}s." if retry else ""149                elif r.status_code == 429:  # rate limit150                    h = r.headers  # response headers151                    m = (152                        f"Rate limit reached ({h['X-RateLimit-Remaining']}/{h['X-RateLimit-Limit']}). "153                        f"Please retry after {h['Retry-After']}s."154                    )155                if verbose:156                    LOGGER.warning(f"{PREFIX}{m} {HELP_MSG} ({r.status_code} #{code})")157                if r.status_code not in retry_codes:158                    return r159            time.sleep(2**i)  # exponential standoff160        return r161 162    args = method, url163    kwargs["progress"] = progress164    if thread:165        threading.Thread(target=func, args=args, kwargs=kwargs, daemon=True).start()166    else:167        return func(*args, **kwargs)168 169 170class Events:171    """172    A class for collecting anonymous event analytics.173 174    Event analytics are enabled when sync=True in settings and disabled when sync=False. Run 'yolo settings' to see and175    update settings.176 177    Attributes:178        url (str): The URL to send anonymous events.179        rate_limit (float): The rate limit in seconds for sending events.180        metadata (dict): A dictionary containing metadata about the environment.181        enabled (bool): A flag to enable or disable Events based on certain conditions.182    """183 184    url = "https://www.google-analytics.com/mp/collect?measurement_id=G-X8NCJYTQXM&api_secret=QLQrATrNSwGRFRLE-cbHJw"185 186    def __init__(self):187        """Initialize the Events object with default values for events, rate_limit, and metadata."""188        self.events = []  # events list189        self.rate_limit = 30.0  # rate limit (seconds)190        self.t = 0.0  # rate limit timer (seconds)191        self.metadata = {192            "cli": Path(ARGV[0]).name == "yolo",193            "install": "git" if IS_GIT_DIR else "pip" if IS_PIP_PACKAGE else "other",194            "python": ".".join(platform.python_version_tuple()[:2]),  # i.e. 3.10195            "version": __version__,196            "env": ENVIRONMENT,197            "session_id": round(random.random() * 1e15),198            "engagement_time_msec": 1000,199        }200        self.enabled = (201            SETTINGS["sync"]202            and RANK in {-1, 0}203            and not TESTS_RUNNING204            and ONLINE205            and (IS_PIP_PACKAGE or get_git_origin_url() == "https://github.com/ultralytics/ultralytics.git")206        )207 208    def __call__(self, cfg):209        """210        Attempt to add a new event to the events list and send events if the rate limit is reached.211 212        Args:213            cfg (IterableSimpleNamespace): The configuration object containing mode and task information.214        """215        if not self.enabled:216            # Events disabled, do nothing217            return218 219        # Attempt to add to events220        if len(self.events) < 25:  # Events list limited to 25 events (drop any events past this)221            params = {222                **self.metadata,223                "task": cfg.task,224                "model": cfg.model if cfg.model in GITHUB_ASSETS_NAMES else "custom",225            }226            if cfg.mode == "export":227                params["format"] = cfg.format228            self.events.append({"name": cfg.mode, "params": params})229 230        # Check rate limit231        t = time.time()232        if (t - self.t) < self.rate_limit:233            # Time is under rate limiter, wait to send234            return235 236        # Time is over rate limiter, send now237        data = {"client_id": SETTINGS["uuid"], "events": self.events}  # SHA-256 anonymized UUID hash and events list238 239        # POST equivalent to requests.post(self.url, json=data)240        smart_request("post", self.url, json=data, retry=0, verbose=False)241 242        # Reset events and rate limit timer243        self.events = []244        self.t = t245 246 247# Run below code on hub/utils init -------------------------------------------------------------------------------------248events = Events()249