From 248e64d1db86b0a0ce3a3e0309f743eb76ad231b Mon Sep 17 00:00:00 2001 From: Manabu Niseki Date: Thu, 13 Aug 2026 14:32:12 +0900 Subject: [PATCH 1/2] feat: add deprecation warning --- src/urlscan/pro/livescan.py | 100 ++++++++++++++++++++++-------------- 1 file changed, 62 insertions(+), 38 deletions(-) diff --git a/src/urlscan/pro/livescan.py b/src/urlscan/pro/livescan.py index d838057..ca0a5a1 100644 --- a/src/urlscan/pro/livescan.py +++ b/src/urlscan/pro/livescan.py @@ -1,11 +1,14 @@ """Live scanning API client module.""" +import warnings from typing import Any from urlscan.client import BaseClient, _compact from urlscan.types import LiveScanResourceType, VisibilityType from urlscan.utils import _merge +DEPRECATED_FEATURES: set[str] = {"stealth"} + class LiveScan(BaseClient): """Live scanning API client.""" @@ -22,6 +25,47 @@ def get_scanners(self) -> dict: """ return self.get_json("/api/v1/livescan/scanners/") + def _build_scan_payload( + self, + url: str, + visibility: VisibilityType | None = None, + page_timeout: int | None = None, + capture_delay: int | None = None, + extra_headers: dict[str, str] | None = None, + enable_features: list[str] | None = None, + disable_features: list[str] | None = None, + **kwargs: Any, + ) -> dict[str, Any]: + """Build the payload for a scan request.""" + task: dict[str, Any] = _compact( + { + "url": url, + "visibility": visibility, + } + ) + # check for deprecated features + for feature in disable_features or []: + if feature in DEPRECATED_FEATURES: + warnings.warn( + f"The feature '{feature}' is deprecated.", + # ref. https://sethmlarson.dev/deprecations-via-warnings-dont-work-for-python-libraries + category=FutureWarning, + stacklevel=3, + ) + scanner: dict[str, Any] = _compact( + _merge( + { + "pageTimeout": page_timeout, + "captureDelay": capture_delay, + "extraHeaders": extra_headers, + "enableFeatures": enable_features, + "disableFeatures": disable_features, + }, + kwargs, + ) + ) + return {"task": task, "scanner": scanner} + def task( self, url: str, @@ -57,26 +101,16 @@ def task( https://docs.urlscan.io/apis/urlscan-openapi/live-scanning/livescantask """ - task: dict[str, Any] = _compact( - { - "url": url, - "visibility": visibility, - } - ) - scanner: dict[str, Any] = _compact( - _merge( - { - "pageTimeout": page_timeout, - "captureDelay": capture_delay, - "extraHeaders": extra_headers, - "enableFeatures": enable_features, - "disableFeatures": disable_features, - }, - kwargs, - ) + data = self._build_scan_payload( + url, + visibility=visibility, + page_timeout=page_timeout, + capture_delay=capture_delay, + extra_headers=extra_headers, + enable_features=enable_features, + disable_features=disable_features, + **kwargs, ) - data: dict[str, Any] = {"task": task, "scanner": scanner} - res = self._post(f"/api/v1/livescan/{scanner_id}/task/", json=data) return self._response_to_json(res) @@ -113,26 +147,16 @@ def scan( https://docs.urlscan.io/apis/urlscan-openapi/live-scanning/livescanscan """ - task: dict[str, Any] = _compact( - { - "url": url, - "visibility": visibility, - } - ) - scanner: dict[str, Any] = _compact( - _merge( - { - "pageTimeout": page_timeout, - "captureDelay": capture_delay, - "extraHeaders": extra_headers, - "enableFeatures": enable_features, - "disableFeatures": disable_features, - }, - kwargs, - ) + data = self._build_scan_payload( + url, + visibility=visibility, + page_timeout=page_timeout, + capture_delay=capture_delay, + extra_headers=extra_headers, + enable_features=enable_features, + disable_features=disable_features, + **kwargs, ) - data: dict[str, Any] = {"task": task, "scanner": scanner} - res = self._post(f"/api/v1/livescan/{scanner_id}/scan/", json=data) return self._response_to_json(res) From eb3f8a44aacc64c2e240220e80b979acc85454b8 Mon Sep 17 00:00:00 2001 From: Manabu Niseki Date: Fri, 14 Aug 2026 10:41:56 +0900 Subject: [PATCH 2/2] refactor: add warning method in client --- src/urlscan/client.py | 6 ++++++ src/urlscan/pro/livescan.py | 8 ++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/urlscan/client.py b/src/urlscan/client.py index e92ad5a..11ad47d 100644 --- a/src/urlscan/client.py +++ b/src/urlscan/client.py @@ -6,6 +6,7 @@ import logging import os import time +import warnings from dataclasses import dataclass from io import BytesIO from typing import Any, BinaryIO, Literal, TypedDict, cast @@ -454,6 +455,11 @@ def _response_to_content(self, res: ClientResponse) -> bytes: return res.content + def _warn_deprecation(self, message: str, stacklevel: int) -> None: + """Warn about deprecated features.""" + # ref. https://sethmlarson.dev/deprecations-via-warnings-dont-work-for-python-libraries + warnings.warn(message, category=FutureWarning, stacklevel=stacklevel) + class Client(BaseClient): """Main client for urlscan.io API.""" diff --git a/src/urlscan/pro/livescan.py b/src/urlscan/pro/livescan.py index ca0a5a1..c50cf69 100644 --- a/src/urlscan/pro/livescan.py +++ b/src/urlscan/pro/livescan.py @@ -1,6 +1,5 @@ """Live scanning API client module.""" -import warnings from typing import Any from urlscan.client import BaseClient, _compact @@ -46,11 +45,8 @@ def _build_scan_payload( # check for deprecated features for feature in disable_features or []: if feature in DEPRECATED_FEATURES: - warnings.warn( - f"The feature '{feature}' is deprecated.", - # ref. https://sethmlarson.dev/deprecations-via-warnings-dont-work-for-python-libraries - category=FutureWarning, - stacklevel=3, + self._warn_deprecation( + f"The feature '{feature}' is deprecated.", stacklevel=4 ) scanner: dict[str, Any] = _compact( _merge(