kyle8581's picture
.
594e237
import gradio as gr
from llm_functions import generate_context_report
# 예제 데이터
example_companies = ["ν† μŠ€", "μ‚Όμ„±μ „μž", "CJμ œμΌμ œλ‹Ή", "ν•˜μ΄λΈŒ", "ν˜„λŒ€κ±΄μ„€", "μ‹ ν•œμ€ν–‰", "카카였", "넀이버", "LGμ „μž", "SKν•˜μ΄λ‹‰μŠ€"]
example_jobs = ["λ°±μ—”λ“œ 개발", "경영기획", "μ‹ν’ˆλ§ˆμΌ€νŒ…", "A&R", "HRM(μΈμ‚¬μš΄μ˜)", "ν•΄μ™Έμ˜μ—…", "데이터 뢄석", "μ˜¨λΌμΈλ§ˆμΌ€νŒ…", "기획", "개발"]
experience_levels = ["μ‹ μž…", "κ²½λ ₯", "인턴", "기타"]
def create_info_cards(report_data):
"""
리포트 데이터λ₯Ό μΉ΄λ“œ ν˜•νƒœλ‘œ ν‘œμ‹œν•˜λŠ” HTML 생성
"""
if not report_data or 'company_profile' not in report_data:
return "<div style='text-align: center; color: #6B7280; padding: 20px;'>리포트λ₯Ό μƒμ„±ν•΄μ£Όμ„Έμš”</div>"
# κΈ°μ—… ν”„λ‘œν•„ μΉ΄λ“œ
company_card = f"""
<div style="
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border-radius: 15px;
padding: 20px;
margin: 10px 0;
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
">
<h3 style="margin: 0 0 15px 0; font-size: 18px;">🏒 κΈ°μ—… ν”„λ‘œν•„</h3>
<div style="background: rgba(255,255,255,0.1); border-radius: 10px; padding: 15px;">
<strong>🎯 λΉ„μ „/λ―Έμ…˜:</strong><br>
{report_data['company_profile']['vision_mission']}<br><br>
<strong>πŸ’Ž 핡심 κ°€μΉ˜:</strong><br>
{' β€’ '.join(report_data['company_profile']['core_values'])}<br><br>
<strong>πŸ‘₯ μΈμž¬μƒ:</strong><br>
{report_data['company_profile']['talent_philosophy']}
</div>
</div>
"""
# 직무 뢄석 μΉ΄λ“œ
position_card = f"""
<div style="
background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%);
color: white;
border-radius: 15px;
padding: 20px;
margin: 10px 0;
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
">
<h3 style="margin: 0 0 15px 0; font-size: 18px;">πŸ’Ό 직무 뢄석</h3>
<div style="background: rgba(255,255,255,0.1); border-radius: 10px; padding: 15px;">
<strong>πŸ“‹ μ—­ν• :</strong><br>
{report_data['position_analysis']['role_summary']}<br><br>
<strong>πŸ”§ ν•˜λ“œ μŠ€ν‚¬:</strong><br>
{' β€’ '.join(report_data['position_analysis']['required_skills']['hard'])}<br><br>
<strong>πŸ’‘ μ†Œν”„νŠΈ μŠ€ν‚¬:</strong><br>
{' β€’ '.join(report_data['position_analysis']['required_skills']['soft'])}
</div>
</div>
"""
# μ‚°μ—… λ§₯락 μΉ΄λ“œ
industry_card = f"""
<div style="
background: linear-gradient(135deg, #fc4a1a 0%, #f7b733 100%);
color: white;
border-radius: 15px;
padding: 20px;
margin: 10px 0;
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
">
<h3 style="margin: 0 0 15px 0; font-size: 18px;">🌐 μ‚°μ—… λ§₯락</h3>
<div style="background: rgba(255,255,255,0.1); border-radius: 10px; padding: 15px;">
<strong>πŸ“ˆ μ£Όμš” νŠΈλ Œλ“œ:</strong><br>
{' β€’ '.join(report_data['industry_context']['trends'])}<br><br>
<strong>πŸ† μ£Όμš” κ²½μŸμ‚¬:</strong><br>
{' β€’ '.join(report_data['industry_context']['competitors'])}
</div>
</div>
"""
# ν‚€μ›Œλ“œ μΉ΄λ“œ
keywords_html = ""
if 'keywords' in report_data['position_analysis']:
keywords_html = "<div style='margin-top: 15px;'><strong>🏷️ 핡심 ν‚€μ›Œλ“œ:</strong><br>"
for keyword in report_data['position_analysis']['keywords']:
keywords_html += f"<span style='background: rgba(255,255,255,0.2); padding: 5px 10px; border-radius: 15px; margin: 2px; display: inline-block; font-size: 12px;'>{keyword}</span>"
keywords_html += "</div>"
return f"""
<div style="display: flex; flex-direction: column; gap: 10px;">
{company_card}
{position_card}
{industry_card}
<div style="
background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
color: #333;
border-radius: 15px;
padding: 20px;
margin: 10px 0;
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
">
<h3 style="margin: 0 0 15px 0; font-size: 18px;">🏷️ 핡심 ν‚€μ›Œλ“œ</h3>
<div style="display: flex; flex-wrap: wrap; gap: 8px;">
{''.join([f'<span style="background: #667eea; color: white; padding: 8px 15px; border-radius: 20px; font-size: 14px; font-weight: bold;">{keyword}</span>' for keyword in report_data['position_analysis']['keywords']])}
</div>
</div>
</div>
"""
def process_report_generation(job_title, company_name, experience_level):
"""
리포트 생성 κ²°κ³Όλ₯Ό μ²˜λ¦¬ν•˜κ³  UI에 ν‘œμ‹œν•  ν˜•νƒœλ‘œ λ³€ν™˜ν•˜λŠ” ν•¨μˆ˜
"""
try:
content, report_data = generate_context_report(job_title, company_name, experience_level)
info_cards = create_info_cards(report_data)
return content, info_cards
except Exception as e:
error_content = f"""## ❌ 였λ₯˜ λ°œμƒ
μ»¨ν…μŠ€νŠΈ 리포트 생성 쀑 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€.
**였λ₯˜ λ‚΄μš©:** {str(e)}
λ‹€μ‹œ μ‹œλ„ν•΄μ£Όμ„Έμš”.
"""
error_cards = create_info_cards({})
return error_content, error_cards
def create_interface():
"""
Gradio μΈν„°νŽ˜μ΄μŠ€ 생성
"""
with gr.Blocks(
title="πŸ“Š μžμ†Œμ„œ μ»¨ν…μŠ€νŠΈ 리포트",
theme=gr.themes.Soft(),
css="""
.main-header {
text-align: center;
padding: 20px;
background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
color: white;
border-radius: 10px;
margin-bottom: 20px;
}
.input-section {
background-color: #f8f9fa;
padding: 20px;
border-radius: 8px;
margin: 10px 0;
}
.example-section {
background-color: #f0f9ff;
padding: 15px;
border-radius: 8px;
margin: 10px 0;
}
"""
) as demo:
# 헀더
gr.HTML("""
<div class="main-header">
<h1>πŸ“Š μžμ†Œμ„œ μ»¨ν…μŠ€νŠΈ 리포트</h1>
<p>κΈ°μ—…κ³Ό 직무에 λŒ€ν•œ 쒅합적인 λΆ„μ„μœΌλ‘œ μ™„λ²½ν•œ μžκΈ°μ†Œκ°œμ„œλ₯Ό μ€€λΉ„ν•˜μ„Έμš”</p>
</div>
""")
# μ„€λͺ…
gr.Markdown("""
### πŸš€ **μ‚¬μš© 방법**
1. **직무**: μ§€μ›ν•˜κ³ μž ν•˜λŠ” 직무λ₯Ό μž…λ ₯ν•˜μ„Έμš”
2. **νšŒμ‚¬λͺ…**: 지원 νšŒμ‚¬λͺ…을 μž…λ ₯ν•˜μ„Έμš”
3. **κ²½λ ₯ μˆ˜μ€€**: μ‹ μž…/κ²½λ ₯/인턴/기타 쀑 μ„ νƒν•˜μ„Έμš”
4. **생성**: '리포트 생성' λ²„νŠΌμ„ ν΄λ¦­ν•˜μ—¬ κ²°κ³Όλ₯Ό ν™•μΈν•˜μ„Έμš”
✨ **νŠΉμ§•**: κΈ°μ—… ν”„λ‘œν•„, 직무 뢄석, μ‚°μ—… λ§₯락을 μ’…ν•©μ μœΌλ‘œ λΆ„μ„ν•˜μ—¬ μžμ†Œμ„œ μž‘μ„±μ— ν•„μš”ν•œ 핡심 정보λ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€.
""")
with gr.Row():
with gr.Column(scale=2):
# μž…λ ₯ μ„Ήμ…˜
gr.HTML('<div class="input-section">')
gr.Markdown("### πŸ“ **κΈ°λ³Έ 정보 μž…λ ₯**")
with gr.Row():
job_input = gr.Textbox(
label="πŸ’Ό 직무",
placeholder="예: λ°±μ—”λ“œ 개발, 경영기획, λ§ˆμΌ€νŒ… λ“±",
value="",
scale=1
)
company_input = gr.Textbox(
label="🏒 νšŒμ‚¬λͺ…",
placeholder="예: ν† μŠ€, μ‚Όμ„±μ „μž, 카카였 λ“±",
value="",
scale=1
)
experience_input = gr.Dropdown(
label="πŸ“ˆ κ²½λ ₯ μˆ˜μ€€",
choices=experience_levels,
value="μ‹ μž…",
interactive=True
)
generate_btn = gr.Button(
"πŸ“Š 리포트 생성",
variant="primary",
size="lg"
)
gr.HTML('</div>')
with gr.Column(scale=1):
# 예제 및 κ°€μ΄λ“œ
gr.HTML('<div class="example-section">')
gr.Markdown("### πŸ’‘ **예제 νšŒμ‚¬**")
company_rows = [example_companies[i:i+2] for i in range(0, len(example_companies), 2)]
for row in company_rows:
with gr.Row():
for company in row:
example_btn = gr.Button(
company,
size="sm",
variant="secondary",
scale=1
)
example_btn.click(
fn=lambda x=company: x,
outputs=company_input
)
gr.Markdown("### πŸ’Ό **예제 직무**")
job_rows = [example_jobs[i:i+2] for i in range(0, len(example_jobs), 2)]
for row in job_rows:
with gr.Row():
for job in row:
job_btn = gr.Button(
job,
size="sm",
variant="secondary",
scale=1
)
job_btn.click(
fn=lambda x=job: x,
outputs=job_input
)
gr.Markdown("### πŸ“ˆ **κ²½λ ₯ μˆ˜μ€€**")
with gr.Row():
for level in experience_levels:
level_btn = gr.Button(
level,
size="sm",
variant="secondary",
scale=1
)
level_btn.click(
fn=lambda x=level: x,
outputs=experience_input
)
gr.HTML('</div>')
# κ²°κ³Ό 좜λ ₯ μ„Ήμ…˜
with gr.Row():
with gr.Column(scale=2):
gr.Markdown("### πŸ“‹ **상세 리포트**")
result_output = gr.Markdown(
value="직무, νšŒμ‚¬λͺ…, κ²½λ ₯ μˆ˜μ€€μ„ μž…λ ₯ν•˜κ³  '리포트 생성' λ²„νŠΌμ„ ν΄λ¦­ν•˜μ„Έμš”.",
elem_classes=["result-output"]
)
with gr.Column(scale=1):
gr.Markdown("### πŸ“Š **핡심 정보**")
info_cards = gr.HTML(
value="<div style='text-align: center; color: #6B7280; padding: 20px;'>리포트λ₯Ό μƒμ„±ν•΄μ£Όμ„Έμš”</div>",
elem_classes=["info-cards"]
)
# 생성 λ²„νŠΌ 클릭 이벀트
generate_btn.click(
fn=process_report_generation,
inputs=[job_input, company_input, experience_input],
outputs=[result_output, info_cards],
api_name="generate_context_report"
)
# ν‘Έν„°
gr.Markdown("""
---
**πŸ“Š 리포트 ꡬ성**:
- **🏒 κΈ°μ—… ν”„λ‘œν•„**: λΉ„μ „/λ―Έμ…˜, ν•΅μ‹¬κ°€μΉ˜, μΈμž¬μƒ, μ΅œκ·Όλ™ν–₯, μ£Όμš”μ œν’ˆ/μ„œλΉ„μŠ€
- **πŸ’Ό 직무 뢄석**: μ—­ν• μš”μ•½, ν•„μš”μŠ€ν‚¬(ν•˜λ“œ/μ†Œν”„νŠΈ), ν•΅μ‹¬ν‚€μ›Œλ“œ
- **🌐 μ‚°μ—… λ§₯락**: μ£Όμš”νŠΈλ Œλ“œ, κ²½μŸμ‚¬ 정보
πŸ’‘ **ν™œμš© 팁**: μƒμ„±λœ ν‚€μ›Œλ“œμ™€ 정보λ₯Ό μžμ†Œμ„œ μž‘μ„± μ‹œ 적극 ν™œμš©ν•˜μ—¬ λ§žμΆ€ν˜• μžκΈ°μ†Œκ°œμ„œλ₯Ό μž‘μ„±ν•˜μ„Έμš”.
πŸ€– **Powered by**: OpenAI GPT-4o
""")
return demo
if __name__ == "__main__":
# Gradio μ•± μ‹€ν–‰
demo = create_interface()
demo.launch(
server_name="0.0.0.0",
# server_port=7862,
share=True,
show_error=True
)