Spaces:
Running
Running
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,144 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
from google.colab import userdata
|
3 |
+
import litellm
|
4 |
+
from crewai import Agent, Task, Crew, Process
|
5 |
+
from crewai_tools import SerperDevTool
|
6 |
+
import pdfplumber
|
7 |
+
from docx import Document
|
8 |
+
import gradio as gr
|
9 |
+
|
10 |
+
# Set up API keys
|
11 |
+
litellm.api_key = userdata.get("GOOGLE_API_KEY")
|
12 |
+
os.environ['SERPER_API_KEY'] = userdata.get('SERPER_API_KEY')
|
13 |
+
|
14 |
+
# Define the LLM
|
15 |
+
llm = "gemini/gemini-1.5-flash-exp-0827" # Your LLM model
|
16 |
+
|
17 |
+
# Initialize the tool for internet searching capabilities
|
18 |
+
tool = SerperDevTool()
|
19 |
+
|
20 |
+
# Create the CV Analysis Agent
|
21 |
+
cv_analysis_agent = Agent(
|
22 |
+
role="CV Analyzer",
|
23 |
+
goal='Analyze the given CV and extract key skills and experiences and make improvements if needed for portfolio creation.',
|
24 |
+
verbose=True,
|
25 |
+
memory=True,
|
26 |
+
backstory=(
|
27 |
+
"As a CV Analyzer, you are skilled in identifying key information "
|
28 |
+
"from resumes to aid in building effective portfolios."
|
29 |
+
"You can add relevant skills and job responsibilities evaluating the whole cv."
|
30 |
+
),
|
31 |
+
tools=[tool],
|
32 |
+
llm=llm,
|
33 |
+
allow_delegation=True
|
34 |
+
)
|
35 |
+
|
36 |
+
# Create the Portfolio Generation Agent
|
37 |
+
portfolio_generation_agent = Agent(
|
38 |
+
role='Portfolio Generator',
|
39 |
+
goal='Generate a beautiful static HTML/CSS/JS landing portfolio webpage based on CV analysis.',
|
40 |
+
verbose=True,
|
41 |
+
memory=True,
|
42 |
+
backstory=(
|
43 |
+
"As a Portfolio Generator, you craft engaging web pages with effective functionalities and color combinations "
|
44 |
+
"to showcase individual talents and experiences with the best user experience."
|
45 |
+
),
|
46 |
+
tools=[tool],
|
47 |
+
llm=llm,
|
48 |
+
allow_delegation=False
|
49 |
+
)
|
50 |
+
|
51 |
+
# Research task for CV analysis
|
52 |
+
cv_analysis_task = Task(
|
53 |
+
description=(
|
54 |
+
"Analyze the provided {cv} and identify key skills, experiences, "
|
55 |
+
"and accomplishments. Highlight notable projects and educational background."
|
56 |
+
),
|
57 |
+
expected_output='A summary of skills, experiences, and projects formatted for a portfolio.',
|
58 |
+
tools=[tool],
|
59 |
+
agent=cv_analysis_agent,
|
60 |
+
)
|
61 |
+
|
62 |
+
# Writing task for portfolio generation with enhanced UI requirements
|
63 |
+
portfolio_task = Task(
|
64 |
+
description=(
|
65 |
+
"Generate a static HTML/CSS/JS landing portfolio with a name as header in top, navbar for different sections, beautiful and responsive design. "
|
66 |
+
"Ensure that the layout is clean, with sections for skills, projects, experiences, certifications, publications, and contact details if present in the CV. "
|
67 |
+
"Include a footer that does not overlap with the content. "
|
68 |
+
"Use a modern color palette and incorporate CSS frameworks if necessary, "
|
69 |
+
"but provide everything embedded in the HTML file. "
|
70 |
+
"The output should be a complete HTML document starting from <html> to </html>, ready to deploy."
|
71 |
+
),
|
72 |
+
expected_output='A complete HTML/CSS/JS code content only for a portfolio website in a single .html file',
|
73 |
+
tools=[tool],
|
74 |
+
agent=portfolio_generation_agent,
|
75 |
+
async_execution=False,
|
76 |
+
output_file='portfolio.html' # Output as HTML file
|
77 |
+
)
|
78 |
+
|
79 |
+
# Function to read CV from PDF or DOCX file
|
80 |
+
def read_cv_file(file_path):
|
81 |
+
ext = os.path.splitext(file_path)[1].lower()
|
82 |
+
cv_content = ""
|
83 |
+
|
84 |
+
if ext == '.pdf':
|
85 |
+
with pdfplumber.open(file_path) as pdf:
|
86 |
+
for page in pdf.pages:
|
87 |
+
cv_content += page.extract_text()
|
88 |
+
elif ext == '.docx':
|
89 |
+
doc = Document(file_path)
|
90 |
+
for para in doc.paragraphs:
|
91 |
+
cv_content += para.text + "\n"
|
92 |
+
else:
|
93 |
+
raise ValueError("Unsupported file format. Please use .pdf or .docx.")
|
94 |
+
|
95 |
+
return cv_content.strip()
|
96 |
+
|
97 |
+
# Create a Crew for processing
|
98 |
+
crew = Crew(
|
99 |
+
agents=[cv_analysis_agent, portfolio_generation_agent],
|
100 |
+
tasks=[cv_analysis_task, portfolio_task],
|
101 |
+
process=Process.sequential,
|
102 |
+
)
|
103 |
+
|
104 |
+
# Function to process CV and generate portfolio
|
105 |
+
import re
|
106 |
+
|
107 |
+
# Function to process CV and generate portfolio
|
108 |
+
def process_cv(file):
|
109 |
+
try:
|
110 |
+
cv_file_content = read_cv_file(file.name)
|
111 |
+
result = crew.kickoff(inputs={'cv': cv_file_content})
|
112 |
+
|
113 |
+
# Print the entire result object to explore its contents (for debugging)
|
114 |
+
print(result)
|
115 |
+
|
116 |
+
# Convert the result to string
|
117 |
+
html_output = str(result)
|
118 |
+
|
119 |
+
# Use replace to remove '''html''' and ''' from the output
|
120 |
+
clean_html_output = html_output.replace("'''html'''", '').replace("'''", '').strip()
|
121 |
+
|
122 |
+
return clean_html_output # Return the cleaned HTML
|
123 |
+
except Exception as e:
|
124 |
+
return f"Error: {e}"
|
125 |
+
|
126 |
+
# Gradio UI using Blocks
|
127 |
+
with gr.Blocks() as iface:
|
128 |
+
gr.Markdown("# CV-2-HTML AI Enhanced Portfolio Website Generation")
|
129 |
+
gr.Markdown("Upload your CV in PDF or DOCX format to analyze its content and generate a portfolio.")
|
130 |
+
|
131 |
+
# File input for uploading CV
|
132 |
+
cv_input = gr.File(label="Upload your CV (.pdf or .docx)")
|
133 |
+
|
134 |
+
# Output textbox for generated HTML
|
135 |
+
output_textbox = gr.Textbox(label="Generated HTML", lines=20, placeholder="Your generated HTML will appear here...", interactive=True)
|
136 |
+
|
137 |
+
# Process button
|
138 |
+
process_button = gr.Button("Generate Portfolio")
|
139 |
+
|
140 |
+
# Define the button actions
|
141 |
+
process_button.click(fn=process_cv, inputs=cv_input, outputs=output_textbox)
|
142 |
+
|
143 |
+
# Launch the Gradio interface
|
144 |
+
iface.launch()
|