Spaces:
Sleeping
Sleeping
| """ | |
| db.py — MongoDB Atlas connection with mongomock fallback. | |
| If MONGO_URI is not set or the connection fails, the app runs on an | |
| in-memory mock store so development works without any database. | |
| """ | |
| import os | |
| import logging | |
| from dotenv import load_dotenv | |
| load_dotenv() | |
| logger = logging.getLogger(__name__) | |
| MONGO_URI = os.getenv("MONGO_URI") or os.getenv("MONGODB_URI") or "" | |
| DB_NAME = "squad_qa" | |
| _client = None | |
| _db = None | |
| _using_mock = False | |
| def _connect_atlas(): | |
| """Attempt to connect to MongoDB Atlas (or local Mongo).""" | |
| global _client, _db, _using_mock | |
| try: | |
| from pymongo import MongoClient | |
| from pymongo.errors import ConnectionFailure, ConfigurationError, ServerSelectionTimeoutError | |
| if not MONGO_URI or "username:password" in MONGO_URI: | |
| raise ValueError("MONGO_URI not configured — falling back to mock.") | |
| _client = MongoClient(MONGO_URI, serverSelectionTimeoutMS=5000, tls=True) | |
| # Trigger actual connection check | |
| _client.admin.command("ping") | |
| _db = _client[DB_NAME] | |
| _using_mock = False | |
| logger.info("[DB] Connected to MongoDB Atlas successfully.") | |
| except Exception as exc: | |
| logger.warning(f"[DB] MongoDB connection failed: {exc}") | |
| logger.warning("[DB] Falling back to in-memory mongomock.") | |
| _connect_mock() | |
| def _connect_mock(): | |
| """Fall back to mongomock (in-memory, no persistence).""" | |
| global _client, _db, _using_mock | |
| try: | |
| import mongomock | |
| _client = mongomock.MongoClient() | |
| _db = _client[DB_NAME] | |
| _using_mock = True | |
| logger.warning("[DB] Running on mongomock — data will NOT persist across restarts.") | |
| except ImportError: | |
| logger.error("[DB] mongomock not installed. Database unavailable.") | |
| _db = None | |
| def get_db(): | |
| """Return the active database handle (Atlas or mock).""" | |
| global _db | |
| if _db is None: | |
| _connect_atlas() | |
| return _db | |
| def is_using_mock(): | |
| return _using_mock | |
| # Initialise on import | |
| _connect_atlas() | |
| # Convenience collection accessors | |
| def users_col(): | |
| return get_db()["users"] | |
| def chats_col(): | |
| return get_db()["chats"] | |
| def settings_col(): | |
| return get_db()["settings"] | |