Spaces:
Sleeping
Sleeping
File size: 11,939 Bytes
efd6a61 90ca14a 9a99c76 efd6a61 75c5f1f efd6a61 b1f421c 070678d 66cff10 876070a 589985f efd6a61 589985f efd6a61 589985f efd6a61 589985f efd6a61 97a1351 51c5935 97a1351 efd6a61 b1f421c efd6a61 589985f 1cf0ddf 5d8720e efd6a61 75c5f1f efd6a61 1cf0ddf 97a1351 51c5935 1cf0ddf 97a1351 efd6a61 75c5f1f efd6a61 efd67c2 589985f 607ce82 efd67c2 6d6fcef 43a2f5a 607ce82 43a2f5a 9a99c76 589985f d4ebc98 36f58d9 90ca14a efd67c2 589985f a0fc312 4382787 973de0d 5ffacbe 973de0d a9634f7 be2ede1 589985f d8a939d 589985f 129ca08 20f564f 05d7096 a6517ab 589985f 508be3f d9caca4 c7659f4 d9caca4 508be3f bb610ed 9a37bde 589985f a3b3bf7 20f564f a3b3bf7 20f564f 129ca08 66cff10 070678d 66cff10 070678d 66cff10 070678d 66cff10 070678d 66cff10 070678d 66cff10 070678d 66cff10 070678d 66cff10 070678d 66cff10 070678d efd6a61 503c1eb 589985f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 |
from fastapi import FastAPI, File, UploadFile, Form, HTTPException, Request, Depends
from fastapi.staticfiles import StaticFiles
from fastapi.responses import HTMLResponse
from fastapi.responses import JSONResponse, FileResponse
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from pydantic import BaseModel, HttpUrl
from typing import Optional
import uvicorn
from fastapi.middleware.cors import CORSMiddleware
from utils import read_file, fetch_job_description, optimize_resume_api
import logging
import os
import json
from supabase import create_client
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
# Set up templates
templates = Jinja2Templates(directory="static")
# Configuration variables (use environment variables in production)
SUPABASE_URL = os.getenv("SUPABASE_URL")
SUPABASE_KEY = os.getenv("SUPABASE_KEY")
# Initialize Supabase client
supabase = create_client(SUPABASE_URL, SUPABASE_KEY)
API_SECRET = os.getenv("API_SECRET")
# Set up logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
app = FastAPI(title="Resume Optimizer API")
app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"])
security = HTTPBearer()
class OptimizationResponse(BaseModel):
optimized_resume: str
changes_made: str
metadata: dict
class ErrorResponse(BaseModel):
detail: str
def verify_token(credentials: HTTPAuthorizationCredentials = Depends(security)):
token = credentials.credentials
if token != API_SECRET:
raise HTTPException(status_code=401, detail="Invalid authentication token")
return token
import re
def extract_xml_content(text, tag):
pattern = f"<{tag}>(.*?)</{tag}>"
matches = re.findall(pattern, text, re.DOTALL)
return matches
@app.post("/api/v1/optimize-resume", response_model=OptimizationResponse, responses={400: {"model": ErrorResponse}, 401: {"model": ErrorResponse}, 500: {"model": ErrorResponse}})
async def optimize_resume(
resume: Optional[UploadFile] = File(None),
resumeText: Optional[str] = Form(None),
jobDescription: Optional[str] = Form(None),
jobDescriptionUrl: Optional[HttpUrl] = Form(None),
token: str = Depends(verify_token)
):
try:
# Input validation
if (resume is None) == (resumeText is None):
raise ValueError("Provide either resume file or resume text, but not both")
if (jobDescription is None) == (jobDescriptionUrl is None):
raise ValueError("Provide either job description text or URL, but not both")
# Process resume
if resume:
resume_content = read_file(resume)
else:
resume_content = resumeText
# Process job description
if jobDescription:
job_description_content = jobDescription
else:
job_description_content = fetch_job_description(jobDescriptionUrl)
# Perform optimization
output = optimize_resume_api(resume_content, job_description_content)
optimized_resume = extract_xml_content(output, "optimized_resume")
changes_made = extract_xml_content(output, "changes_made")
# Prepare the response
response_data = OptimizationResponse(
optimized_resume=optimized_resume[0] if optimized_resume else "",
changes_made=changes_made[0] if changes_made else "",
metadata={
"original_resume": resume_content,
"original_jd": job_description_content
}
)
return response_data
except ValueError as ve:
logger.error(f"ValueError occurred: {str(ve)}", exc_info=True)
raise HTTPException(status_code=400, detail=str(ve))
except Exception as e:
logger.error(f"Unexpected error occurred: {str(e)}", exc_info=True)
raise HTTPException(status_code=500, detail=f"An unexpected error occurred: {str(e)}")
# Mount the static directory
static_dir = os.path.join(os.path.dirname(__file__), "static")
app.mount("/static", StaticFiles(directory=static_dir), name="static")
# Set up templates
templates = Jinja2Templates(directory="static")
app.mount("/iresearcher-v3", StaticFiles(directory="static/iresearcher", html=True), name="iresearcher")
# App1 route
@app.get("/iresearcher-v2", response_class=HTMLResponse)
async def iresearcher_v2(request: Request):
try:
# Debug: Print the current working directory
print(f"Current working directory: {os.getcwd()}")
# Debug: Print the full path of the template
template_path = os.path.join(static_dir, "iresearcher", "index.html")
print(f"Full template path: {template_path}")
# Debug: Check if the file exists
if not os.path.exists(template_path):
raise HTTPException(status_code=404, detail=f"Template not found: {template_path}")
# Debug: Print the content of the template file
with open(template_path, 'r') as f:
print(f"Template content:\n{f.read()}")
# Render the template
return templates.TemplateResponse("iresearcher/index.html", {"request": request})
except Exception as e:
# Log any exceptions
print(f"Error rendering template: {str(e)}")
raise HTTPException(status_code=500, detail=str(e))
@app.get("/js/{path:path}")
async def send_js(path: str):
file_path = f"static/js/apps-hub/{path}"
if os.path.exists(file_path):
return FileResponse(file_path)
raise HTTPException(status_code=404, detail="File not found")
@app.get("/css/{path:path}")
async def send_css(path: str):
file_path = f"static/css/apps-hub/{path}"
if os.path.exists(file_path):
return FileResponse(file_path)
raise HTTPException(status_code=404, detail="File not found")
@app.get("/svg/{path:path}")
async def send_svg(path: str):
file_path = f"static/svg/{path}"
if os.path.exists(file_path):
return FileResponse(file_path)
raise HTTPException(status_code=404, detail="File not found")
@app.get("/png/{path:path}")
async def send_png(path: str):
file_path = f"static/png/{path}"
if os.path.exists(file_path):
return FileResponse(file_path)
raise HTTPException(status_code=404, detail="File not found")
# Add a route for serving the HTML file
@app.get("/", response_class=HTMLResponse)
async def serve_landing_page():
with open("static/landing-page.html", "r") as file:
content = file.read()
return HTMLResponse(content=content)
# Add a route for serving the HTML file
@app.get("/career", response_class=HTMLResponse)
async def serve_resume_optimizer():
with open("static/resume-optimizer.html", "r") as file:
content = file.read()
return HTMLResponse(content=content)
@app.get("/followup-agent", response_class=HTMLResponse)
async def serve_resume_optimizer():
with open("static/followup-agent.html", "r") as file:
content = file.read()
return HTMLResponse(content=content)
@app.get("/digiyatra", response_class=HTMLResponse)
async def serve_resume_optimizer():
with open("static/digiyatra.html", "r") as file:
content = file.read()
return HTMLResponse(content=content)
@app.get("/auth", response_class=HTMLResponse)
async def serve_resume_optimizer():
with open("static/auth.html", "r") as file:
content = file.read()
return HTMLResponse(content=content)
@app.get("/auth-success", response_class=HTMLResponse)
async def serve_resume_optimizer():
with open("static/auth-success.html", "r") as file:
content = file.read()
return HTMLResponse(content=content)
@app.get("/app-selector", response_class=HTMLResponse)
async def serve_resume_optimizer():
with open("static/v0/app-selector.html", "r") as file:
content = file.read()
return HTMLResponse(content=content)
@app.get("/multi-agent", response_class=HTMLResponse)
async def serve_resume_optimizer():
with open("static/multi-agent.html", "r") as file:
content = file.read()
return HTMLResponse(content=content)
@app.get("/medium-report", response_class=HTMLResponse)
async def serve_resume_optimizer():
with open("static/medium-report.html", "r") as file:
content = file.read()
return HTMLResponse(content=content)
@app.get("/iresearcher", response_class=HTMLResponse)
async def serve_iresearcher():
with open("static/iresearcher.html", "r") as file:
content = file.read()
return HTMLResponse(content=content)
@app.get("/graph-maker", response_class=HTMLResponse)
async def serve_iresearcher():
with open("static/graph-maker.html", "r") as file:
content = file.read()
return HTMLResponse(content=content)
@app.get("/indic-tts", response_class=HTMLResponse)
async def serve_indic_tts():
with open("static/indic-text-to-speech.html", "r") as file:
content = file.read()
return HTMLResponse(content=content)
@app.get("/presentation", response_class=HTMLResponse)
async def presentation():
with open("static/presentation-agent.html", "r") as file:
content = file.read()
return HTMLResponse(content=content)
@app.get("/dashboard", response_class=HTMLResponse)
async def presentation():
with open("static/mult-agent-auth.html", "r") as file:
content = file.read()
return HTMLResponse(content=content)
@app.get("/login", response_class=HTMLResponse)
async def presentation():
with open("static/login.html", "r") as file:
content = file.read()
return HTMLResponse(content=content)
@app.get("/file-convert", response_class=HTMLResponse)
async def serve_resume_optimizer():
with open("static/file-convert.html", "r") as file:
content = file.read()
return HTMLResponse(content=content)
from fastapi import HTTPException
from pydantic import BaseModel
class EmailCheck(BaseModel):
email: str
@app.post("/check-allowlist")
async def check_allowlist(email_check: EmailCheck):
logging.debug(f"Checking email: {email_check.email}")
try:
# Fetch allowlist from Supabase, including email and access_type
response = supabase.table('email_allowlist').select('email,access_type').eq('email', email_check.email).execute()
if response.data:
user_data = response.data[0]
logging.debug(f"Email is in allowlist with access type: {user_data['access_type']}")
try:
# Read the appropriate JSON file based on access type
if user_data['access_type'] == 'team':
file_name = "app_urls_team.json"
else:
file_name = "app_urls_public.json"
# Try to read the JSON file with UTF-8 encoding
with open(file_name, "r", encoding="utf-8") as file:
app_data = json.load(file)
except UnicodeDecodeError:
# If UTF-8 fails, try with ISO-8859-1 encoding
with open(file_name, "r", encoding="iso-8859-1") as file:
app_data = json.load(file)
return {
"allowed": True,
"access_type": user_data['access_type'],
"app_data": app_data
}
else:
logging.debug("Email is not in allowlist")
return {"allowed": False}
except Exception as e:
logging.error(f"Error: {e}")
raise HTTPException(status_code=500, detail=str(e))
@app.exception_handler(HTTPException)
async def http_exception_handler(request: Request, exc: HTTPException):
return JSONResponse(status_code=exc.status_code, content={"detail": exc.detail})
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000, debug=True) |