file blob
All checks were successful
Build and Deploy MITM Webserver / build (push) Successful in 11s

This commit is contained in:
2026-03-01 08:57:11 +01:00
parent caf6799dd2
commit c48d93642a

View File

@@ -3,7 +3,7 @@ NFQUEUE Python-Scripting API Router
Endpoints:
- POST /scripts -> upload script (multipart): script file, optional requirements file, required 'name' form field
- GET /scripts -> list scripts
- GET /scripts/{name} -> download script
- GET /scripts/{name} -> download script (binary blob)
- POST /scripts/{name}/enable -> enable systemd service for script on given qnum
- POST /scripts/{name}/disable -> disable service for script on qnum
- DELETE /scripts/{name} -> disable all or a specific qnum service(s) and delete script + venv + requirements
@@ -445,6 +445,8 @@ async def upload_script(
"""
Upload a script with supplied 'name' and optional requirements file.
On pip/venv install failure, cleanup uploaded files and venv and return 500 with details.
NOTE: This endpoint is multipart/form-data (UploadFile), so Swagger UI will show file upload widgets.
"""
# validate name
try:
@@ -542,9 +544,23 @@ def list_scripts() -> List[ScriptInfo]:
return out
@router.get("/{name}")
def download_script(name: str):
# dynamic route - placed after /status and /{name}/status
@router.get(
"/{name}",
response_class=FileResponse,
responses={
200: {
"content": {"application/octet-stream": {"schema": {"type": "string", "format": "binary"}}},
"description": "Python script file (binary).",
},
404: {"description": "Not found"},
400: {"description": "Invalid name"},
},
)
def download_script(name: str) -> FileResponse:
"""
Download a script as a binary file. Clients should request raw bytes (blob).
Swagger/OpenAPI will document the response as binary.
"""
try:
validate_name(name)
except ValueError as e:
@@ -554,7 +570,9 @@ def download_script(name: str):
logger.warning("Download requested for missing script %s", name)
raise HTTPException(status_code=404, detail="not found")
logger.info("Download script %s", name)
return FileResponse(path, media_type="text/x-python", filename=f"{name}.py")
# Return generic octet-stream so clients treat as binary blob.
return FileResponse(path, media_type="application/octet-stream", filename=f"{name}.py")
@router.post("/{name}/enable", response_model=OperationResult)