Sazzz02 commited on
Commit
a5495b8
·
verified ·
1 Parent(s): 83c1ffd

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +112 -0
app.py ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ import uuid
4
+ import chromadb
5
+ import pandas as pd
6
+ from fastapi import FastAPI, Request
7
+ from fastapi.responses import HTMLResponse
8
+ from fastapi.templating import Jinja2Templates
9
+ from langchain_groq import ChatGroq
10
+ from langchain_community.document_loaders import WebBaseLoader
11
+ from langchain_core.prompts import PromptTemplate
12
+ from langchain_core.output_parsers import JsonOutputParser
13
+ from langchain_core.output_parsers import StrOutputParser
14
+
15
+ # FastAPI app initialization
16
+ app = FastAPI()
17
+
18
+ # Get API key from environment variables
19
+ GROQ_API_KEY = os.environ.get("GROQ_API_KEY")
20
+
21
+ # Set up templates for rendering HTML
22
+ templates = Jinja2Templates(directory="templates")
23
+
24
+ # --- Initialize Vector Database on Startup ---
25
+ try:
26
+ df = pd.read_csv("my_portfolio.csv")
27
+ except FileNotFoundError:
28
+ print("❌ Error: my_portfolio.csv not found.")
29
+ sys.exit(1)
30
+
31
+ client = chromadb.PersistentClient('vectorstore')
32
+ collection = client.get_or_create_collection(name="portfolio")
33
+
34
+ if collection.count() != len(df):
35
+ if collection.count() > 0:
36
+ collection.delete(ids=collection.get()['ids'])
37
+
38
+ for _, row in df.iterrows():
39
+ collection.add(
40
+ documents=row["Techstack"],
41
+ metadatas={"links": row["Links"]},
42
+ ids=[str(uuid.uuid4())]
43
+ )
44
+ print("✅ Vector database populated with portfolio data.")
45
+ else:
46
+ print("✅ Vector database already exists.")
47
+
48
+ @app.get("/", response_class=HTMLResponse)
49
+ async def get_index(request: Request):
50
+ """Serves the main robot UI HTML page."""
51
+ return templates.TemplateResponse("robot_ui.html", {"request": request})
52
+
53
+ @app.post("/generate")
54
+ async def generate_content(request: Request):
55
+ form_data = await request.form()
56
+ job_url = form_data.get('job_url')
57
+
58
+ if not GROQ_API_KEY:
59
+ return "❌ Error: Groq API key is not set. Please add it to your Space secrets.", 500
60
+
61
+ if not job_url:
62
+ return "Please provide a job URL.", 400
63
+
64
+ # --- 1. Validate Groq API Key ---
65
+ try:
66
+ llm = ChatGroq(
67
+ temperature=0,
68
+ groq_api_key=GROQ_API_KEY,
69
+ model_name="llama3-70b-8192"
70
+ )
71
+ llm.invoke("Test LLM connection.")
72
+ except Exception as e:
73
+ return f"❌ Error: Invalid Groq API key or model unavailable. Details: {e}", 500
74
+
75
+ # --- 2. Scrape and Extract Job Information ---
76
+ try:
77
+ loader = WebBaseLoader(job_url)
78
+ page_data = loader.load().pop().page_content
79
+ except Exception as e:
80
+ return f"❌ Error scraping URL. Please check the URL. Error: {e}", 500
81
+
82
+ prompt_extract = PromptTemplate.from_template(
83
+ """
84
+ ### SCRAPED TEXT FROM WEBSITE: {page_data}
85
+ ### INSTRUCTION: Extract the job posting details and return them in JSON format with keys: `role`, `experience`, `skills` and `description`. Only return the valid JSON.
86
+ ### VALID JSON (NO PREAMBLE):"""
87
+ )
88
+ json_parser = JsonOutputParser()
89
+ chain_extract = prompt_extract | llm | json_parser
90
+ job = chain_extract.invoke(input={'page_data': page_data})
91
+
92
+ # --- 3. Find Relevant Portfolio Links ---
93
+ job_skills = job.get('skills', [])
94
+ relevant_links = collection.query(query_texts=job_skills, n_results=2).get('metadatas', [])
95
+
96
+ # --- 4. Generate Cold Email ---
97
+ prompt_email = PromptTemplate.from_template(
98
+ """### JOB DESCRIPTION: {job_description}
99
+ ### INSTRUCTION: You are Mohan, a business development executive at AtliQ. Write a cold email to the client, describing AtliQ's capabilities in fulfilling their needs. Also add the most relevant ones from the following links to showcase Atliq's portfolio: {link_list}
100
+ ### EMAIL (NO PREAMBLE):"""
101
+ )
102
+ chain_email = prompt_email | llm | StrOutputParser()
103
+ email_content = chain_email.invoke({
104
+ "job_description": str(job),
105
+ "link_list": relevant_links
106
+ })
107
+
108
+ return email_content
109
+
110
+ if __name__ == '__main__':
111
+ import uvicorn
112
+ uvicorn.run("app:app", host="0.0.0.0", port=int(os.environ.get('PORT', 7860)))