fix: возврат к /api/v1/scan/checkFile (по лицензии разрешён API с выбранными параметрами)

This commit is contained in:
redlineo committed 2026-09-16 20:29:00 +03:00
1 parent f193b3f553
commit f218e875e9
2 files changed
+20 -70

No files matched your search

+2 -4
View File
@@ -49,10 +49,8 @@ pt_sandbox:
# Отключать проверку SSL-сертификата (для самоподписанных сертификатов) # Отключать проверку SSL-сертификата (для самоподписанных сертификатов)
verify_ssl: true verify_ssl: true
# Endpoint для загрузки файла во временное хранилище # Endpoint для загрузки + запуска проверки одним запросом (соответствует лицензии)
upload_endpoint: "/api/v1/storage/uploadScanFile" upload_endpoint: "/api/v1/scan/checkFile"
# Endpoint для запуска проверки загруженного файла
scan_endpoint: "/api/v1/analysis/createScanTask"
# Заголовок и значение для авторизации в Sandbox # Заголовок и значение для авторизации в Sandbox
auth_header: "X-API-Key" auth_header: "X-API-Key"
+18 -66
View File
@@ -355,8 +355,7 @@ class PTSandboxClient:
def __init__(self, cfg: dict): def __init__(self, cfg: dict):
sb_cfg = cfg["pt_sandbox"] sb_cfg = cfg["pt_sandbox"]
self.base_url = sb_cfg["base_url"].rstrip("/") self.base_url = sb_cfg["base_url"].rstrip("/")
self.upload_endpoint = sb_cfg.get("upload_endpoint", "/api/v1/storage/uploadScanFile") self.upload_endpoint = sb_cfg.get("upload_endpoint", "/api/v1/scan/checkFile")
self.scan_endpoint = sb_cfg.get("scan_endpoint", "/api/v1/analysis/createScanTask")
self.auth_header = sb_cfg.get("auth_header", "X-API-Key") self.auth_header = sb_cfg.get("auth_header", "X-API-Key")
self.api_key = sb_cfg.get("api_key", "") self.api_key = sb_cfg.get("api_key", "")
self.file_field_name = sb_cfg.get("file_field_name", "file") self.file_field_name = sb_cfg.get("file_field_name", "file")
@@ -378,93 +377,46 @@ class PTSandboxClient:
self._session.mount("https://", InsecureSslAdapter()) self._session.mount("https://", InsecureSslAdapter())
logger.warning("Проверка SSL-сертификата отключена для PT Sandbox") logger.warning("Проверка SSL-сертификата отключена для PT Sandbox")
def _request(self, method: str, url: str, **kwargs) -> requests.Response:
"""Выполнить HTTP-запрос к API PT Sandbox."""
try:
resp = self._session.request(method, url, **kwargs)
if resp.status_code == 401:
logger.error("Sandbox 401: неверный или неактивный токен доступа")
return resp
resp.raise_for_status()
return resp
except requests.exceptions.RequestException as exc:
logger.error("Ошибка запроса Sandbox %s: %s", url, exc)
raise
def upload_file(self, file_path: Path) -> Optional[str]: def upload_file(self, file_path: Path) -> Optional[str]:
""" """Отправить файл в PT Sandbox на анализ (загрузка + запуск проверки одним запросом).
Двухшаговый流程: загрузить файл в Sandbox, затем запустить проверку. Возвращает scan_id или None при ошибке."""
Возвращает scan_id или None при ошибке. params = {
""" "file_name": file_path.name,
# Шаг 1: загрузка файла "async_result": "true",
upload_url = f"{self.base_url}{self.upload_endpoint}" }
logger.info("Шаг 1/2: загрузка файла %s в Sandbox", file_path.name) url = f"{self.base_url}{self.upload_endpoint}"
logger.info("Отправка файла в Sandbox: %s", file_path.name)
try: try:
with open(file_path, "rb") as fh: with open(file_path, "rb") as fh:
files = {self.file_field_name: (file_path.name, fh)} files = {self.file_field_name: (file_path.name, fh)}
resp = self._session.post( resp = self._session.post(
upload_url, files=files, url, params=params, files=files,
timeout=(self.timeout_connect, self.timeout_read), timeout=(self.timeout_connect, self.timeout_read),
verify=self.verify_ssl, verify=self.verify_ssl,
) )
if resp.status_code not in (200, 201, 202): if resp.status_code not in (200, 201, 202):
logger.error("Sandbox ошибка загрузки: %s: %s", logger.error("Sandbox вернул %s: %s",
resp.status_code, resp.text[:500]) resp.status_code, resp.text[:500])
return None return None
upload_data = resp.json().get("data", {}) data = resp.json().get("data", {})
file_uri = upload_data.get("file_uri") scan_id = data.get("scan_id") or data.get("id")
if not file_uri:
logger.error("Sandbox: не получен file_uri в ответе на загрузку")
return None
logger.debug("Файл загружен, file_uri=%s", file_uri)
except requests.RequestException as exc:
logger.error("Ошибка загрузки файла %s в Sandbox: %s",
file_path.name, exc)
return None
except OSError as exc:
logger.error("Ошибка чтения файла %s: %s", file_path.name, exc)
return None
# Шаг 2: запуск проверки
scan_url = f"{self.base_url}{self.scan_endpoint}"
logger.info("Шаг 2/2: запуск проверки файла %s", file_path.name)
try:
body = {
"file_uri": file_uri,
"file_name": file_path.name,
"async_result": True,
"short_result": True,
}
resp = self._session.post(
scan_url, json=body,
timeout=(self.timeout_connect, self.timeout_read),
verify=self.verify_ssl,
)
if resp.status_code not in (200, 201, 202):
logger.error("Sandbox ошибка запуска проверки: %s: %s",
resp.status_code, resp.text[:500])
return None
scan_data = resp.json().get("data", {})
scan_id = scan_data.get("scan_id") or scan_data.get("id")
if scan_id: if scan_id:
logger.info("Файл %s принят Sandbox. scan_id=%s", logger.info("Файл %s принят Sandbox. scan_id=%s",
file_path.name, scan_id) file_path.name, scan_id)
return str(scan_id) return str(scan_id)
logger.error("Sandbox: не получен scan_id в ответе") logger.error("Sandbox: не получен scan_id в ответе")
return None return None
except requests.RequestException as exc: except requests.exceptions.RequestException as exc:
logger.error("Ошибка запуска проверки %s в Sandbox: %s", logger.error("Ошибка отправки файла %s в Sandbox: %s",
file_path.name, exc) file_path.name, exc)
return None return None
except OSError as exc:
logger.error("Ошибка чтения файла %s: %s", file_path.name, exc)
return None
# ───────────────────────────────────────────────────────── # ─────────────────────────────────────────────────────────