Hammad712 commited on
Commit
52f18dd
Β·
1 Parent(s): e4f17db

Updated main file

Browse files
Files changed (1) hide show
  1. app/main.py +30 -40
app/main.py CHANGED
@@ -1,6 +1,7 @@
1
  """
2
  Main FastAPI application module.
3
  """
 
4
  import time
5
  import logging
6
  import json
@@ -9,6 +10,7 @@ from fastapi import FastAPI
9
  from fastapi.middleware.cors import CORSMiddleware
10
  from fastapi.responses import JSONResponse
11
  from contextlib import asynccontextmanager
 
12
 
13
  from app.page_speed.config import settings
14
  from app.page_speed.models import HealthResponse
@@ -19,19 +21,16 @@ from app.content_relevence import routes as content_relevance_routes
19
  from app.keywords.routes import router as keywords_router
20
  from app.uiux import routes as uiux_routes
21
  from app.mobile_usability import routes as mobile_usability
22
- # app/suppress_warnings.py
23
-
24
- import warnings
25
 
26
- # Suppress Pydantic config change warning
 
 
27
  warnings.filterwarnings(
28
  "ignore",
29
  message="Valid config keys have changed in V2:*",
30
  category=UserWarning,
31
  module="pydantic._internal._config",
32
  )
33
-
34
- # Suppress other optional warnings
35
  warnings.filterwarnings("ignore", category=FutureWarning)
36
  try:
37
  from langchain_core._api.deprecation import LangChainDeprecationWarning
@@ -39,13 +38,11 @@ try:
39
  except ImportError:
40
  pass
41
 
42
-
43
- # ------------------------
44
- # Configure root logger
45
- # ------------------------
46
  logger = logging.getLogger("app")
47
  logger.setLevel(logging.INFO)
48
-
49
  handler = logging.StreamHandler()
50
  formatter = logging.Formatter(
51
  "%(asctime)s | %(levelname)s | %(name)s | %(message)s",
@@ -54,20 +51,20 @@ formatter = logging.Formatter(
54
  handler.setFormatter(formatter)
55
  logger.addHandler(handler)
56
 
57
- # Global variable to track startup time
58
  startup_time = None
59
 
60
  @asynccontextmanager
61
  async def lifespan(app: FastAPI):
62
- """Application lifespan manager."""
63
  global startup_time
64
  startup_time = time.time()
65
  logger.info("πŸš€ Starting %s v%s", settings.app_name, settings.app_version)
66
- logger.info("πŸ“Š Server running on %s:%s", settings.host, settings.port)
67
  yield
68
  logger.info("πŸ“Š Shutting down %s", settings.app_name)
69
 
70
- # Create FastAPI app instance
 
 
71
  app = FastAPI(
72
  title=settings.app_name,
73
  description=settings.app_description,
@@ -77,36 +74,29 @@ app = FastAPI(
77
  redoc_url="/redoc"
78
  )
79
 
80
- # Mount RAG router
81
  app.include_router(rag_router)
82
-
83
  app.include_router(seo_routes.router)
84
-
85
  app.include_router(content_relevance_routes.router)
86
-
87
- # Mount PageSpeed router
88
  app.include_router(page_speed_routes.router)
89
-
90
- # Mount the keywords router
91
  app.include_router(keywords_router)
92
-
93
- # Mount UI/UX router
94
  app.include_router(uiux_routes.router)
95
-
96
  app.include_router(mobile_usability.router)
97
 
98
- # Add CORS middleware
99
  app.add_middleware(
100
  CORSMiddleware,
101
- allow_origins=["*"], # In production, specify exact origins
102
  allow_credentials=True,
103
  allow_methods=["*"],
104
  allow_headers=["*"],
105
  )
106
 
 
 
 
107
  @app.get("/", response_model=dict)
108
  async def root():
109
- """Root endpoint with API information."""
110
  return {
111
  "message": f"Welcome to {settings.app_name}",
112
  "version": settings.app_version,
@@ -115,28 +105,22 @@ async def root():
115
  "health": "/health"
116
  }
117
 
118
-
119
  @app.get("/health", response_model=HealthResponse)
120
  async def health_check():
121
- """Health check endpoint."""
122
- global startup_time
123
-
124
  if startup_time:
125
  uptime_seconds = time.time() - startup_time
126
  uptime_str = f"{uptime_seconds:.2f} seconds"
127
  else:
128
  uptime_str = "Unknown"
129
-
130
  return HealthResponse(
131
  status="healthy",
132
  version=settings.app_version,
133
  uptime=uptime_str
134
  )
135
 
136
-
137
  @app.exception_handler(404)
138
  async def not_found_handler(request, exc):
139
- """Custom 404 handler."""
140
  logger.warning("404 Not Found: %s %s", request.method, request.url.path)
141
  return JSONResponse(
142
  status_code=404,
@@ -149,7 +133,6 @@ async def not_found_handler(request, exc):
149
 
150
  @app.exception_handler(500)
151
  async def internal_error_handler(request, exc):
152
- """Custom 500 handler."""
153
  logger.error("500 Internal Server Error: %s %s -> %s", request.method, request.url.path, exc, exc_info=True)
154
  return JSONResponse(
155
  status_code=500,
@@ -160,13 +143,20 @@ async def internal_error_handler(request, exc):
160
  }
161
  )
162
 
163
-
 
 
164
  if __name__ == "__main__":
165
  import uvicorn
166
- # When running directly, uvicorn will print its own logs. We just start it here.
 
 
 
 
 
167
  uvicorn.run(
168
  "app.main:app",
169
- host=settings.host,
170
- port=settings.port,
171
  reload=settings.debug
172
  )
 
1
  """
2
  Main FastAPI application module.
3
  """
4
+ import os
5
  import time
6
  import logging
7
  import json
 
10
  from fastapi.middleware.cors import CORSMiddleware
11
  from fastapi.responses import JSONResponse
12
  from contextlib import asynccontextmanager
13
+ import warnings
14
 
15
  from app.page_speed.config import settings
16
  from app.page_speed.models import HealthResponse
 
21
  from app.keywords.routes import router as keywords_router
22
  from app.uiux import routes as uiux_routes
23
  from app.mobile_usability import routes as mobile_usability
 
 
 
24
 
25
+ # ─────────────────────────────────────────────
26
+ # Suppress warnings
27
+ # ─────────────────────────────────────────────
28
  warnings.filterwarnings(
29
  "ignore",
30
  message="Valid config keys have changed in V2:*",
31
  category=UserWarning,
32
  module="pydantic._internal._config",
33
  )
 
 
34
  warnings.filterwarnings("ignore", category=FutureWarning)
35
  try:
36
  from langchain_core._api.deprecation import LangChainDeprecationWarning
 
38
  except ImportError:
39
  pass
40
 
41
+ # ─────────────────────────────────────────────
42
+ # Logging setup
43
+ # ─────────────────────────────────────────────
 
44
  logger = logging.getLogger("app")
45
  logger.setLevel(logging.INFO)
 
46
  handler = logging.StreamHandler()
47
  formatter = logging.Formatter(
48
  "%(asctime)s | %(levelname)s | %(name)s | %(message)s",
 
51
  handler.setFormatter(formatter)
52
  logger.addHandler(handler)
53
 
 
54
  startup_time = None
55
 
56
  @asynccontextmanager
57
  async def lifespan(app: FastAPI):
 
58
  global startup_time
59
  startup_time = time.time()
60
  logger.info("πŸš€ Starting %s v%s", settings.app_name, settings.app_version)
61
+ logger.info("πŸ“Š Server will run on %s:%s", settings.host, settings.port)
62
  yield
63
  logger.info("πŸ“Š Shutting down %s", settings.app_name)
64
 
65
+ # ─────────────────────────────────────────────
66
+ # FastAPI app creation
67
+ # ─────────────────────────────────────────────
68
  app = FastAPI(
69
  title=settings.app_name,
70
  description=settings.app_description,
 
74
  redoc_url="/redoc"
75
  )
76
 
77
+ # Include routers
78
  app.include_router(rag_router)
 
79
  app.include_router(seo_routes.router)
 
80
  app.include_router(content_relevance_routes.router)
 
 
81
  app.include_router(page_speed_routes.router)
 
 
82
  app.include_router(keywords_router)
 
 
83
  app.include_router(uiux_routes.router)
 
84
  app.include_router(mobile_usability.router)
85
 
86
+ # CORS
87
  app.add_middleware(
88
  CORSMiddleware,
89
+ allow_origins=["*"], # TODO: Restrict in production
90
  allow_credentials=True,
91
  allow_methods=["*"],
92
  allow_headers=["*"],
93
  )
94
 
95
+ # ─────────────────────────────────────────────
96
+ # Routes
97
+ # ─────────────────────────────────────────────
98
  @app.get("/", response_model=dict)
99
  async def root():
 
100
  return {
101
  "message": f"Welcome to {settings.app_name}",
102
  "version": settings.app_version,
 
105
  "health": "/health"
106
  }
107
 
 
108
  @app.get("/health", response_model=HealthResponse)
109
  async def health_check():
 
 
 
110
  if startup_time:
111
  uptime_seconds = time.time() - startup_time
112
  uptime_str = f"{uptime_seconds:.2f} seconds"
113
  else:
114
  uptime_str = "Unknown"
115
+
116
  return HealthResponse(
117
  status="healthy",
118
  version=settings.app_version,
119
  uptime=uptime_str
120
  )
121
 
 
122
  @app.exception_handler(404)
123
  async def not_found_handler(request, exc):
 
124
  logger.warning("404 Not Found: %s %s", request.method, request.url.path)
125
  return JSONResponse(
126
  status_code=404,
 
133
 
134
  @app.exception_handler(500)
135
  async def internal_error_handler(request, exc):
 
136
  logger.error("500 Internal Server Error: %s %s -> %s", request.method, request.url.path, exc, exc_info=True)
137
  return JSONResponse(
138
  status_code=500,
 
143
  }
144
  )
145
 
146
+ # ─────────────────────────────────────────────
147
+ # Entrypoint
148
+ # ─────────────────────────────────────────────
149
  if __name__ == "__main__":
150
  import uvicorn
151
+
152
+ # Force Cloud Run compatible host/port
153
+ host = os.getenv("HOST", "0.0.0.0")
154
+ port = int(os.getenv("PORT", settings.port if settings.port else 8080))
155
+
156
+ logger.info(f"Starting Uvicorn with host={host}, port={port}")
157
  uvicorn.run(
158
  "app.main:app",
159
+ host=host,
160
+ port=port,
161
  reload=settings.debug
162
  )