| |
| import time |
| import logging |
| from typing import Optional |
|
|
| from pymongo import MongoClient |
| from pymongo.errors import ServerSelectionTimeoutError, ConfigurationError |
| import certifi |
| from qdrant_client import QdrantClient |
|
|
| from app.page_speed.config import settings |
|
|
| logger = logging.getLogger(__name__) |
| |
| if not logging.getLogger().handlers: |
| |
| logging.basicConfig(level=logging.INFO) |
|
|
| |
| MONGO_SERVER_SELECTION_TIMEOUT_MS = 20000 |
|
|
| def _create_mongo_client() -> MongoClient: |
| """ |
| Create and return a MongoClient configured to use TLS with certifi CA bundle. |
| This function intentionally passes tls=True and tlsCAFile to make TLS explicit and reliable. |
| """ |
| uri = settings.mongo_uri |
| logger.info("Creating MongoClient for URI: %s", uri) |
|
|
| try: |
| client = MongoClient( |
| uri, |
| tls=True, |
| tlsCAFile=certifi.where(), |
| serverSelectionTimeoutMS=MONGO_SERVER_SELECTION_TIMEOUT_MS, |
| ) |
| logger.debug("MongoClient created with explicit TLS and certifi CA bundle.") |
| return client |
| except TypeError as e: |
| |
| logger.warning("MongoClient creation with tls arguments failed (%s). Falling back without tls args.", e) |
| client = MongoClient(uri, serverSelectionTimeoutMS=MONGO_SERVER_SELECTION_TIMEOUT_MS) |
| return client |
| except Exception as e: |
| logger.exception("Unexpected exception while creating MongoClient: %s", e) |
| raise |
|
|
| |
| mongo_client: Optional[MongoClient] = None |
| _last_exc: Optional[Exception] = None |
|
|
| try: |
| mongo_client = _create_mongo_client() |
| |
| for attempt in range(1, 4): |
| try: |
| logger.info("Pinging MongoDB (attempt %d)...", attempt) |
| mongo_client.admin.command("ping") |
| logger.info("Successfully connected to MongoDB.") |
| _last_exc = None |
| break |
| except ServerSelectionTimeoutError as e: |
| _last_exc = e |
| logger.exception("ServerSelectionTimeoutError pinging MongoDB on attempt %d: %s", attempt, e) |
| except ConfigurationError as e: |
| _last_exc = e |
| logger.exception("ConfigurationError pinging MongoDB: %s", e) |
| break |
| except Exception as e: |
| _last_exc = e |
| logger.exception("Unexpected error pinging MongoDB on attempt %d: %s", attempt, e) |
| time.sleep(1 * attempt) |
| except Exception as e: |
| _last_exc = e |
| logger.exception("MongoClient creation failed: %s", e) |
|
|
| if _last_exc: |
| |
| |
| raise _last_exc |
|
|
| |
| mongo_db = mongo_client[settings.mongo_db] |
| vectorstore_meta_coll = mongo_db["vectorstore_metadata"] |
| chat_collection_name = settings.mongo_collection |
|
|
| def get_mongo_client() -> MongoClient: |
| """Return the active MongoClient instance.""" |
| return mongo_client |
|
|
| def get_vectorstore_collection(): |
| return vectorstore_meta_coll |
|
|
| |
| |
| |
| |
| qdrant_client = QdrantClient( |
| url=settings.qdrant_url, |
| api_key=settings.qdrant_api_key or None |
| ) |
|
|
| |
| |
| |
|
|
| |
| |
| |
| |
|
|
| |
| |
|
|
| |
| |
|
|
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |