| | |
| | 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 |
| | ) |
| |
|
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| |
|
| | |
| | |
| |
|
| | |
| | |
| |
|
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |