""" LinkSyncServer - Main Application FastAPI application for bookmark management with advanced collection and query capabilities. """ from fastapi import FastAPI, Depends, HTTPException, status from fastapi.middleware.cors import CORSMiddleware from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates from fastapi.responses import HTML, JSONResponse from pydantic import BaseModel from typing import Optional import os import secrets import logging # Configure logging logging.basicConfig(level=os.environ.get('LOG_LEVEL', 'INFO')) logger = logging.getLogger(__name__) # Create FastAPI app app = FastAPI( title="LinkSyncServer", description="Self-hosted bookmark server with advanced collection capabilities", version="1.0.0", ) # CORS configuration allow_origins = os.environ.get('CORS_ORIGINS', 'http://localhost:5555').split(',') app.add_middleware( CORSMiddleware, allow_origins=allow_origins, allow_credentials=True, allow_methods=['*'], allow_headers=['*'], ) # Static files app.mount("/static", StaticFiles(directory="static"), name="static") # Templates app.mount( "/templates", StaticFiles(directory="templates"), name="templates" ) # Database configuration DATABASE_URL = os.environ.get('DATABASE_URL') SECRET_KEY = os.environ.get('SECRET_KEY', secrets.token_urlsafe(32)) DEBUG = os.environ.get('DEBUG', 'False').lower() == 'true' HOST = os.environ.get('HOST', '0.0.0.0') PORT = int(os.environ.get('PORT', 5000)) # CORS origins from environment CORS_ORIGINS = [o.strip() for o in os.environ.get('CORS_ORIGINS', 'http://localhost:5555').split(',')] # Add CORS middleware app.add_middleware( CORSMiddleware, allow_origins=CORS_ORIGINS, allow_credentials=True, allow_methods=['*'], allow_headers=['*'], ) # Health check endpoint @app.get("/health") async def health_check(): """Health check endpoint for Docker monitoring.""" return {"status": "ok", "service": "LinkSyncServer"} # Root endpoint @app.get("/") async def root(): """Root endpoint with redirect to web UI.""" return HTML(""" LinkSyncServer

LinkSyncServer

Web UI: Login

API Docs: API Documentation

""") # Error handler @app.exception_handler(Exception) async def global_exception_handler(request, exc): logger.error(f"Exception: {exc}") return JSONResponse( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={"detail": "Internal server error"} ) # Error handler for specific exceptions @app.exception_handler(HTTPException) async def http_exception_handler(request, exc): return JSONResponse( status_code=exc.status_code, content={"detail": exc.detail} ) def get_api_key(user): """Get API key from database for a user.""" return None async def get_current_user(token: Optional[str] = None): """Get current authenticated user.""" if token: # Validate JWT token # In production, implement proper JWT validation pass return None if __name__ == "__main__": import uvicorn uvicorn.run( "app:app", host=HOST, port=PORT, reload=DEBUG )