import os import subprocess import shutil from typing import Optional from fastapi import FastAPI, UploadFile, HTTPException from fastapi.responses import JSONResponse, FileResponse from fastapi.staticfiles import StaticFiles from obs import ObsClient from dotenv import load_dotenv # Load environment variables load_dotenv() app = FastAPI() # Mount static files app.mount("/static", StaticFiles(directory="static"), name="static") # OBS configuration ACCESS_KEY = os.getenv('OBS_ACCESS_KEY') SECRET_KEY = os.getenv('OBS_SECRET_KEY') ENDPOINT = os.getenv('OBS_ENDPOINT') BUCKET = os.getenv('OBS_BUCKET') # File paths UPLOAD_DIR = "/app/uploads" PROCESSED_DIR = "/app/processed" # Ensure directories exist os.makedirs(UPLOAD_DIR, exist_ok=True) os.makedirs(PROCESSED_DIR, exist_ok=True) def get_obs_client() -> ObsClient: return ObsClient( access_key_id=ACCESS_KEY, secret_access_key=SECRET_KEY, server=ENDPOINT ) @app.get("/") async def root(): return FileResponse("static/index.html") @app.post("/convert") async def convert_eps_to_svg(file: UploadFile): # Check file size (10MB limit) file_size = 0 content = await file.read() file_size = len(content) if file_size > 10 * 1024 * 1024: # 10MB raise HTTPException(status_code=400, detail="File too large. Maximum size is 10MB") # Check file extension if not file.filename.lower().endswith('.eps'): raise HTTPException(status_code=400, detail="Only EPS files are accepted") try: # Save uploaded file input_path = os.path.join(UPLOAD_DIR, file.filename) with open(input_path, "wb") as f: f.write(content) # Generate output paths base_name = os.path.splitext(file.filename)[0] temp_svg = os.path.join(PROCESSED_DIR, f"{base_name}_temp.svg") final_svg = os.path.join(PROCESSED_DIR, f"{base_name}.svg") # Convert EPS to SVG subprocess.run(['eps2svg', input_path, temp_svg], check=True) # Try to optimize SVG using scour try: subprocess.run(['scour', '-i', temp_svg, '-o', final_svg], check=True) except subprocess.CalledProcessError: # If scour fails, use the unoptimized SVG shutil.copy(temp_svg, final_svg) print("Scour optimization failed, using unoptimized SVG") # Upload to OBS obs_client = get_obs_client() obs_key = f"svg/{base_name}.svg" with open(final_svg, 'rb') as f: obs_client.putContent(BUCKET, obs_key, f.read()) # Clean up files os.remove(input_path) os.remove(temp_svg) os.remove(final_svg) return JSONResponse({ "status": "success", "message": "File processed successfully", "obs_key": obs_key }) except subprocess.CalledProcessError as e: raise HTTPException(status_code=500, detail=f"Error processing file: {str(e)}") except Exception as e: raise HTTPException(status_code=500, detail=f"An error occurred: {str(e)}") @app.get("/health") def health_check(): return {"status": "healthy"}