| import os
|
| import asyncio
|
| from fastapi import FastAPI, Form, Request
|
| from fastapi.responses import HTMLResponse, StreamingResponse
|
| from fastapi.templating import Jinja2Templates
|
|
|
| app = FastAPI()
|
| templates = Jinja2Templates(directory="templates")
|
|
|
| async def run_and_stream(command: list):
|
| """An async generator that runs a subprocess and yields its stdout/stderr line by line."""
|
| proc = await asyncio.create_subprocess_exec(
|
| *command,
|
| stdout=asyncio.subprocess.PIPE,
|
| stderr=asyncio.subprocess.PIPE
|
| )
|
|
|
|
|
| if proc.stdout:
|
| while True:
|
| line = await proc.stdout.readline()
|
| if not line:
|
| break
|
|
|
| yield f"data: {line.decode('utf-8', errors='ignore')}\n\n"
|
| await asyncio.sleep(0.01)
|
|
|
|
|
| if proc.stderr:
|
| while True:
|
| line = await proc.stderr.readline()
|
| if not line:
|
| break
|
| yield f"data: {line.decode('utf-8', errors='ignore')}\n\n"
|
| await asyncio.sleep(0.01)
|
|
|
| await proc.wait()
|
| yield f"data: [STREAM_COMPLETE]\n\n"
|
|
|
| @app.get("/", response_class=HTMLResponse)
|
| async def read_root(request: Request):
|
| return templates.TemplateResponse("index.html", {"request": request})
|
|
|
| @app.post("/run", response_class=StreamingResponse)
|
| async def run_dorker_stream(request: Request, query: str = Form(...), dork_file: str = Form(...)):
|
| github_tokens = os.environ.get("GHA_TOKENS")
|
|
|
| if not github_tokens:
|
| async def error_generator():
|
| yield "data: Error: GHA_TOKENS is not set in the Space secrets.\n\n"
|
| return StreamingResponse(error_generator(), media_type="text/event-stream")
|
|
|
| command = [
|
| "python3",
|
| "-u",
|
| "GitDorker.py",
|
| "-t", github_tokens,
|
| "-q", query,
|
| "-d", dork_file,
|
| "-o", f"outputs/output_{query.replace('.', '_')}"
|
| ]
|
|
|
| return StreamingResponse(run_and_stream(command), media_type="text/event-stream") |