File size: 3,091 Bytes
4cf4462
 
 
 
61a5a78
 
 
65072ba
4cf4462
9fe2f9f
4cf4462
 
9fe2f9f
61a5a78
4cf4462
 
 
 
 
61a5a78
 
9fe2f9f
4cf4462
 
 
 
 
 
61a5a78
9fe2f9f
4cf4462
 
 
 
61a5a78
 
9fe2f9f
 
 
65072ba
61a5a78
4cf4462
65072ba
9b81f0f
 
 
 
9fe2f9f
 
9b81f0f
 
 
 
 
 
61a5a78
9b81f0f
61a5a78
 
 
 
 
 
65072ba
 
 
9b81f0f
61a5a78
4cf4462
61a5a78
 
 
9fe2f9f
61a5a78
 
 
9fe2f9f
61a5a78
4cf4462
 
 
9fe2f9f
 
 
 
 
 
 
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
from dotenv import load_dotenv
from openai import OpenAI
from pypdf import PdfReader
import gradio as gr
import datetime
from collections import defaultdict
import os
import re

# Load environment variables (like OPENAI_API_KEY)
load_dotenv(override=True)

# Track questions per IP
user_question_counter = defaultdict(lambda: {"date": None, "count": 0})


class Me:
    def __init__(self):
        self.openai = OpenAI()
        self.name = "Narendra"

        # Load LinkedIn profile
        reader = PdfReader("me/linkedin.pdf")
        self.linkedin = ""
        for page in reader.pages:
            text = page.extract_text()
            if text:
                self.linkedin += text

        # Load summary
        with open("me/summary.txt", "r", encoding="utf-8") as f:
            self.summary = f.read()

    def system_prompt(self):
        return (
            f"You are acting as {self.name}, an experienced Python technical interviewer. "
            f"Only answer questions related to Python programming. If the question is unrelated to Python, say so. "
            f"All answers must be under 100 tokens.\n\n"
            f"## About {self.name}:\n{self.summary}\n\n"
            f"## LinkedIn Profile:\n{self.linkedin}"
        )

    def is_python_related(self, text):
        python_keywords = [
            "python", "list", "dictionary", "dict", "tuple", "set", "loop",
            "for", "while", "comprehension", "function", "class", "exception",
            "PEP", "decorator", "lambda", "flask", "django", "pandas", "numpy",
            "jupyter", "interpreter", "import", "package", "virtualenv", "pytest",
            "recursion", "palindrome", "factorial", "generator", "iterator"
        ]
        text_lower = text.lower()
        return any(kw in text_lower for kw in python_keywords)

    def chat(self, message, history, request: gr.Request):
        ip = request.client.host or "unknown"
        today = datetime.date.today()
        record = user_question_counter[ip]

        if record["date"] != today:
            record["date"] = today
            record["count"] = 0

        if record["count"] >= 3:
            return "🚫 You've reached your daily limit of 3 Python questions. Please try again tomorrow."

        if not self.is_python_related(message):
            return "⚠️ I can only answer questions related to Python programming. Please ask something Python-specific."

        messages = [{"role": "system", "content": self.system_prompt()}] + history + [{"role": "user", "content": message}]
        response = self.openai.chat.completions.create(
            model="gpt-4o-mini",
            messages=messages,
            max_tokens=50
        )

        record["count"] += 1
        return response.choices[0].message.content


if __name__ == "__main__":
    me = Me()
    gr.ChatInterface(
        fn=me.chat,
        type="messages",
        title="πŸ‘‹ Narendra is your Python Interviewer. Ask your Python questions (max 3/day).",
        concurrency_limit=None,
        theme="default"
    ).launch(share=True, show_api=False)