from fastapi import FastAPI, UploadFile, File from fastapi.middleware.cors import CORSMiddleware import httpx, io, json, os from googleapiclient.discovery import build from googleapiclient.http import MediaIoBaseUpload from google.oauth2 import service_account app = FastAPI() app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"]) DRIVE_FOLDER_ID = os.environ.get("DRIVE_FOLDER_ID", "") _creds = None drive = None def get_drive(): global _creds, drive if drive is None: _creds = service_account.Credentials.from_service_account_info( json.loads(os.environ["GOOGLE_SERVICE_ACCOUNT_JSON"]), scopes=["https://www.googleapis.com/auth/drive"] ) drive = build("drive", "v3", credentials=_creds) return drive @app.get("/") def root(): return {"status": "Dolor D Prince API Gateway running"} @app.post("/v1/chat/completions") async def chat_completions(body: dict): api_key = os.environ.get("OPENROUTER_API_KEY", "") async with httpx.AsyncClient(timeout=60) as client: res = await client.post( "https://openrouter.ai/api/v1/chat/completions", headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}, json=body, ) return res.json() @app.post("/v1/projects/{page_id}") async def save_project(page_id: str, body: dict): d = get_drive() fname = f"{page_id}.json" media = MediaIoBaseUpload(io.BytesIO(json.dumps(body).encode()), mimetype="application/json") existing = d.files().list(q=f"name='{fname}' and '{DRIVE_FOLDER_ID}' in parents").execute() if existing["files"]: d.files().update(fileId=existing["files"][0]["id"], media_body=media).execute() else: d.files().create(body={"name": fname, "parents": [DRIVE_FOLDER_ID]}, media_body=media).execute() return {"status": "ok"} @app.get("/v1/projects/{page_id}") async def load_project(page_id: str): d = get_drive() fname = f"{page_id}.json" res = d.files().list(q=f"name='{fname}' and '{DRIVE_FOLDER_ID}' in parents").execute() if not res["files"]: return {"data": {}} content = d.files().get_media(fileId=res["files"][0]["id"]).execute() return {"data": json.loads(content)} @app.post("/v1/assets/upload") async def upload_asset(files: list[UploadFile] = File(...)): d = get_drive() urls = [] for f in files: media = MediaIoBaseUpload(io.BytesIO(await f.read()), mimetype=f.content_type) created = d.files().create( body={"name": f.filename, "parents": [DRIVE_FOLDER_ID]}, media_body=media, fields="id" ).execute() d.permissions().create(fileId=created["id"], body={"role": "reader", "type": "anyone"}).execute() urls.append(f"https://drive.google.com/uc?id={created['id']}") return {"data": [{"src": u} for u in urls]}