Spaces:
Sleeping
Sleeping
File size: 4,105 Bytes
e3adae4 3345ea7 6a3bea4 e3adae4 3345ea7 3685afc 6e0d75c 3345ea7 e3adae4 6a3bea4 e3adae4 3345ea7 3d6ba25 6a3bea4 3345ea7 e3adae4 3345ea7 6e0d75c 1162eb0 3d6ba25 b5ef3ac 324fdf4 1162eb0 324fdf4 b5ef3ac 6e0d75c 69ce36d 6e0d75c 1802731 6e0d75c d76fac3 1802731 3345ea7 |
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 |
import base64
import re
import tempfile
from enum import Enum
import httpx
import pypandoc
from docx import Document
from docx.shared import Inches, Pt
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from src.utils import EmailClient
app = FastAPI()
pypandoc.download_pandoc()
TEMPLATE_PATH = "src/template.docx"
class Email(str, Enum):
sukhwinder = "sukhwinder@sifars.com"
munish = "munish@sifars.com"
jatin = "jatin@sifars.com"
class ProposalRequest(BaseModel):
project_name: str
project_overview: str
project_introduction: str
about_us: str
background_of_the_project: str
scope_of_work: str
technical_approach: str
deployment_and_integration: str
timeline: str
team_structure: str
platform: str
licensing_model: str
risk_analysis: str
past_projects: str
architecture_diagram: str
recipient_email: Email
async def generate_proposal(data: dict):
doc = Document(TEMPLATE_PATH)
email_to_name = {
"sukhwinder@sifars.com": "Sukhwinder Singh Sehgal",
"munish@sifars.com": "Munish Kumar",
"jatin@sifars.com": "Jatin Sethi",
}
data["name"] = email_to_name.get(data.get("recipient_email", ""), "").title()
mermaid_code = data.get("architecture_diagram", "")
architecture_diagram_path = None
mermaid_code = (
mermaid_code.replace("```mermaid\n", "").replace("```", "").replace("\n", ";")
)
if mermaid_code.strip():
graphbytes = mermaid_code.encode("utf8")
base64_bytes = base64.urlsafe_b64encode(graphbytes)
base64_str = base64_bytes.decode("ascii")
url = f"https://mermaid.ink/img/{base64_str}"
async with httpx.AsyncClient() as client:
response = await client.get(url)
response.raise_for_status()
with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as temp_file:
temp_file.write(response.content)
architecture_diagram_path = temp_file.name
for para in doc.paragraphs:
for key, value in data.items():
if f"{{{key}}}" in para.text:
if key == "architecture_diagram":
if architecture_diagram_path:
para.clear()
run = para.add_run()
run.add_picture(
architecture_diagram_path, width=Inches(6)
)
else:
clean_value = re.sub(r"[*#`]", "", value)
para.text = para.text.replace(f"{{{key}}}", clean_value)
for run in para.runs:
run.font.size = Pt(14)
run.font.name = "Arial"
with tempfile.NamedTemporaryFile(suffix=".docx") as temp_file:
doc.save(temp_file.name)
docx_file_path = temp_file.name
attachments = [docx_file_path]
recipient_email = data.get("recipient_email", "sukhwinder@sifars.com")
subject = f"Proposal for {data.get('project_name')}"
body = "Hello,\n\nPlease find the proposal attached.\n\nBest,\nProposal Bot"
async with EmailClient() as email_client:
await email_client.send_email(
subject=subject,
body=body,
to_emails=[recipient_email],
attachments=attachments,
)
return {"message": "Proposal sent successfully"}
return {"message": "Failed to send proposal"}
@app.get("/")
async def check_health():
return {"response": "Service is healthy!"}
@app.post("/proposals/")
async def generate_proposal_endpoint(request: ProposalRequest):
try:
proposal = await generate_proposal(data=request.model_dump())
return {"proposal": proposal}
except Exception as e:
raise HTTPException(status_code=500, detail=f"{e}")
|