-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat: 이력서 수정 #37
Merged
Merged
Feat: 이력서 수정 #37
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
d43a346
feat: 이력서 수정 키값 찾을 경우
Oh-JunTaek 0749b74
feat: 이력서 수정 gpt
Oh-JunTaek fa825f8
feat: 이력서 수정 프롬프트
Oh-JunTaek c3927d3
feat: 이력서 수정 dto
Oh-JunTaek a8eea4a
feat: 이력서 수정 프롬프트 str setting
Oh-JunTaek 61d30f2
perf:사용하지 않느 기능 비활성화
Oh-JunTaek 434c65c
feat: 이력서 수정 api
Oh-JunTaek 462f049
docs: 깃 이그노어 데이터 생성 결과값 추가
Oh-JunTaek File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
from pydantic import BaseModel | ||
from typing import List, Optional | ||
|
||
class WorkExperience(BaseModel): | ||
companyName: str | ||
departmentName: str | ||
role: str | ||
workType: str # FULL_TIME, PART_TIME 등 | ||
employmentStatus: str # EMPLOYMENT, UNEMPLOYMENT 등 | ||
startedAt: str # YYYY-MM 형식 | ||
endedAt: Optional[str] # YYYY-MM 형식 또는 빈 값 | ||
|
||
class ProjectResponse(BaseModel): | ||
projectName: str | ||
projectStartedAt: str # YYYY.MM 형식 | ||
projectEndedAt: str # YYYY.MM 형식 | ||
skillSet: str | ||
projectDescription: str | ||
repoLink: str | ||
class Link(BaseModel): | ||
linkTitle: str | ||
linkUrl: str | ||
|
||
class Education(BaseModel): | ||
schoolType: str # UNIVERSITY_BACHELOR 등 | ||
schoolName: str | ||
major: str | ||
graduationStatus: str # ATTENDING, GRADUATED 등 | ||
startedAt: str # YYYY-MM 형식 | ||
endedAt: Optional[str] # YYYY-MM 형식 또는 빈 값 | ||
|
||
class Certificate(BaseModel): | ||
certificateName: str | ||
certificateGrade: str | ||
certificatedAt: str # YYYY-MM 형식 | ||
certificateOrganization: str | ||
|
||
class ResumeResponseDto(BaseModel): | ||
resumeId: str | ||
memberId: int | ||
memberName: str | ||
avatarUrl: str | ||
email: str | ||
position: str | ||
techStack: List[str] | ||
aboutMe: str | ||
tags: Optional[List[str]] # null 가능 | ||
workExperiences: List[WorkExperience] | ||
projects: List[ProjectResponse] | ||
links: Optional[List[Link]] # null 가능 | ||
educations: List[Education] | ||
certificates: List[Certificate] | ||
|
||
class UpdateRequestDto(BaseModel): | ||
selectedText: str | ||
requirement: str | ||
resumeInfo: ResumeResponseDto |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,9 @@ | ||
from openai import OpenAI | ||
from app.config.settings import settings | ||
from app.dto.resume_dto import GptProject | ||
from app.dto.resume_modify_dto import ResumeResponseDto | ||
from app.services.github_service import get_github_profile_and_repos | ||
# from app.services.json_service import find_key_by_value | ||
import tiktoken | ||
import json | ||
import os | ||
|
@@ -182,7 +184,7 @@ def simplify_project_summary_byJson(summary_text, openai_api_key, requirements, | |
return GptProject(projectName="", skillSet="", projectDescription="") | ||
|
||
# 어바웃미 생성 | ||
def generate_aboutme(openai_api_key, prompt=settings.aboutme_prompt) -> str: | ||
def generate_aboutme(openai_api_key, prompt=settings.aboutme_prompt): | ||
try: | ||
# 요약 요청 | ||
print("Generating about me...") | ||
|
@@ -248,4 +250,73 @@ def generate_aboutme(openai_api_key, prompt=settings.aboutme_prompt) -> str: | |
|
||
except Exception as e: | ||
print(f"Error generating About Me: {e}") | ||
return "" | ||
return "" | ||
|
||
def resume_update(openai_api_key, requirements, selected_text, context_data, prompt=settings.resume_update_prompt) : | ||
try: | ||
# 선택된 텍스트가 없을 때 처리 | ||
if not selected_text or not selected_text.strip(): | ||
print("Error: Selected text is empty or missing.") | ||
return context_data # 오류 발생시 기존 데이터 반환 | ||
|
||
# 수정 요구사항이 없을 때 처리 | ||
if not requirements or not requirements.strip(): | ||
print("Error: User request (requirements) is empty or missing.") | ||
return context_data # 오류 발생시 기존 데이터 반환 | ||
|
||
# # 선택된 텍스트의 키 경로 탐색 | ||
# key_path = find_key_by_value(context_data, selected_text) | ||
|
||
# if not key_path: | ||
# print("Error: Selected text does not match any value in the JSON data.") | ||
# return context_data # 오류 발생시 기존 데이터 반환 | ||
|
||
# 수정 요청 | ||
print("이력서 수정") | ||
|
||
# OpenAI API 호출 | ||
client = OpenAI(api_key=openai_api_key) | ||
response = client.beta.chat.completions.parse( | ||
model=settings.gpt_model, | ||
messages=[ | ||
{ | ||
"role": "system", | ||
"content": ( | ||
"You are a friendly and professional resume modification expert." | ||
"Your task is to update only the specified sections of the resume based on the user's request while leaving all other parts unchanged." | ||
"Ensure the modifications are concise, professional, and aligned with the tone of the original resume." | ||
) | ||
Comment on lines
+283
to
+288
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 프롬프트 작성한건 잘 작성하신거같아요 |
||
}, | ||
{ | ||
"role": "user", | ||
"content": ( | ||
"Context Data:\n" | ||
f"{json.dumps(context_data, indent=4)}\n\n" | ||
"Selected Text:\n" | ||
f"{selected_text}\n\n" | ||
# "Key Path:\n" | ||
# f"{key_path}\n\n" | ||
"User Request:\n" | ||
f"{requirements}\n\n" | ||
"Please update the selected text based on the instructions provided." | ||
) | ||
}, | ||
{ | ||
"role": "assistant", | ||
"content": f"Sample summary format: {prompt}." | ||
} | ||
], | ||
max_tokens=settings.max_output_tokens, | ||
response_format=ResumeResponseDto | ||
) | ||
|
||
# GPT 응답 파싱 | ||
response_text = response.choices[0].message.parsed | ||
|
||
# ResumeResponseDto 객체로 반환 | ||
return response_text | ||
|
||
|
||
except Exception as e: | ||
print(f"Error modifying resume with GPT: {e}") | ||
return context_data # 오류 발생 시 기존 데이터 반환 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import json | ||
|
||
def find_key_by_value(json_data, target_value): | ||
""" | ||
JSON 데이터에서 target_value를 가진 키를 재귀적으로 검색합니다. | ||
""" | ||
for key, value in json_data.items(): # JSON 데이터의 각 키-값 쌍을 순회 | ||
if isinstance(value, dict): # 값이 중첩된 딕셔너리인 경우 | ||
result = find_key_by_value(value, target_value) # 재귀적으로 해당 딕셔너리 내부 탐색 | ||
if result: | ||
return f"{key}.{result}" # 부모 키와 결과 키를 합쳐 반환 | ||
elif isinstance(value, list): # 값이 리스트인 경우 | ||
for i, item in enumerate(value): # 리스트의 각 항목을 순회 | ||
if isinstance(item, dict): # 리스트 항목이 딕셔너리인 경우 | ||
result = find_key_by_value(item, target_value) # 딕셔너리를 재귀적으로 탐색 | ||
if result: | ||
return f"{key}[{i}].{result}" # 부모 키와 인덱스를 포함한 경로 반환 | ||
elif item == target_value: # 리스트 항목이 target_value와 동일한 경우 | ||
return f"{key}[{i}]" # 리스트의 인덱스를 포함한 경로 반환 | ||
elif value == target_value: # 값이 target_value와 동일한 경우 | ||
return key # 키 반환 | ||
return None # target_value를 찾지 못한 경우 None 반환 | ||
|
||
|
||
def update_json_by_key(json_data, key_path, new_value): | ||
""" | ||
JSON 데이터에서 지정된 key_path에 있는 값을 new_value로 업데이트합니다. | ||
""" | ||
keys = key_path.split('.') # key_path를 '.' 기준으로 나눠 리스트로 변환 | ||
current = json_data # JSON 데이터를 탐색하기 위해 초기화 | ||
|
||
for key in keys[:-1]: # 마지막 키를 제외한 경로를 순회 | ||
if '[' in key and ']' in key: # 키가 리스트 인덱스를 포함하는 경우 | ||
list_key, index = key[:-1].split('[') # 리스트 키와 인덱스를 분리 | ||
current = current[list_key][int(index)] # 리스트 인덱스를 사용해 값 탐색 | ||
else: # 리스트가 아닌 일반 키인 경우 | ||
current = current[key] # 키를 사용해 값 탐색 | ||
|
||
final_key = keys[-1] # 경로의 마지막 키 | ||
if '[' in final_key and ']' in final_key: # 마지막 키가 리스트 인덱스를 포함하는 경우 | ||
list_key, index = final_key[:-1].split('[') # 리스트 키와 인덱스를 분리 | ||
current[list_key][int(index)] = new_value # 새로운 값으로 업데이트 | ||
else: # 마지막 키가 리스트 인덱스가 아닌 경우 | ||
current[final_key] = new_value # 새로운 값으로 업데이트 |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dto도 멋진데요? ㅎㅎ 리턴하고 요청받는것만 약속한대로 유지하고, 나머지는 형이 편한대로 잘짜시면되요 보기에는 문제가 없어보입니다. :) 굿