2026-07-07 09:57:21 +02:00
|
|
|
import logging
|
|
|
|
|
import httpx
|
|
|
|
|
from app.core.config import settings
|
|
|
|
|
from app.schemas.qa_report import QARawResults, RuntimeOutput
|
|
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
async_client = httpx.AsyncClient(verify=False)
|
|
|
|
|
|
2026-07-15 14:00:59 +02:00
|
|
|
async def run_project_qa(repo_url: str) -> QARawResults:
|
2026-07-07 09:57:21 +02:00
|
|
|
"""
|
2026-07-15 14:00:59 +02:00
|
|
|
Sollicite l'API du conteneur arc-sandbox pour effectuer
|
|
|
|
|
une analyse de qualité et sécurité statique (Semgrep) en clonant le dépôt.
|
2026-07-07 09:57:21 +02:00
|
|
|
"""
|
2026-07-15 14:00:59 +02:00
|
|
|
sandbox_url = "http://arc-sandbox:8004/scan"
|
|
|
|
|
logger.info(f"[QA Client] Envoi de la requête de scan pour le dépôt : {repo_url}")
|
2026-07-07 09:57:21 +02:00
|
|
|
|
|
|
|
|
try:
|
2026-07-15 14:00:59 +02:00
|
|
|
response = await async_client.post(sandbox_url, params={"repo_url": repo_url}, timeout=150.0)
|
2026-07-07 09:57:21 +02:00
|
|
|
|
|
|
|
|
if response.status_code == 200:
|
|
|
|
|
data = response.json()
|
2026-07-15 14:00:59 +02:00
|
|
|
|
|
|
|
|
if data is None:
|
|
|
|
|
logger.error("[QA Client] ❌ La Sandbox a répondu 200 OK mais a renvoyé une réponse vide (null).")
|
|
|
|
|
return QARawResults(
|
|
|
|
|
is_executable=False,
|
|
|
|
|
runtime=RuntimeOutput(
|
|
|
|
|
exit_code=-1,
|
|
|
|
|
stdout="",
|
|
|
|
|
stderr="Erreur interne Sandbox : Réponse JSON vide.",
|
|
|
|
|
duration_seconds=0,
|
|
|
|
|
timeout_triggered=False
|
|
|
|
|
),
|
|
|
|
|
issues=[]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
results = data.get("results", {})
|
|
|
|
|
if not results.get("is_executable"):
|
|
|
|
|
logger.error(f"[QA Client] ❌ Erreur interne Sandbox (Semgrep STDERR) : {results.get('runtime', {}).get('stderr')}")
|
|
|
|
|
|
|
|
|
|
return QARawResults.model_validate(results)
|
|
|
|
|
|
2026-07-07 09:57:21 +02:00
|
|
|
else:
|
|
|
|
|
logger.error(f"[QA Client] Erreur de la Sandbox (Status {response.status_code}): {response.text}")
|
|
|
|
|
return QARawResults(
|
|
|
|
|
is_executable=False,
|
|
|
|
|
runtime=RuntimeOutput(
|
|
|
|
|
exit_code=response.status_code,
|
|
|
|
|
stdout="",
|
|
|
|
|
stderr=f"Erreur HTTP Sandbox: {response.text}",
|
|
|
|
|
duration_seconds=0,
|
|
|
|
|
timeout_triggered=False
|
|
|
|
|
),
|
|
|
|
|
issues=[]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
logger.error(f"[QA Client] Impossible de joindre l'API de la Sandbox : {str(e)}")
|
|
|
|
|
return QARawResults(
|
|
|
|
|
is_executable=False,
|
|
|
|
|
runtime=RuntimeOutput(
|
|
|
|
|
exit_code=-1,
|
|
|
|
|
stdout="",
|
|
|
|
|
stderr=f"Exception de connexion QA Client: {str(e)}",
|
|
|
|
|
duration_seconds=0,
|
|
|
|
|
timeout_triggered=False
|
|
|
|
|
),
|
|
|
|
|
issues=[]
|
|
|
|
|
)
|