-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgradio_app.py
179 lines (143 loc) · 6.73 KB
/
gradio_app.py
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
#import all dependencies
import os
from pathlib import Path
import litellm
from crewai import Agent, Task, Crew, Process
from crewai_tools import SerperDevTool
import pdfplumber
from docx import Document
import gradio as gr
import html
# Set up API keys
litellm.api_key = "YOUR_LLM_API_KEY"
os.environ['SERPER_API_KEY'] = "YOUR_SERPER_API_KEY"
# Define the LLM
llm = "gemini/gemini-1.5-flash-exp-0827" # I have used google gemini-1.5-flash-exp-0827, you can replace it with your own llm
# Initialize the tool for internet searching capabilities
tool = SerperDevTool()
# Create the CV Analysis Agent
cv_analysis_agent = Agent(
role="CV Analyzer",
goal='Analyze the given CV and extract key skills and experiences and make improvements if needed for portfolio creation.',
verbose=True,
memory=True,
backstory=(
"You are an expert CV Analyzer with a keen eye for detail. Your role is to meticulously examine the provided CV, "
"identifying and extracting key skills, experiences, accomplishments, and areas for improvement. "
"Your analysis should highlight strengths and suggest enhancements that would make the portfolio more competitive."
),
tools=[tool],
llm=llm,
allow_delegation=True
)
# Create the Portfolio Generation Agent
portfolio_generation_agent = Agent(
role='Portfolio Generator',
goal='Generate a professional HTML/CSS/JS responsive landing portfolio webpage based on {cv} analysis.',
verbose=True,
memory=True,
backstory=(
"As a Responsive Portfolio Generator, your expertise lies in creating visually appealing and user-friendly web pages. "
"Based on the CV analysis, you will generate a professional HTML/CSS/JS portfolio. "
"Ensure the design reflects the individual's strengths and experiences while incorporating effective functionality. "
"Consider responsiveness, color schemes, and navigation for an optimal user experience."
),
tools=[tool],
llm=llm,
allow_delegation=False
)
# Research task for CV analysis
cv_analysis_task = Task(
description=(
"Analyze the provided {cv} in detail. Identify and summarize key skills, experiences, and notable accomplishments. "
"Highlight educational background and suggest potential enhancements to improve the overall presentation and competitiveness of the CV."
),
expected_output='A detailed summary of skills, experiences, accomplishments, and improvement suggestions formatted for a portfolio.',
tools=[tool],
agent=cv_analysis_agent,
)
# Writing task for portfolio generation with enhanced UI requirements
portfolio_task = Task(
description=(
"Generate a responsive HTML/CSS portfolio webpage based on the given CV analysis. "
"Include a navbar with the individual's name, and sections for skills, projects, experiences, certifications, and contact information. "
"Ensure the layout is clean and visually appealing with a light/dark theme toggle option. "
"Embed CSS/JS directly into the HTML for easy deployment, and optimize for both desktop and mobile viewing."
),
expected_output='A complete and responsive HTML document ready for deployment, showcasing the individual’s strengths.',
tools=[tool],
agent=portfolio_generation_agent,
async_execution=True,
)
# Function to read CV from PDF or DOCX file
def read_cv_file(file_path):
ext = os.path.splitext(file_path)[1].lower()
cv_content = ""
if ext == '.pdf':
with pdfplumber.open(file_path) as pdf:
for page in pdf.pages:
cv_content += page.extract_text()
elif ext == '.docx':
doc = Document(file_path)
for para in doc.paragraphs:
cv_content += para.text + "\n"
else:
raise ValueError("Unsupported file format. Please use .pdf or .docx.")
return cv_content.strip()
# Create a Crew for processing
crew = Crew(
agents=[cv_analysis_agent, portfolio_generation_agent],
tasks=[cv_analysis_task, portfolio_task],
process=Process.sequential,
)
# Function to process CV and generate portfolio
def process_cv(file):
try:
cv_file_content = read_cv_file(file.name)
result = crew.kickoff(inputs={'cv': cv_file_content})
# Print the entire result object to explore its contents (for debugging)
print(result)
# Convert the result to string
html_output = str(result)
# Use replace to remove '''html''' and ''' from the output
clean_html_output = html_output.replace("```html", '').replace("```", '').strip()
return clean_html_output # Return the cleaned HTML
except Exception as e:
return f"Error: {e}"
def save_html_to_file(html_content):
output_file_path = "Portfolio_generated_by_FiftyBit.html"
with open(output_file_path, "w") as f:
f.write(html_content)
return output_file_path
def upload_file(filepath):
name = Path(filepath).name
html_content = process_cv(filepath) # Get HTML content from the CV
# Clean the HTML content and escape it for proper iframe embedding
clean_html_output = html_content.replace("```html", '').replace("```", '').strip()
escaped_html_content = html.escape(clean_html_output) # Escape HTML content
# Debugging print to check the escaped HTML content
#print("Escaped HTML content:", escaped_html_content)
# Save the cleaned HTML content to a file (if you still want this feature)
file_path = save_html_to_file(clean_html_output)
# Return a full HTML string with embedded iframe for preview
iframe_html = f"""
<iframe srcdoc="{escaped_html_content}" style="width:100%; height:1000px; border:none; overflow:auto;"></iframe>
"""
return iframe_html, gr.UploadButton(visible=False), gr.DownloadButton(label=f"Download Code", value=file_path, visible=True)
def download_file():
return [gr.UploadButton(label=f"Regenerate", visible=True), gr.DownloadButton(visible=False)]
# Gradio App
with gr.Blocks() as demo:
gr.Markdown("<center><h1> CV-2-Portfolio Site Generator</center></h1>")
gr.Markdown("<center><h2>Upload your CV in PDF or DOCX format for analysis and portfolio webpage generation.</center></h2>")
u = gr.UploadButton("Upload CV (.pdf or .docx)", file_count="single")
d = gr.DownloadButton("Download Portfolio", visible=False)
# Use gr.HTML with larger iframe size to display the full preview
output_preview = gr.HTML(
value="<div style='width:100%; height:1000px; border:1px solid #ccc; text-align:center;'>Upload a file to preview the generated portfolio</div>"
)
# Connect the upload button to the upload_file function and update the output preview
u.upload(upload_file, u, [output_preview, u, d])
# Handle download button click
d.click(download_file, None, [u, d])
demo.launch(debug=True)