Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Code Crafters/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
chat_history.db
/database/__pycache__
9 changes: 9 additions & 0 deletions Code Crafters/.streamlit/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[theme]
primaryColor="#F63366"
backgroundColor="#444654"
secondaryBackgroundColor="#202123"
textColor="#fff"
font="sans serif"

[server]
enableStaticServing = true
7 changes: 7 additions & 0 deletions Code Crafters/Backend/Models/input_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from pydantic import BaseModel

class InputData(BaseModel):
"""
A class used to represent the user prompt
"""
userPrompt: str
5 changes: 5 additions & 0 deletions Code Crafters/Backend/Models/output_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# api/models/output_data.py
from pydantic import BaseModel

class OutputData(BaseModel):
anonymized_text: str
101 changes: 101 additions & 0 deletions Code Crafters/Backend/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
from fastapi import FastAPI
from pydantic import BaseModel
from llama_cpp import Llama
import openai
import os

app = FastAPI()


class UserPrompt(BaseModel):
"""
A class used to represent the user prompt
"""


from fastapi.middleware.cors import CORSMiddleware
from fastapi import HTTPException, APIRouter

# Load vicuna-13b model
print("Loading model...")
llm = Llama(model_path="./models/ggml-vicuna-13b-4bit-rev1.bin")
print("Model loaded")

# OpenAI API key
openai.api_key_path = os.path.join(os.path.dirname(__file__), "openai_api_key.txt")


@app.get("/")
async def root():
return {"message": "Hello World"}


# Add a post method to the app with the /api endpoint
@app.post("/api")
async def api(userPrompt: str):
"""
API endpoint for the model which performs data redaction
:param userPrompt: The user prompt
:return: privatePrompt
"""
# prompt="Remove all personal information and sensitive data such as name, address, mobile number, financial information, etc. in the following text and replace it with masks:"+userPrompt+"Mask all text that would violate privacy. Please output only the masked text and nothing else."
prompt = (
"""You are PrivateGPT, an AI language model designed to ensure user privacy by anonymizing personal information and sensitive data. Your primary goal is to help users interact securely without exposing any sensitive or personally identifiable information (PII), including passwords, financial details, and API keys. Please use this prompt to understand the anonymization process comprehensively.

Sensitive Personally Identifiable Information (PII):
- Sensitive PII includes data that can uniquely identify an individual and poses a significant risk if disclosed. This includes social security numbers, driver's license numbers, government-issued identification numbers, financial account details, personal health information, passwords, and API keys.

Non-Sensitive Personally Identifiable Information (PII):
- Non-sensitive PII includes information that can identify an individual but doesn't pose significant risks if disclosed. Examples include first names, last names, ages, job titles, generic addresses, and generic email addresses.

Instructions:
1. **Sensitive PII**: Never enter real or sensitive personal information, financial details, passwords, or API keys. This is vital to prevent identity theft, financial harm, unauthorized access, or breaches of confidential information.

2. **Non-Sensitive PII**: When providing examples or testing the anonymization, use generic or fake data to ensure privacy. Experiment with various non-sensitive PII like first names, job titles, or generic email addresses without using any real or sensitive data.

3. **Sensitive Data in Code**: If you include any code examples, refrain from adding sensitive information like API keys or other credentials. Use placeholder strings or generic values instead.

4. **Anonymization Process**: Once you input a text containing personal information or sensitive data, I will carefully identify and anonymize any PII and sensitive elements. Names will be replaced with generic placeholders (e.g., "John Doe" to "Person A"). Addresses, emails, passwords, financial data, and API keys will be replaced with generic or redacted versions.

Example 1:
Input: "Hi, my name is Alice, and my email is alice@example.com. My password is 'secure123'."
Output: "Hi, my name is <REDACTED>, and my email is <REDACTED>. My password is '<REDACTED>'."

Example 2:
Input: "My friend's name is Bob, and he lives at 456 Oak Avenue. He was born on 10th April 1985. His bank account number is 1234567890."
Output: "My friend's name is <REDACTED>, and he lives at <REDACTED> Avenue. He was born on <REDACTED>. His bank account number is <REDACTED>."

Example 3:
Input: "Hi, I'm Jane, and my API key is 'abc123xyz'."
Output: "Hi, I'm <REDACTED>, and my API key is '<REDACTED>'."

Anonymize the following text:
"""
+ userPrompt
+ """Mask all text that would violate privacy. Please output only the masked text and nothing else."""
)
output = llm(
prompt,
max_tokens=100,
temperature=0.0,
top_p=1.0,
frequency_penalty=0.0,
presence_penalty=0.0,
stop=["\n"],
)
privatePrompt = output.choices[0].text

# OpenAI API call
response = openai.Completion.create(
model="davinci",
prompt=privatePrompt,
max_tokens=100,
temperature=0.5,
best_of=10,
)
# Send the privatePrompt and the response from OpenAI to the frontend as a JSON object
return {"privatePrompt": privatePrompt, "response": response.choices[0].text}

if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="127.0.0.1", port=8080)
129 changes: 129 additions & 0 deletions Code Crafters/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
from database.db import init_database, insert_chat_message, get_chat_history
import streamlit as st
import requests

def chatbot_response(input_text):
url = 'https://avid-infinity-386618.el.r.appspot.com/api'
payload = {'userPrompt': input_text}
try:
with requests.post(url, json=payload) as response:
response.raise_for_status() # Check for any HTTP errors
data = response.json()
print(data)
return data
except requests.exceptions.RequestException as e:
return f'Error: {e}'

def display_chat_history(chat_history):
st.subheader("Chat History")
chat_container = st.empty()
chat_log = ""
# Process the chat history to make it more readable and display it
for index, (sender, message) in enumerate(chat_history):
if sender == "You":
chat_log += f'<div style="text-align: left; padding-left: 20px; padding: 1.5rem; color:#fff; background-color: #333;">{message}</div>'
elif sender == "PrivateGPT":
chat_log += f'<div style="text-align: right; padding-left: 20px; padding: 1.5rem; color:#fff; background-color: #555;">{message}</div>'
chat_container.write(chat_log, unsafe_allow_html=True)

def clear_chat_history():
st.session_state.chat_history = []



def main():
# Initialize the database and chat history table
db_connected = init_database()

if db_connected:
print("Database connection successful 🔗")
else:
print("Database connection failed ❌")
st.stop()

# Get the chat history from the database
chat_history = get_chat_history()

# Initialize SessionState to store chat history
if "chat_history" not in st.session_state:
st.session_state.chat_history = []

st.title("Private GPT")

# Sidebar with settings
st.sidebar.title("Settings")
# Add more settings as needed

# Apply custom CSS to change the background color
background_color = "#444654"
st.markdown(
f"""
<style>
body {{
background-color: {background_color};
}}
</style>
""",
unsafe_allow_html=True,
)


# Add a container to hold the textbox
container = st.container()
container.markdown(
"""
<style>
.st-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
padding: 10px;
}
</style>
""",
unsafe_allow_html=True,
)
user_input = container.text_input("You:", "",key="text_input")

if st.button("Send"):
response = chatbot_response(user_input)
st.session_state.chat_history.append(("You", user_input))
st.session_state.chat_history.append(("PrivateGPT", response["privatePrompt"]))
insert_chat_message("You", user_input)
insert_chat_message("PrivateGPT", response["privatePrompt"])
user_input = "" # Clear the user input after sending

# # Display previous chats in the sidebar
st.sidebar.subheader("Chat History")
st.sidebar.markdown(
"""
<style>
.sidebar .sidebar-content {
background-color: #333;
}
</style>
""",
unsafe_allow_html=True,
)
if st.sidebar.button("Show chat history"):
# Show chat history
display_chat_history(chat_history)

if st.sidebar.button("Clear chat history"):
clear_chat_history()

st.subheader("Chat")
chat_container = st.empty()
chat_log = ""
for sender, message in st.session_state.chat_history:
if sender == "You":
chat_log += f'<div style="text-align: left; padding-left: 20px; padding: 1.5rem; color:#fff; background-color: #333;">{message}</div>'
elif sender == "PrivateGPT":
chat_log += f'<div style="text-align: left; padding-left: 20px; padding: 1.5rem; color:#fff; background-color: #555;">{message}</div>'


chat_container.write(chat_log, unsafe_allow_html=True)

if __name__ == "__main__":
main()
43 changes: 43 additions & 0 deletions Code Crafters/database/db.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import sqlite3

# Function to initialize the database and chat history table
def init_database():
try:
conn = sqlite3.connect("chat_history.db")
cursor = conn.cursor()
cursor.execute(
"""
CREATE TABLE IF NOT EXISTS chat_history (
id INTEGER PRIMARY KEY,
sender TEXT,
message TEXT
)
"""
)
conn.commit()
conn.close()
return True
except Exception as e:
print(e)
return False


# Function to insert a chat message into the database
def insert_chat_message(sender, message):
conn = sqlite3.connect("chat_history.db")
cursor = conn.cursor()
cursor.execute(
"INSERT INTO chat_history (sender, message) VALUES (?, ?)", (sender, message)
)
conn.commit()
conn.close()


# Function to retrieve all chat history from the database
def get_chat_history():
conn = sqlite3.connect("chat_history.db")
cursor = conn.cursor()
cursor.execute("SELECT sender, message FROM chat_history")
chat_history = cursor.fetchall()
conn.close()
return chat_history
Loading