Coverage for backend / app / main.py: 92%

83 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-03-17 21:34 +0000

1"""Main script""" 

2 

3from contextlib import asynccontextmanager 

4 

5import jwt 

6from fastapi import FastAPI, APIRouter, Request 

7from fastapi.middleware.cors import CORSMiddleware 

8 

9from app import database 

10from app import routers as app_routers 

11from app.config import settings 

12from app.core import routers as core_routers 

13from app.data_tables import routers as data_table_routers 

14from app.demo import routers as demo_routers 

15from app.demo.setup import setup_demo_schema 

16from app.emails import routers as email_routers 

17from app.geolocation import routers as geolocation_routers 

18from app.job_email_scraping import routers as job_email_scraping_routers 

19from app.job_rating import routers as job_rating_routers 

20from app.payments import routers as payment_routers 

21 

22 

23@asynccontextmanager 

24async def lifespan(_app: FastAPI): 

25 """Application lifespan event handler.""" 

26 

27 setup_demo_schema() 

28 yield 

29 

30 

31app = FastAPI(title="JAM", version=settings.app_version, lifespan=lifespan) 

32 

33 

34def get_allowed_origins() -> list[str]: 

35 """Get allowed CORS origins based on environment""" 

36 

37 # In test mode, allow all origins 

38 if settings.test_mode: 

39 return ["*"] 

40 

41 # In production, allow only the frontend URL 

42 else: 

43 return [settings.frontend_url, "http://localhost:3000"] 

44 

45 

46app.add_middleware( 

47 CORSMiddleware, 

48 allow_origins=get_allowed_origins(), 

49 allow_credentials=True, 

50 allow_methods=["*"], 

51 allow_headers=["*"], 

52) 

53 

54 

55@app.middleware("http") 

56async def demo_schema_middleware(request: Request, call_next): 

57 """Detect demo tokens and set demo_mode context variable.""" 

58 

59 token = request.headers.get("Authorization", "").replace("Bearer ", "") 

60 if token: 

61 try: 

62 payload = jwt.decode(token, settings.secret_key, algorithms=[settings.algorithm]) 

63 if payload.get("is_demo"): 

64 database.demo_mode.set(True) 

65 except Exception: 

66 pass 

67 response = await call_next(request) 

68 database.demo_mode.set(False) 

69 return response 

70 

71 

72# Data table routers 

73app.include_router(data_table_routers.company_router) 

74app.include_router(data_table_routers.person_router) 

75app.include_router(data_table_routers.location_router) 

76app.include_router(data_table_routers.job_router) 

77app.include_router(data_table_routers.aggregator_router) 

78app.include_router(data_table_routers.interview_router) 

79app.include_router(data_table_routers.keyword_router) 

80app.include_router(data_table_routers.file_router) 

81app.include_router(data_table_routers.job_application_update_router) 

82app.include_router(data_table_routers.speculative_application_update_router) 

83 

84# Job Scraping routers 

85app.include_router(job_email_scraping_routers.scraped_job_router) 

86app.include_router(job_email_scraping_routers.job_alert_email_router) 

87app.include_router(job_email_scraping_routers.job_scraping_service_log_router) 

88app.include_router(job_email_scraping_routers.email_scraper_service_router) 

89app.include_router(job_email_scraping_routers.scraping_filter_router) 

90app.include_router(job_email_scraping_routers.forwarding_confirmation_router) 

91 

92# Job Rating routers 

93app.include_router(job_rating_routers.llm_system_prompt_router) 

94app.include_router(job_rating_routers.job_rating_router) 

95app.include_router(job_rating_routers.job_rating_service_log_router) 

96app.include_router(job_rating_routers.job_rating_service_router) 

97 

98# User routers 

99app.include_router(core_routers.user_router) 

100app.include_router(core_routers.current_user_router) 

101app.include_router(core_routers.user_qualification_router) 

102 

103# Auth routers 

104app.include_router(core_routers.login_router) 

105app.include_router(core_routers.register_router) 

106app.include_router(core_routers.password_router) 

107 

108# Export router 

109app.include_router(app_routers.export_router) 

110 

111# Settings router 

112app.include_router(core_routers.settings_router) 

113 

114# Email admin 

115app.include_router(email_routers.email_template_router) 

116 

117# Others 

118app.include_router(app_routers.other_router) 

119app.include_router(app_routers.config_router) 

120app.include_router(geolocation_routers.router) 

121 

122# Demo 

123app.include_router(demo_routers.demo_router) 

124 

125# Stripe 

126app.include_router(payment_routers.payment_router) 

127 

128# Testing 

129if settings.test_mode: 

130 app.include_router(email_routers.email_test_router) 

131 app.include_router(payment_routers.payment_test_router) 

132 

133 

134@app.get("/") 

135def read_root() -> dict: 

136 """Root endpoint""" 

137 

138 return {"message": "Welcome to the JAM API"} 

139 

140 

141health_router = APIRouter(prefix="/health", tags=["health"]) 

142 

143 

144@app.get("/health") 

145def health_check() -> dict: 

146 """Health check endpoint""" 

147 

148 return {"status": "ok"}