fix: async subprocess + httpx — no more event loop blocking during scans

This commit is contained in:
Marker689
2026-05-09 05:58:55 +03:00
parent e577f1944c
commit 41a8745198
4 changed files with 48 additions and 75 deletions

View File

@@ -1,8 +1,8 @@
"""GuardDog CLI integration via subprocess."""
"""GuardDog CLI integration via asyncio subprocess."""
import asyncio
import json
import shutil
import subprocess
from guarddog_nexus.config import config
from guarddog_nexus.logging_setup import log
@@ -10,39 +10,33 @@ from guarddog_nexus.logging_setup import log
GUARDDOG_BIN = shutil.which("guarddog") or "guarddog"
def scan_package(filepath: str, ecosystem: str = "pypi") -> dict:
async def scan_package(filepath: str, ecosystem: str = "pypi") -> dict:
"""Run guarddog scan on a downloaded package file. Returns normalized dict."""
cmd = [
GUARDDOG_BIN,
ecosystem,
"scan",
filepath,
"--output-format",
"json",
]
cmd = [GUARDDOG_BIN, ecosystem, "scan", filepath, "--output-format", "json"]
log.info("Running: %s", " ".join(cmd))
try:
result = subprocess.run(
cmd,
capture_output=True,
text=True,
timeout=config.scan_timeout_seconds,
proc = await asyncio.create_subprocess_exec(
*cmd,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
except subprocess.TimeoutExpired:
stdout, stderr = await asyncio.wait_for(
proc.communicate(), timeout=config.scan_timeout_seconds
)
except asyncio.TimeoutError:
log.error("GuardDog scan timed out for %s", filepath)
return {"findings": [], "errors": ["timeout"]}
except FileNotFoundError:
log.error("GuardDog binary not found at %s", GUARDDOG_BIN)
return {"findings": [], "errors": ["guarddog_not_found"]}
if result.returncode not in (0, 1):
log.error("GuardDog exited %d: %s", result.returncode, result.stderr)
return {"findings": [], "errors": [result.stderr.strip()]}
if proc.returncode not in (0, 1):
log.error("GuardDog exited %d: %s", proc.returncode, stderr.decode())
return {"findings": [], "errors": [stderr.decode().strip()]}
try:
data = json.loads(result.stdout)
data = json.loads(stdout.decode())
except json.JSONDecodeError:
log.error("GuardDog returned invalid JSON for %s", filepath)
return {"findings": [], "errors": ["json_parse_error"]}