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}")