VerokeAI/Object_tracking_boxmot
0
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 