from fastapi import FastAPI, Depends, HTTPException, status from fastapi.middleware.cors import CORSMiddleware from fastapi.security import APIKeyHeader import os from routers import pdf_converter, pdf_compressor, pdf_to_images # ========================= # API KEY CONFIGURATION # ========================= API_KEY = os.getenv("PD_TOOLS_API_KEY") if not API_KEY: raise RuntimeError("❌ PD_TOOLS_API_KEY not found in environment variables or HF Space Secrets") # API Key Header api_key_header = APIKeyHeader(name="X-API-Key", auto_error=False) def verify_api_key(api_key: str = Depends(api_key_header)): """Verify the API key from request headers""" if not api_key: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Missing API key. Please provide X-API-Key header." ) if api_key != API_KEY: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid API key" ) return api_key # ========================= # FASTAPI APP # ========================= app = FastAPI( title="Document Converter API", description="Convert and manipulate PDF files with API key authentication", version="1.0.0" ) # CORS configuration app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Create temp directory TEMP_DIR = "/tmp/conversions" os.makedirs(TEMP_DIR, exist_ok=True) # Include routers with API key dependency app.include_router( pdf_converter.router, prefix="/pdf", tags=["PDF Converter"], dependencies=[Depends(verify_api_key)] # Add API key protection ) app.include_router( pdf_compressor.router, prefix="/pdf", tags=["PDF Compressor"], dependencies=[Depends(verify_api_key)] # Add API key protection ) app.include_router( pdf_to_images.router, prefix="/pdf", tags=["PDF to Images"], dependencies=[Depends(verify_api_key)] # Add API key protection ) # ========================= # PUBLIC ENDPOINTS # ========================= @app.get("/") def read_root(): """Public endpoint - no authentication required""" return { "message": "Document Converter API", "version": "1.0.0", "secured": True, "authentication": "Required for all /pdf/* endpoints", "endpoints": { "PDF Conversion": { "/pdf/to-word": "Convert PDF to Word (DOCX)", "/pdf/to-powerpoint": "Convert PDF to PowerPoint (PPTX)", "/pdf/to-excel": "Convert PDF to Excel (XLSX)", "/pdf/to-html": "Convert PDF to HTML", "/pdf/to-text": "Extract text from PDF" }, "PDF Compression": { "/pdf/compress": "Compress PDF file" }, "PDF to Images": { "/pdf/to-images": "Convert PDF pages to images (PNG/JPG)" }, "Utilities": { "/health": "Health check" } }, "usage": { "header": "X-API-Key", "example": "curl -H 'X-API-Key: your-api-key-here' https://your-space.hf.space/pdf/to-word" } } @app.get("/health") def health_check(): """Public health check endpoint - no authentication required""" return {"status": "healthy", "service": "Document Converter API", "secured": True} if __name__ == "__main__": import uvicorn port = int(os.environ.get("PORT", 7860)) uvicorn.run(app, host="0.0.0.0", port=port)