pvanand commited on
Commit
efd6a61
·
verified ·
1 Parent(s): dfffe93

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +104 -157
main.py CHANGED
@@ -1,164 +1,111 @@
1
- from fastapi import FastAPI, HTTPException, Request, Query
2
- from fastapi.middleware.cors import CORSMiddleware
3
- # from fastapi_cache import FastAPICache
4
- # from fastapi_cache.backends.inmemory import InMemoryBackend
5
- # from fastapi_cache.decorator import cache
6
- from queue import Empty
7
- import os
8
- app = FastAPI()
9
- root_dir = os.getcwd()
10
- # @app.on_event("startup")
11
- # async def startup():
12
- # FastAPICache.init(InMemoryBackend(), prefix="fastapi-cache")
13
-
14
- from pydantic import BaseModel
15
- from typing import List, Dict, Any
16
-
17
- TOGETHER_API_KEY = os.getenv('TOGETHER_API_KEY')
18
- BRAVE_API_KEY = os.getenv('BRAVE_API_KEY')
19
- GROQ_API_KEY = os.getenv("GROQ_API_KEY")
20
- HELICON_API_KEY = os.getenv("HELICON_API_KEY")
21
- SUPABASE_USER = os.environ['SUPABASE_USER']
22
- SUPABASE_PASSWORD = os.environ['SUPABASE_PASSWORD']
23
-
24
- app.add_middleware(
25
- CORSMiddleware,
26
- allow_origins=["*"],
27
- allow_credentials=True,
28
- allow_methods=["*"],
29
- allow_headers=["*"],)
30
-
31
- import asyncio
32
  import uvicorn
33
- from fastapi import FastAPI, HTTPException
34
- from pydantic import BaseModel
35
- from jupyter_client import KernelManager
36
- from typing import Dict
37
- from datetime import datetime, timedelta
38
- import psutil
39
-
40
- # Model for input data
41
- class CodeExecutionRequest(BaseModel):
42
- session_token: str
43
- code: str
44
-
45
- # Store kernel managers and last access times
46
- kernel_managers: Dict[str, KernelManager] = {}
47
- last_access_times: Dict[str, datetime] = {}
48
-
49
- # Timeout duration in seconds
50
- TIMEOUT_DURATION = 600 # 10 minutes
51
-
52
- # Function to create a new kernel
53
- async def create_kernel(session_token: str):
54
- km = KernelManager()
55
- km.start_kernel()
56
- kernel_managers[session_token] = km
57
- last_access_times[session_token] = datetime.now()
58
-
59
- # Function to kill a kernel
60
- async def kill_kernel(session_token: str):
61
- km = kernel_managers.pop(session_token, None)
62
- if km:
63
- km.shutdown_kernel(now=True)
64
- last_access_times.pop(session_token, None)
65
-
66
- session_dir = os.path.join(root_dir, "output", session_token)
67
- if os.path.exists(session_dir):
68
- shutil.rmtree(session_dir)
69
-
70
- # Function to execute code in a kernel
71
- # Function to execute code in a kernel
72
- async def execute_code(session_token: str, code: str):
73
- setup_code = "%matplotlib inline"
74
-
75
- session_dir = os.path.join(root_dir,"output", session_token)
76
-
77
- if not os.path.exists(session_dir):
78
- os.makedirs(session_dir)
79
-
80
- if session_token not in kernel_managers:
81
- await create_kernel(session_token)
82
-
83
- km = kernel_managers[session_token]
84
- kc = km.client()
85
-
86
  try:
87
- os.chdir(session_dir)
88
- print("current working directory",os.getcwd())
89
- # Execute setup code
90
- kc.execute_interactive(setup_code, store_history=False)
91
- # Execute the provided code
92
- kc.execute(code, store_history=False)
93
-
94
- output = []
95
- timeout = datetime.now() + timedelta(seconds=TIMEOUT_DURATION)
96
-
97
- output = []
98
- while True:
99
- if datetime.now() > timeout:
100
- raise TimeoutError("Code execution timed out.")
101
-
102
- msg = kc.get_iopub_msg()
103
- if msg['msg_type'] == 'status' and msg['content']['execution_state'] == 'idle':
104
- break
105
- elif msg['msg_type'] == 'error':
106
- error_output = {
107
- "ename": msg['content']['ename'],
108
- "evalue": msg['content']['evalue'],
109
- "traceback": msg['content']['traceback']
110
- }
111
- output.append({"error": error_output})
112
- if 'data' in msg['content']:
113
- output.append({"data": msg['content']['data']})
114
- elif 'text' in msg['content']:
115
- output.append({"text": msg['content']['text']})
116
-
117
- last_access_times[session_token] = datetime.now()
118
- print("Execution SUCCESS")
119
- print("#################")
120
- print("CODE:",code)
121
- print("OUTPUT:",output)
122
- return {'status': 'success', 'value': output}
123
-
 
 
 
 
 
 
 
 
 
124
  except Exception as e:
125
- last_access_times[session_token] = datetime.now()
126
- return {'status': 'error', 'value': str(e)}
127
-
128
-
129
- # Background task to check for idle kernels
130
- async def check_idle_kernels():
131
- while True:
132
- now = datetime.now()
133
- for session_token, last_access in list(last_access_times.items()):
134
- if now - last_access > timedelta(seconds=TIMEOUT_DURATION):
135
- await kill_kernel(session_token)
136
- await asyncio.sleep(60) # Check every minute
137
 
138
  @app.on_event("startup")
139
- async def startup_event():
140
- asyncio.create_task(check_idle_kernels())
141
-
142
- @app.post("/execute")
143
- async def execute(request: CodeExecutionRequest):
144
- result = await execute_code(request.session_token, request.code)
145
- return result
146
-
147
- @app.get("/info")
148
- async def get_info():
149
- # Get the number of active kernels
150
- active_kernels = len(kernel_managers)
151
-
152
- # Get system resource usage
153
- cpu_usage = psutil.cpu_percent(interval=1)
154
- ram_usage = psutil.virtual_memory().percent
155
-
156
- # Return the information
157
- return {
158
- "active_kernels": active_kernels,
159
- "cpu_usage_percent": cpu_usage,
160
- "ram_usage_percent": ram_usage
161
- }
162
 
163
  if __name__ == "__main__":
164
- uvicorn.run(app, host="0.0.0.0", port=7860)
 
1
+ from fastapi import FastAPI, File, UploadFile, Form, HTTPException, Request, Depends
2
+ from fastapi.responses import JSONResponse
3
+ from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
4
+ from pydantic import BaseModel, HttpUrl
5
+ from typing import Optional
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  import uvicorn
7
+ from fastapi.middleware.cors import CORSMiddleware
8
+ from utils import read_file, fetch_job_description, optimize_resume_api
9
+ import logging
10
+ from fastapi_cache import FastAPICache
11
+ from fastapi_cache.backends.inmemory import InMemoryBackend
12
+ from fastapi_cache.decorator import cache
13
+ import hashlib
14
+
15
+ # Set up logging
16
+ logging.basicConfig(level=logging.DEBUG)
17
+ logger = logging.getLogger(__name__)
18
+
19
+ app = FastAPI(title="Resume Optimizer API")
20
+
21
+ app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"])
22
+
23
+ security = HTTPBearer()
24
+
25
+ class OptimizationResponse(BaseModel):
26
+ optimizedResume: str
27
+ metadata: dict
28
+
29
+ class ErrorResponse(BaseModel):
30
+ detail: str
31
+
32
+ def verify_token(credentials: HTTPAuthorizationCredentials = Depends(security)):
33
+ token = credentials.credentials
34
+ if token != "your_secret_token":
35
+ raise HTTPException(status_code=401, detail="Invalid authentication token")
36
+ return token
37
+
38
+ def generate_cache_key(resume_content: str, job_description_content: str) -> str:
39
+ combined = resume_content + job_description_content
40
+ return hashlib.md5(combined.encode()).hexdigest()
41
+
42
+ @app.post("/api/optimize-resume", response_model=OptimizationResponse, responses={400: {"model": ErrorResponse}, 401: {"model": ErrorResponse}, 500: {"model": ErrorResponse}})
43
+ @cache(expire=36000000) # Cache for n seconds
44
+ async def optimize_resume(
45
+ resume: Optional[UploadFile] = File(None),
46
+ resumeText: Optional[str] = Form(None),
47
+ jobDescription: Optional[str] = Form(None),
48
+ jobDescriptionUrl: Optional[HttpUrl] = Form(None),
49
+ token: str = Depends(verify_token)
50
+ ):
 
 
 
 
 
 
 
 
 
51
  try:
52
+ # Input validation
53
+ if (resume is None) == (resumeText is None):
54
+ raise ValueError("Provide either resume file or resume text, but not both")
55
+ if (jobDescription is None) == (jobDescriptionUrl is None):
56
+ raise ValueError("Provide either job description text or URL, but not both")
57
+
58
+ # Process resume
59
+ if resume:
60
+ resume_content = read_file(resume)
61
+ else:
62
+ resume_content = resumeText
63
+
64
+ # Process job description
65
+ if jobDescription:
66
+ job_description_content = jobDescription
67
+ else:
68
+ job_description_content = fetch_job_description(jobDescriptionUrl)
69
+
70
+ # Generate cache key
71
+ cache_key = generate_cache_key(resume_content, job_description_content)
72
+
73
+ # Check cache
74
+ cached_result = await FastAPICache.get(cache_key)
75
+ if cached_result:
76
+ return OptimizationResponse(**cached_result)
77
+
78
+ # Perform optimization
79
+ optimized_resume = optimize_resume_api(resume_content, job_description_content)
80
+
81
+ metadata = {
82
+ "original_resume": resume_content,
83
+ "original_jd": job_description_content
84
+ }
85
+
86
+ result = OptimizationResponse(
87
+ optimizedResume=optimized_resume,
88
+ metadata=metadata
89
+ )
90
+
91
+ # Cache the result
92
+ await FastAPICache.set(cache_key, result.dict(), expire=36000000)
93
+
94
+ return result
95
+ except ValueError as ve:
96
+ logger.error(f"ValueError occurred: {str(ve)}", exc_info=True)
97
+ raise HTTPException(status_code=400, detail=str(ve))
98
  except Exception as e:
99
+ logger.error(f"Unexpected error occurred: {str(e)}", exc_info=True)
100
+ raise HTTPException(status_code=500, detail=f"An unexpected error occurred: {str(e)}")
101
+
102
+ @app.exception_handler(HTTPException)
103
+ async def http_exception_handler(request: Request, exc: HTTPException):
104
+ return JSONResponse(status_code=exc.status_code, content={"detail": exc.detail})
 
 
 
 
 
 
105
 
106
  @app.on_event("startup")
107
+ async def startup():
108
+ FastAPICache.init(InMemoryBackend(), prefix="fastapi-cache")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
 
110
  if __name__ == "__main__":
111
+ uvicorn.run(app, host="0.0.0.0", port=8000, debug=True)