|
2 | 2 | import os |
3 | 3 | from contextlib import asynccontextmanager |
4 | 4 | from pathlib import Path |
5 | | -from typing import Optional |
| 5 | +from typing import Any, Optional |
6 | 6 |
|
7 | 7 | from fastapi import FastAPI, Form, Request |
8 | 8 | from fastapi.responses import HTMLResponse, PlainTextResponse, RedirectResponse |
9 | 9 | from fastapi.staticfiles import StaticFiles |
10 | 10 | from fastapi.templating import Jinja2Templates |
11 | 11 | from starlette.middleware.sessions import SessionMiddleware |
12 | 12 |
|
13 | | -from typing import TYPE_CHECKING |
14 | | - |
15 | | -if TYPE_CHECKING: |
16 | | - from pymongo.errors import PyMongoError |
17 | | -else: |
18 | | - try: |
19 | | - from pymongo.errors import PyMongoError |
20 | | - except ImportError: |
21 | | - |
22 | | - class PyMongoError(Exception): |
23 | | - pass |
24 | | - |
25 | | - |
26 | | -# fallback for offline mode |
27 | | - |
28 | 13 | from app.api.fast_api import app as api_app |
29 | 14 | from app.db import data as db_data |
30 | | -from app.utils.qr import generate_qr_with_logo |
31 | | - |
32 | 15 | from app.utils.config import load_env |
33 | 16 | from app.utils.helper import ( |
34 | 17 | format_date, |
35 | 18 | generate_code, |
36 | 19 | is_valid_url, |
37 | 20 | sanitize_url, |
38 | 21 | ) |
| 22 | +from app.utils.qr import generate_qr_with_logo |
| 23 | + |
| 24 | +load_env() # ✅ load env ONCE |
| 25 | + |
| 26 | +RED = "\033[31m" |
| 27 | +GREEN = "\033[32m" |
| 28 | +BLUE = "\033[34m" |
| 29 | +RESET = "\033[0m" |
| 30 | + |
| 31 | +app_name = os.getenv("APP_NAME", "TinyURL") |
| 32 | +print(f"Environment loaded as {BLUE}{app_name}{RESET}") |
| 33 | + |
| 34 | +# 1. MongoDB error handling: Try to import the real exception class first |
| 35 | +PyMongoError: Any |
| 36 | +try: |
| 37 | + from pymongo.errors import PyMongoError as _RealPyMongoError |
| 38 | + |
| 39 | + PyMongoError = _RealPyMongoError |
| 40 | +except (ImportError, ModuleNotFoundError): |
| 41 | + # 2. Fallback: Define our own only if the real one fails |
| 42 | + class _FallbackPyMongoError(Exception): |
| 43 | + pass |
| 44 | + |
| 45 | + # Assign our fallback to the same local name |
| 46 | + PyMongoError = _FallbackPyMongoError |
39 | 47 |
|
40 | 48 |
|
41 | 49 | # ----------------------------- |
42 | 50 | # Lifespan: env + DB connect ONCE |
43 | 51 | # ----------------------------- |
44 | 52 | @asynccontextmanager |
45 | 53 | async def lifespan(app: FastAPI): |
46 | | - load_env() # ✅ load env ONCE |
47 | 54 | connected = db_data.connect_db() # ✅ connect DB ONCE |
48 | 55 | app.state.db_available = connected |
49 | 56 | yield |
|
0 commit comments