Spaces:
Sleeping
Sleeping
Commit ·
adfe44e
1
Parent(s): 78e1a17
uploading all files
Browse files- Dockerfile +12 -0
- app/__pycache__/main.cpython-310.pyc +0 -0
- app/controllers/__pycache__/lm_controller.cpython-310.pyc +0 -0
- app/controllers/lm_controller.py +38 -0
- app/generated_lm.docx +0 -0
- app/main.py +6 -0
- app/models/__pycache__/docx_generator.cpython-310.pyc +0 -0
- app/models/__pycache__/lm_generator.cpython-310.pyc +0 -0
- app/models/__pycache__/pdf_generator.cpython-310.pyc +0 -0
- app/models/docx_generator.py +22 -0
- app/models/lm_generator.py +20 -0
- app/models/pdf_generator.py +13 -0
- requirements.txt +6 -0
Dockerfile
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM python:3.10-slim
|
| 2 |
+
|
| 3 |
+
WORKDIR /app
|
| 4 |
+
|
| 5 |
+
COPY requirements.txt ./
|
| 6 |
+
RUN pip install --no-cache-dir -r requirements.txt
|
| 7 |
+
|
| 8 |
+
COPY ./app ./app
|
| 9 |
+
|
| 10 |
+
EXPOSE 8000
|
| 11 |
+
|
| 12 |
+
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
app/__pycache__/main.cpython-310.pyc
ADDED
|
Binary file (328 Bytes). View file
|
|
|
app/controllers/__pycache__/lm_controller.cpython-310.pyc
ADDED
|
Binary file (1.64 kB). View file
|
|
|
app/controllers/lm_controller.py
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from fastapi import APIRouter, HTTPException
|
| 2 |
+
from models.lm_generator import AiAgentLMGenerator
|
| 3 |
+
from models.docx_generator import DocxGenerator
|
| 4 |
+
from pydantic import BaseModel
|
| 5 |
+
|
| 6 |
+
router = APIRouter()
|
| 7 |
+
|
| 8 |
+
class LMRequest(BaseModel):
|
| 9 |
+
name: str
|
| 10 |
+
job: str
|
| 11 |
+
job_description: str
|
| 12 |
+
email: str
|
| 13 |
+
phone: str
|
| 14 |
+
competences: list[str]
|
| 15 |
+
github_url: str = None
|
| 16 |
+
linkedin_url: str = None
|
| 17 |
+
|
| 18 |
+
class DocxRequest(BaseModel):
|
| 19 |
+
lm_content: str
|
| 20 |
+
|
| 21 |
+
@router.post("/generatelmcontent")
|
| 22 |
+
def generate_lm_content(request: LMRequest):
|
| 23 |
+
try:
|
| 24 |
+
generator = AiAgentLMGenerator()
|
| 25 |
+
user_data = request.dict()
|
| 26 |
+
content = generator.generate(user_data)
|
| 27 |
+
return {"lm_content": content}
|
| 28 |
+
except Exception as e:
|
| 29 |
+
raise HTTPException(status_code=500, detail=str(e))
|
| 30 |
+
|
| 31 |
+
@router.post("/generateDocx")
|
| 32 |
+
def generate_docx(request: DocxRequest):
|
| 33 |
+
try:
|
| 34 |
+
docx_gen = DocxGenerator()
|
| 35 |
+
docx_path = docx_gen.generate_docx(request.lm_content)
|
| 36 |
+
return {"docx_path": docx_path}
|
| 37 |
+
except Exception as e:
|
| 38 |
+
raise HTTPException(status_code=500, detail=str(e))
|
app/generated_lm.docx
ADDED
|
Binary file (37.8 kB). View file
|
|
|
app/main.py
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from fastapi import FastAPI
|
| 2 |
+
from controllers.lm_controller import router as lm_router
|
| 3 |
+
|
| 4 |
+
app = FastAPI()
|
| 5 |
+
|
| 6 |
+
app.include_router(lm_router)
|
app/models/__pycache__/docx_generator.cpython-310.pyc
ADDED
|
Binary file (992 Bytes). View file
|
|
|
app/models/__pycache__/lm_generator.cpython-310.pyc
ADDED
|
Binary file (1.28 kB). View file
|
|
|
app/models/__pycache__/pdf_generator.cpython-310.pyc
ADDED
|
Binary file (827 Bytes). View file
|
|
|
app/models/docx_generator.py
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from docx import Document
|
| 2 |
+
from docx.shared import Pt
|
| 3 |
+
from docx.enum.text import WD_ALIGN_PARAGRAPH
|
| 4 |
+
import os
|
| 5 |
+
|
| 6 |
+
class DocxGenerator:
|
| 7 |
+
def generate_docx(self, lm_content: str) -> str:
|
| 8 |
+
doc = Document()
|
| 9 |
+
|
| 10 |
+
# Ajouter le contenu de la lettre
|
| 11 |
+
lines = lm_content.split("\n")
|
| 12 |
+
for i, line in enumerate(lines):
|
| 13 |
+
p = doc.add_paragraph()
|
| 14 |
+
run = p.add_run(line)
|
| 15 |
+
if i == 0:
|
| 16 |
+
run.bold = True
|
| 17 |
+
|
| 18 |
+
output_path = "generated_lm.docx"
|
| 19 |
+
doc.save(output_path)
|
| 20 |
+
with open(output_path, "rb") as f:
|
| 21 |
+
blob = f.read()
|
| 22 |
+
return blob
|
app/models/lm_generator.py
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from langchain_google_genai import ChatGoogleGenerativeAI
|
| 2 |
+
|
| 3 |
+
class AiAgentLMGenerator:
|
| 4 |
+
def __init__(self):
|
| 5 |
+
self.llm = ChatGoogleGenerativeAI(
|
| 6 |
+
google_api_key="AIzaSyAmpT2kjqFcz7HZyiFeh6dBOu-zx_MRxIA",
|
| 7 |
+
model="models/gemini-2.5-flash"
|
| 8 |
+
)
|
| 9 |
+
|
| 10 |
+
def generate(self, user_data: dict) -> str:
|
| 11 |
+
name = user_data.get("name", "Candidat")
|
| 12 |
+
job = user_data.get("job", "poste")
|
| 13 |
+
prompt = (
|
| 14 |
+
f"Rédige une lettre de motivation professionnelle pour postuler au poste de {job}. "
|
| 15 |
+
f"Le candidat s'appelle {name}. La lettre doit être formelle et convaincante."
|
| 16 |
+
f"Veuillez saisir l'objet et le contenu de la lettre.\n"
|
| 17 |
+
f"Pas d'autre reponse que la lettre."
|
| 18 |
+
)
|
| 19 |
+
response = self.llm.invoke(prompt)
|
| 20 |
+
return response.content if hasattr(response, 'content') else str(response)
|
app/models/pdf_generator.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from fpdf import FPDF
|
| 2 |
+
import os
|
| 3 |
+
|
| 4 |
+
class PdfGenerator:
|
| 5 |
+
def generate_pdf(self, lm_content: str) -> str:
|
| 6 |
+
pdf = FPDF()
|
| 7 |
+
pdf.add_page()
|
| 8 |
+
pdf.set_font("Arial", size=12)
|
| 9 |
+
for line in lm_content.split("\n"):
|
| 10 |
+
pdf.cell(200, 10, txt=line, ln=1)
|
| 11 |
+
output_path = "generated_lm.pdf"
|
| 12 |
+
pdf.output(output_path)
|
| 13 |
+
return os.path.abspath(output_path)
|
requirements.txt
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
fastapi
|
| 2 |
+
uvicorn
|
| 3 |
+
python-docx
|
| 4 |
+
langchain
|
| 5 |
+
langchain-google-genai
|
| 6 |
+
pydantic
|