ultralytics-opencv-headless 8.3.248__py3-none-any.whl → 8.3.249__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
ultralytics/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
2
2
 
3
- __version__ = "8.3.248"
3
+ __version__ = "8.3.249"
4
4
 
5
5
  import importlib
6
6
  import os
@@ -129,7 +129,7 @@ class ObjectCounter(BaseSolution):
129
129
  str.capitalize(key): f"{'IN ' + str(value['IN']) if self.show_in else ''} "
130
130
  f"{'OUT ' + str(value['OUT']) if self.show_out else ''}".strip()
131
131
  for key, value in self.classwise_count.items()
132
- if value["IN"] != 0 or (value["OUT"] != 0 and (self.show_in or self.show_out))
132
+ if (value["IN"] != 0 and self.show_in) or (value["OUT"] != 0 and self.show_out)
133
133
  }
134
134
  if labels_dict:
135
135
  self.annotator.display_analytics(plot_im, labels_dict, (104, 31, 17), (255, 255, 255), self.margin)
@@ -32,6 +32,85 @@ except (AssertionError, ImportError):
32
32
  _api_key = None
33
33
 
34
34
 
35
+ def resolve_platform_uri(uri, hard=True):
36
+ """Resolve ul:// URIs to signed URLs by authenticating with Ultralytics Platform.
37
+
38
+ Formats:
39
+ ul://username/datasets/slug -> Returns signed URL to NDJSON file
40
+ ul://username/project/model -> Returns signed URL to .pt file
41
+
42
+ Args:
43
+ uri (str): Platform URI starting with "ul://".
44
+ hard (bool): Whether to raise an error if resolution fails (FileNotFoundError only).
45
+
46
+ Returns:
47
+ (str | None): Signed URL on success, None if not found and hard=False.
48
+
49
+ Raises:
50
+ ValueError: If API key is missing/invalid or URI format is wrong.
51
+ PermissionError: If access is denied.
52
+ RuntimeError: If resource is not ready (e.g., dataset still processing).
53
+ FileNotFoundError: If resource not found and hard=True.
54
+ ConnectionError: If network request fails and hard=True.
55
+ """
56
+ import requests
57
+
58
+ path = uri[5:] # Remove "ul://"
59
+ parts = path.split("/")
60
+
61
+ api_key = os.getenv("ULTRALYTICS_API_KEY") or SETTINGS.get("api_key")
62
+ if not api_key:
63
+ raise ValueError(f"ULTRALYTICS_API_KEY required for '{uri}'. Get key at https://alpha.ultralytics.com/settings")
64
+
65
+ base = "https://alpha.ultralytics.com/api/v1"
66
+ headers = {"Authorization": f"Bearer {api_key}"}
67
+
68
+ # ul://username/datasets/slug
69
+ if len(parts) == 3 and parts[1] == "datasets":
70
+ username, _, slug = parts
71
+ url = f"{base}/datasets/{username}/{slug}/export"
72
+
73
+ # ul://username/project/model
74
+ elif len(parts) == 3:
75
+ username, project, model = parts
76
+ url = f"{base}/models/{username}/{project}/{model}/download"
77
+
78
+ else:
79
+ raise ValueError(f"Invalid platform URI: {uri}. Use ul://user/datasets/name or ul://user/project/model")
80
+
81
+ LOGGER.info(f"Resolving {uri} from Ultralytics Platform...")
82
+
83
+ try:
84
+ r = requests.head(url, headers=headers, allow_redirects=False, timeout=30)
85
+
86
+ # Handle redirect responses (301, 302, 303, 307, 308)
87
+ if 300 <= r.status_code < 400 and "location" in r.headers:
88
+ return r.headers["location"] # Return signed URL
89
+
90
+ # Handle error responses
91
+ if r.status_code == 401:
92
+ raise ValueError(f"Invalid ULTRALYTICS_API_KEY for '{uri}'")
93
+ if r.status_code == 403:
94
+ raise PermissionError(f"Access denied for '{uri}'. Check dataset/model visibility settings.")
95
+ if r.status_code == 404:
96
+ if hard:
97
+ raise FileNotFoundError(f"Not found on platform: {uri}")
98
+ LOGGER.warning(f"Not found on platform: {uri}")
99
+ return None
100
+ if r.status_code == 409:
101
+ raise RuntimeError(f"Resource not ready: {uri}. Dataset may still be processing.")
102
+
103
+ # Unexpected response
104
+ r.raise_for_status()
105
+ raise RuntimeError(f"Unexpected response from platform for '{uri}': {r.status_code}")
106
+
107
+ except requests.exceptions.RequestException as e:
108
+ if hard:
109
+ raise ConnectionError(f"Failed to resolve {uri}: {e}") from e
110
+ LOGGER.warning(f"Failed to resolve {uri}: {e}")
111
+ return None
112
+
113
+
35
114
  def _interp_plot(plot, n=101):
36
115
  """Interpolate plot curve data from 1000 to n points to reduce storage size."""
37
116
  import numpy as np
@@ -592,7 +592,7 @@ def check_file(file, suffix="", download=True, download_dir=".", hard=True):
592
592
  """Search/download file (if necessary), check suffix (if provided), and return path.
593
593
 
594
594
  Args:
595
- file (str): File name or path.
595
+ file (str): File name or path, or platform URI (ul://username/datasets/name).
596
596
  suffix (str | tuple): Acceptable suffix or tuple of suffixes to validate against the file.
597
597
  download (bool): Whether to download the file if it doesn't exist locally.
598
598
  download_dir (str): Directory to download the file to.
@@ -610,6 +610,18 @@ def check_file(file, suffix="", download=True, download_dir=".", hard=True):
610
610
  or file.lower().startswith("grpc://")
611
611
  ): # file exists or gRPC Triton images
612
612
  return file
613
+ elif download and file.lower().startswith("ul://"): # Ultralytics Platform URI
614
+ from ultralytics.utils.callbacks.platform import resolve_platform_uri
615
+
616
+ url = resolve_platform_uri(file, hard=hard) # Convert to signed HTTPS URL
617
+ if url is None:
618
+ return [] # Not found, soft fail (consistent with file search behavior)
619
+ local_file = Path(download_dir) / url2file(url)
620
+ if local_file.exists():
621
+ LOGGER.info(f"Found {clean_url(url)} locally at {local_file}")
622
+ else:
623
+ downloads.safe_download(url=url, file=local_file, unzip=False)
624
+ return str(local_file)
613
625
  elif download and file.lower().startswith(("https://", "http://", "rtsp://", "rtmp://", "tcp://")): # download
614
626
  url = file # warning: Pathlib turns :// -> :/
615
627
  file = Path(download_dir) / url2file(file) # '%2F' to '/', split https://url.com/file.txt?auth
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ultralytics-opencv-headless
3
- Version: 8.3.248
3
+ Version: 8.3.249
4
4
  Summary: Ultralytics YOLO 🚀 for SOTA object detection, multi-object tracking, instance segmentation, pose estimation and image classification.
5
5
  Author-email: Glenn Jocher <glenn.jocher@ultralytics.com>, Jing Qiu <jing.qiu@ultralytics.com>
6
6
  Maintainer-email: Ultralytics <hello@ultralytics.com>
@@ -7,7 +7,7 @@ tests/test_exports.py,sha256=5G5EgDmars6d-N7TVnJdDFWId0IJs-yw03DvdQIjrNU,14246
7
7
  tests/test_integrations.py,sha256=6QgSh9n0J04RdUYz08VeVOnKmf4S5MDEQ0chzS7jo_c,6220
8
8
  tests/test_python.py,sha256=viMvRajIbDZdm64hRRg9i8qZ1sU9frwB69e56mxwEXk,29266
9
9
  tests/test_solutions.py,sha256=CIaphpmOXgz9AE9xcm1RWODKrwGfZLCc84IggGXArNM,14122
10
- ultralytics/__init__.py,sha256=3s1nuBps-pxOoh0FBkRcxTAWjSIgHPexA-U-3STiLm8,1302
10
+ ultralytics/__init__.py,sha256=nbR9xzuCbfetnkDGSTE5sxiBO0svWjIEk40CpLGaTJo,1302
11
11
  ultralytics/py.typed,sha256=la67KBlbjXN-_-DfGNcdOcjYumVpKG_Tkw-8n5dnGB4,8
12
12
  ultralytics/assets/bus.jpg,sha256=wCAZxJecGR63Od3ZRERe9Aja1Weayrb9Ug751DS_vGM,137419
13
13
  ultralytics/assets/zidane.jpg,sha256=Ftc4aeMmen1O0A3o6GCDO9FlfBslLpTAw0gnetx7bts,50427
@@ -227,7 +227,7 @@ ultralytics/solutions/distance_calculation.py,sha256=RcpRDodEHAJUug9tobtQKt5_byS
227
227
  ultralytics/solutions/heatmap.py,sha256=DUyV5UFsOwZ8ArN4BtW8Vm3ps8_VZXc6VP0uiKyGDWY,5481
228
228
  ultralytics/solutions/instance_segmentation.py,sha256=eggk1uWCZ-6cp0YfxCGVUwnKS6xqJua946oxafjAXGk,3778
229
229
  ultralytics/solutions/object_blurrer.py,sha256=EZrv3oU68kEaahAxlhk9cF5ZKFtoVaW8bDB4Css9xe0,3981
230
- ultralytics/solutions/object_counter.py,sha256=nguTJebkCi_sCsP1cz2jABfi0kPOg2DdNZeS2xG-CeE,9354
230
+ ultralytics/solutions/object_counter.py,sha256=OpMSLlenDK-cLvCgCOoKbqMXIZrngyqP8DP6ZeEnWL8,9355
231
231
  ultralytics/solutions/object_cropper.py,sha256=WRbrfXAR5aD6PQBqJ-BvcVaiaqta_9YeTlXN2dY274s,3510
232
232
  ultralytics/solutions/parking_management.py,sha256=FQKeLEiwnTmRcXqsNOlOt9GTFPjkyvnE5pwwKnneJa4,13770
233
233
  ultralytics/solutions/queue_management.py,sha256=NlVX6PMEaffjoZjfQrVyayaDUdtc0JF8GzTQrZFjpCg,4371
@@ -253,7 +253,7 @@ ultralytics/utils/__init__.py,sha256=JfvODTB4mG_JOhTeCiPtq0iCEgiCh14hJf195rnOhLQ
253
253
  ultralytics/utils/autobatch.py,sha256=jiE4m_--H9UkXFDm_FqzcZk_hSTCGpS72XdVEKgZwAo,5114
254
254
  ultralytics/utils/autodevice.py,sha256=rXlPuo-iX-vZ4BabmMGEGh9Uxpau4R7Zlt1KCo9Xfyc,8892
255
255
  ultralytics/utils/benchmarks.py,sha256=S_W4S4pe2ktSRdSuWb6m09UEFQmZhmjl943bbo67hOI,32277
256
- ultralytics/utils/checks.py,sha256=QAy9nCtgBCCcweJhB4Wa_5SE25g5PF07lXJOhQOBssM,38312
256
+ ultralytics/utils/checks.py,sha256=NFtryEVFsmY35OsTDS-iEFKmU7nT9TVf_5qkUOF6f1U,38997
257
257
  ultralytics/utils/cpu.py,sha256=OksKOlX93AsbSsFuoYvLXRXgpkOibrZSwQyW6lipt4Q,3493
258
258
  ultralytics/utils/dist.py,sha256=hOuY1-unhQAY-uWiZw3LWw36d1mqJuYK75NdlwB4oKE,4131
259
259
  ultralytics/utils/downloads.py,sha256=IyiGjjXqOyf1B0qLMk7vE6sSQ8s232OhKS8aj9XbTgs,22883
@@ -282,7 +282,7 @@ ultralytics/utils/callbacks/dvc.py,sha256=YT0Sa5P8Huj8Fn9jM2P6MYzUY3PIVxsa5BInVi
282
282
  ultralytics/utils/callbacks/hub.py,sha256=fVLqqr3ZM6hoYFlVMEeejfq1MWDrkWCskPFOG3HGILQ,4159
283
283
  ultralytics/utils/callbacks/mlflow.py,sha256=wCXjQgdufp9LYujqMzLZOmIOur6kvrApHNeo9dA7t_g,5323
284
284
  ultralytics/utils/callbacks/neptune.py,sha256=_vt3cMwDHCR-LyT3KtRikGpj6AG11oQ-skUUUUdZ74o,4391
285
- ultralytics/utils/callbacks/platform.py,sha256=L7P5ttko-QVkig2y3r-D8YxfOWb7lNAan4iuMXxQ_u4,11682
285
+ ultralytics/utils/callbacks/platform.py,sha256=EbKwGV0kVX1ZfwR6MBOPSeDKWpd4-nVO14uydMpJlRs,14798
286
286
  ultralytics/utils/callbacks/raytune.py,sha256=Y0dFyNZVRuFovSh7nkgUIHTQL3xIXOACElgHuYbg_5I,1278
287
287
  ultralytics/utils/callbacks/tensorboard.py,sha256=PTJYvD2gqRUN8xw5VoTjvKnu2adukLfvhMlDgTnTiFU,4952
288
288
  ultralytics/utils/callbacks/wb.py,sha256=ghmL3gigOa-z_F54-TzMraKw9MAaYX-Wk4H8dLoRvX8,7705
@@ -290,9 +290,9 @@ ultralytics/utils/export/__init__.py,sha256=Cfh-PwVfTF_lwPp-Ss4wiX4z8Sm1XRPklsqd
290
290
  ultralytics/utils/export/engine.py,sha256=23-lC6dNsmz5vprSJzaN7UGNXrFlVedNcqhlOH_IXes,9956
291
291
  ultralytics/utils/export/imx.py,sha256=2_mcNzqRIk5LB92JofqNYLN0kkQke1UgKT2jWmEy_l4,13300
292
292
  ultralytics/utils/export/tensorflow.py,sha256=igYzwbdblb9YgfV4Jgl5lMvynuVRcF51dAzI7j-BBI0,9966
293
- ultralytics_opencv_headless-8.3.248.dist-info/licenses/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
294
- ultralytics_opencv_headless-8.3.248.dist-info/METADATA,sha256=WhYBz90KQfio0rd_8ekZRuqyLKdefnRLTxRaB4JkWuo,37728
295
- ultralytics_opencv_headless-8.3.248.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
296
- ultralytics_opencv_headless-8.3.248.dist-info/entry_points.txt,sha256=YM_wiKyTe9yRrsEfqvYolNO5ngwfoL4-NwgKzc8_7sI,93
297
- ultralytics_opencv_headless-8.3.248.dist-info/top_level.txt,sha256=XP49TwiMw4QGsvTLSYiJhz1xF_k7ev5mQ8jJXaXi45Q,12
298
- ultralytics_opencv_headless-8.3.248.dist-info/RECORD,,
293
+ ultralytics_opencv_headless-8.3.249.dist-info/licenses/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
294
+ ultralytics_opencv_headless-8.3.249.dist-info/METADATA,sha256=Zc55oZrhDpNLBB2BmsMs7BDSME_c7Ohxpu034qM3rOM,37728
295
+ ultralytics_opencv_headless-8.3.249.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
296
+ ultralytics_opencv_headless-8.3.249.dist-info/entry_points.txt,sha256=YM_wiKyTe9yRrsEfqvYolNO5ngwfoL4-NwgKzc8_7sI,93
297
+ ultralytics_opencv_headless-8.3.249.dist-info/top_level.txt,sha256=XP49TwiMw4QGsvTLSYiJhz1xF_k7ev5mQ8jJXaXi45Q,12
298
+ ultralytics_opencv_headless-8.3.249.dist-info/RECORD,,