# import os # import json # import shutil # from fastapi import APIRouter, HTTPException, UploadFile, Form, Request # from crewai import Crew, Process # from agents.design_phase import search_engine_agent, search_engine_task # from schemas import DNAMetadata, OutlineInput # from modules import TRUSTED_SITES # router = APIRouter(prefix="/design", tags=["Design"]) # @router.post("/source_finder") # async def run_training(request: Request, file: UploadFile, data: str = Form(...)): # """Uploads keywords JSON + metadata JSON, runs CrewAI search, returns download link""" # # ✅ Parse metadata JSON manually # try: # parsed_data = json.loads(data) # metadata = OutlineInput(**parsed_data) # except Exception as e: # raise HTTPException( # status_code=400, detail=f"Invalid JSON in 'data' field: {str(e)}" # ) # # ✅ Save uploaded file # save_path = f"/tmp/{file.filename}" # with open(save_path, "wb") as buffer: # shutil.copyfileobj(file.file, buffer) # # ✅ Validate extension # ext = save_path.lower().split(".")[-1] # if ext != "json": # raise HTTPException(status_code=400, detail="File must be a JSON file") # # ✅ Load keywords file # with open(save_path, "r", encoding="utf-8") as f: # try: # units_data = json.load(f) # except json.JSONDecodeError: # raise HTTPException(status_code=400, detail="Invalid JSON file content") # # ✅ Initialize Crew # crew = Crew( # agents=[search_engine_agent], # tasks=[search_engine_task], # process=Process.sequential, # ) # # ✅ Prepare static user input # user_inputs = DNAMetadata( # topic=metadata.topic, # domain=metadata.domain, # content_type=metadata.content_type, # audience=metadata.audience, # material_type=metadata.material_type, # ).dict() # all_results = [] # # total_prompt = 0 # # total_completion = 0 # # ✅ Loop through each subtopic and query # for unit in units_data: # unit_title = unit["unit_title"] # subtopic_title = unit["subtopic_title"] # queries = unit["queries"] # for query in queries: # print(f"🔍 Running search for [{subtopic_title}] | Query: {query}") # merged_input = { # **user_inputs, # "score_th": 0.6, # "no_links": 3, # "queries": query, # "unit_title": unit_title, # "subtopic_title": subtopic_title, # "TRUSTED_SITES": TRUSTED_SITES, # } # try: # result = crew.kickoff(inputs=merged_input) # all_results.append(result.json_dict) # # usage = result.token_usage # CrewAI بيحسبها جاهز # # total_prompt += usage["prompt_tokens"] # # total_completion += usage["completion_tokens"] # # total_tokens += usage["total_tokens"] # except Exception as e: # print(f"⚠️ Error while running query '{query}': {e}") # output_data = {"results": all_results} # # ✅ Save results to file # output_file = f"/tmp/search_results" # with open(output_file, "w", encoding="utf-8") as f: # json.dump(output_data, f, ensure_ascii=False, indent=2) # # ✅ Create downloadable link # base_url = str(request.base_url).rstrip("/") # download_link = ( # f"{base_url}/design/download?filename={os.path.basename(output_file)}" # ) # return { # "message": "Search process completed successfully 🚀", # "total_queries": len(all_results), # # "total_prompt": total_prompt, # # "total_completion": total_completion, # # "total_tokens": total_tokens, # "download_link": download_link, # "result": all_results, # "json_dict": output_data, # } # # ✅ New endpoint for downloading results # @router.get("/download") # async def download_file(filename: str): # file_path = f"/tmp/{filename}" # if not os.path.exists(file_path): # raise HTTPException(status_code=404, detail="File not found") # with open(file_path, "r", encoding="utf-8") as f: # data = json.load(f) # return data