Spaces:
Running
Running
File size: 6,881 Bytes
efd6a61 90ca14a efd6a61 75c5f1f efd6a61 b1f421c 1cf0ddf b1f421c efd6a61 97a1351 51c5935 97a1351 efd6a61 b1f421c efd6a61 1cf0ddf 5d8720e efd6a61 75c5f1f efd6a61 1cf0ddf 97a1351 51c5935 1cf0ddf 97a1351 efd6a61 75c5f1f efd6a61 efd67c2 90ca14a efd67c2 90ca14a d4ebc98 90ca14a 18d9c79 90ca14a efd67c2 a0fc312 4382787 973de0d 5ffacbe 973de0d a9634f7 be2ede1 d8a939d 129ca08 20f564f 05d7096 a6517ab 508be3f 05d7096 a3b3bf7 20f564f a3b3bf7 20f564f 129ca08 efd6a61 75c5f1f efd6a61 |
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 |
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
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
from fastapi.responses import JSONResponse
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
app.mount("/static", StaticFiles(directory="static"), name="static")
# Add a route for serving the HTML file
@app.get("/", response_class=HTMLResponse)
async def serve_resume_optimizer():
with open("static/index.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("/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)
@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) |