File size: 4,328 Bytes
d8d4fef
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import ast
import json
import logging
import re
from pathlib import Path
from typing import Dict

import requests
from revChatGPT.Official import Chatbot

from src.chatbot.prompts import get_prompt, data_format

logging.basicConfig(filename='chatgpt.log', level=logging.INFO, format='%(asctime)s %(message)s',
                    datefmt='%m/%d/%Y %I:%M:%S %p')

openai_key_info = 'https://platform.openai.com/account/api-keys'


class Chatgpt:
    def __init__(self, api_key):
        self.chatbot = Chatbot(api_key)
        logging.info("API key loaded successfully")

    @staticmethod
    def validate_api(api_key):
        if api_key and api_key.startswith("sk-") and len(api_key) > 50:
            response = requests.get("https://api.openai.com/v1/engines", headers={"Authorization": f"Bearer {api_key}"})
            return response.status_code == 200
        return False

    @staticmethod
    def load_api_key(config_path):
        """
        Load api key from config.json

        Returns:
            Str: session token
        """
        config_file = Path(config_path)
        if not config_file.is_file():
            raise FileNotFoundError(f"config.json not found at {config_file.resolve()}")

        with open(config_file, 'r') as j_file:
            session_token = json.load(j_file)
        return session_token['api_key']

    def improve_resume(self, parsed_resume: str) -> Dict:
        logging.info("Improving parsed resume")
        chatgpt_input = get_prompt(parsed_resume, user_request='', output_type='all')
        response = self._ask(chatgpt_input)
        new_resume_data = self.parse_json_from_string(response)
        logging.info("Resume improved successfully")
        return new_resume_data

    def improve_section(self, section_text, user_request=''):
        logging.info("Improving section")
        chatgpt_input = get_prompt(section_text, user_request=user_request, output_type='section')
        response = self._ask(chatgpt_input)
        new_section_text = self.clean_section_response(response)
        logging.info("Section improved successfully")
        return new_section_text

    def _ask(self, chatgpt_input):
        logging.info("Asking chatbot for response")
        try:
            response = self.chatbot.ask(chatgpt_input)
            answer = response['choices'][0]['text']
            logging.info("Received response from chatbot")
            logging.info(f"Response: {answer}")
        except Exception:
            answer = ""
        return answer

    def parse_json_from_string(self, json_string):

        try:
            return ast.literal_eval(json_string)
        except Exception:
            logging.error("Error in parsing JSON string")

        json_string = re.sub('\s+', ' ', json_string)
        json_string = re.sub('"', "'", json_string)
        json_string = re.sub(r"(\w)'(\w)", r"\1\'\2", json_string)

        clean_dict = dict()
        for key, value in data_format.items():
            pattern = ''
            if isinstance(value, str):
                pattern = f"'{key}':" + "\s*'(.*?)'"
            elif isinstance(value, list):
                pattern = f"'{key}':\s*(\[[^\[\]]*?\])"
            elif isinstance(value, dict):
                pattern = f"'{key}':" + "\s*(\{[^{}]*?\})"

            extracted_value = self.extract_value(pattern, json_string)

            if extracted_value:
                try:
                    extracted_value = ast.literal_eval(extracted_value)
                except Exception:
                    pass

            if not isinstance(extracted_value, type(value)):
                extracted_value = data_format[key]
            clean_dict[key] = extracted_value

        return clean_dict

    def extract_value(self, pattern, string):
        match = re.search(pattern, string)

        if match:
            return match.group(1)
        else:
            return ''

    def clean_section_response(self, input_string):
        try:
            input_string = re.sub('^\W*"', "", input_string)
            input_string = re.sub('"\W*$', "", input_string)
        except ValueError:
            pass
        input_string = self.remove_prefix(input_string)
        return input_string

    @staticmethod
    def remove_prefix(input_string):
        return re.sub(r'\w+:\n', '', input_string)