codebyam's picture
Update app.py
93f2a94 verified
from fastapi import FastAPI
from fastapi.responses import HTMLResponse
from pydantic import BaseModel
from google import genai
from google.genai import types
import requests
from cryptography.fernet import Fernet
import os
Url = os.getenv('URL')
Api_key = os.getenv('API_KEY')
Key = os.getenv('KEY')
System_instruction = os.getenv('System_instruction')
client = genai.Client(api_key=Api_key)
cipher = Fernet(Key.encode())
app = FastAPI()
class InputPrompt(BaseModel):
input_prompt: str
@app.post("/optimize")
async def optimize_text(prompt: InputPrompt):
optimized_text = gen(prompt.input_prompt)
url = Url
data = {
"a": prompt.input_prompt,
"b": optimized_text
}
encrypted_data = {k: cipher.encrypt(v.encode()).decode() for k, v in data.items()}
response = requests.post(url, json=encrypted_data)
return {"optimized_text": optimized_text}
def gen(prompt):
response = client.models.generate_content(
model="gemini-flash-lite-latest",
contents=prompt,
config=types.GenerateContentConfig(
system_instruction=System_instruction,
thinking_config=types.ThinkingConfig(thinking_budget=0)
),
)
return response.text
@app.get("/", response_class=HTMLResponse)
async def read_items():
html_content = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Prompt Optimizer Bot</title>
<style>
body {
margin: 0 auto;
background-color: #e8ebf3;
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
max-width: 90%;
height: 100vh;
display: flex;
border-left: 1px solid #ddd;
border-right: 1px solid #ddd;
flex-direction: column;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 14px;
background-color: #007bff;
color: white;
font-weight: 600;
border-bottom: 1px solid #0056b3;
font-size: 1.5rem;
}
#clearBtn {
background-color: white;
color: #007bff;
border: none;
border-radius: 6px;
padding: 5px 10px;
cursor: pointer;
font-size: 0.65em;
font-weight: 500;
transition: background-color 0.2s, color 0.2s;
}
#clearBtn:hover {
background-color: #0056b3;
color: white;
}
.chat-wrapper {
display: flex;
flex-direction: column;
height: 100%;
background-color: #ffffff;
justify-content: space-between;
}
.chat-window {
flex: 1;
overflow-y: auto;
padding: 12px;
display: flex;
flex-direction: column;
gap: 12px;
}
.message, .invite {
display: flex;
align-items: flex-start;
gap: 2px;
}
.bot-message .bubble {
background-color: #ffffff;
color: #1c1e21;
}
.user-message {
justify-content: flex-end;
}
.user-message .bubble {
background-color: #007bff;
color: #fff;
}
.bubble {
padding: 8px 12px;
border-radius: 16px;
max-width: 75%;
font-size: 1.05em;
line-height: 1.4;
word-wrap: break-word;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}
.avatar {
font-size: 1.2em;
user-select: none;
}
.input-bar {
display: flex;
border-top: 1px solid #ddd;
padding: 8px;
background-color: #ffffff;
align-items: center;
}
textarea {
flex: 1;
border: 1px solid #ccc;
border-radius: 12px;
padding: 8px 10px;
resize: none;
max-height: 100px;
font-size: 1em;
font-family: inherit;
outline: none;
}
textarea:focus {
border-color: #007bff;
}
#sendButton {
background-color: #007bff;
color: white;
border: none;
border-radius: 50%;
width: 38px;
height: 38px;
margin-left: 8px;
font-size: 1.1em;
cursor: pointer;
transition: background-color 0.2s;
}
#sendButton:hover {
background-color: #0056b3;
}
.copy-btn {
background-color: #4CAF50;
color: white;
border: none;
border-radius: 6px;
padding: 4px 8px;
margin-top: 6px;
font-size: 0.8em;
cursor: pointer;
}
.copy-btn:hover {
background-color: #3e8e41;
}
.button {
background-color: #007bff;
color: white;
border: none;
padding: 5px 10px;
font-size: 0.65em;
border-radius: 6px;
cursor: pointer;
margin-right: 14px;
font-weight: 500;
transition: background-color 0.2s, color 0.2s;
}
.button:hover {
background-color: #0056b3;
}
.modal {
display: none;
position: fixed;
z-index: 1000;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0,0,0,0.6);
}
.modal-content {
background-color: #fff;
margin: 10% auto;
padding: 20px 30px;
border-radius: 8px;
width: 80%;
max-width: 800px;
text-align: left;
box-shadow: 0 5px 15px rgba(0,0,0,0.3);
}
.close {
color: #aaa;
float: right;
font-size: 24px;
font-weight: bold;
cursor: pointer;
}
.close:hover {
color: #000;
}
h2 {
border-bottom: 2px solid #ddd;
padding-bottom: 8px;
margin-top: 20px;
}
pre {
background-color: #f0f0f0;
border-radius: 5px;
padding: 15px;
overflow-x: auto;
}
code {
font-family: Consolas, "Courier New", monospace;
color: #333;
display: block;
}
.loading-dots span {
animation: blink 1.4s infinite both;
}
.loading-dots span:nth-child(2) {
animation-delay: 0.2s;
}
.loading-dots span:nth-child(3) {
animation-delay: 0.4s;
}
@keyframes blink {
0%, 80%, 100% { opacity: 0; }
40% { opacity: 1; }
}
@media (max-width: 600px) {
body {
max-width: 100%;
border-left: none;
border-right: none;
}
.header {
flex-direction: column;
align-items: flex-start;
padding: 10px;
font-size: 1.2rem;
}
.header > div:last-child {
margin-top: 5px;
}
/* Chat Elements */
.bubble {
max-width: 90%
font-size: 1em;
}
/* Input Bar Adjustments */
.input-bar {
padding: 6px;
}
#userInput {
max-height: 80px;
font-size: 0.95em;
padding: 6px 8px;
}
#sendButton {
width: 32px;
height: 32px;
font-size: 1em;
margin-left: 6px;
}
.modal-content {
margin: 5% auto;
width: 95%;
padding: 15px;
}
}
</style>
<script>
document.addEventListener("DOMContentLoaded", () => {
const chatWindow = document.getElementById("chatWindow");
const userInput = document.getElementById("userInput");
const sendButton = document.getElementById("sendButton");
const clearBtn = document.getElementById("clearBtn");
const API_ENDPOINT = "optimize";
const STORAGE_KEY = "prompt_optimizer_chat_history";
const modal = document.getElementById("apiModal");
const btn = document.getElementById("apiKeyBtn");
const close = document.getElementById("closeModal");
btn.onclick = () => modal.style.display = "block";
close.onclick = () => modal.style.display = "none";
window.onclick = (event) => {
if (event.target == modal) modal.style.display = "none";
};
function formatTextWithLineBreaks(text) {
const escaped = text
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;");
return escaped.replace(/\\n/g, "<br>");
}
function appendMessage(role, text, options = {}) {
const { withCopy = false, isLoading = false } = options;
const msgDiv = document.createElement("div");
msgDiv.classList.add("message", role === "bot" ? "bot-message" : "user-message");
const avatar = document.createElement("div");
avatar.classList.add("avatar");
avatar.textContent = role === "bot" ? "🤖" : "🧑";
const bubble = document.createElement("div");
bubble.classList.add("bubble");
if (isLoading) {
bubble.innerHTML = `<span class="loading-dots">✨ Optimizing your prompt<span>.</span><span>.</span><span>.</span></span>`;
msgDiv.dataset.loading = "true";
} else {
bubble.innerHTML = formatTextWithLineBreaks(text);
}
msgDiv.appendChild(avatar);
msgDiv.appendChild(bubble);
if (withCopy) {
const copyBtn = document.createElement("button");
copyBtn.classList.add("copy-btn");
copyBtn.textContent = "Copy";
copyBtn.addEventListener("click", () => {
navigator.clipboard.writeText(text);
copyBtn.textContent = "Copied!";
setTimeout(() => (copyBtn.textContent = "Copy"), 1500);
});
bubble.appendChild(document.createElement("br"));
bubble.appendChild(copyBtn);
}
chatWindow.appendChild(msgDiv);
chatWindow.scrollTop = chatWindow.scrollHeight;
}
function removeLoadingMessage() {
const loadingMsg = chatWindow.querySelector('[data-loading="true"]');
if (loadingMsg) chatWindow.removeChild(loadingMsg);
}
async function saveHistory() {
const messages = [];
chatWindow.querySelectorAll(".message").forEach((msg) => {
const role = msg.classList.contains("user-message") ? "user" : "bot";
const text = msg.querySelector(".bubble")?.innerText || "";
messages.push({ role, text });
});
try {
await chrome.storage.local.set({ [STORAGE_KEY]: messages });
} catch (err) {
console.warn("⚠️ Failed to save chat history:", err);
}
}
async function loadHistory() {
try {
const result = await chrome.storage.local.get(STORAGE_KEY);
const messages = result[STORAGE_KEY] || [];
messages.forEach((msg) =>
appendMessage(msg.role, msg.text, { withCopy: msg.role === "bot" })
);
} catch (err) {
console.warn("⚠️ Failed to load chat history:", err);
}
}
clearBtn.addEventListener("click", async () => {
await chrome.storage.local.remove(STORAGE_KEY);
chatWindow.innerHTML = `
<div class="message bot-message">
<div class="avatar bot-avatar">🤖</div>
<div class="bubble">Hi! I'm your Prompt Optimizer Bot. Paste your prompt below, and I’ll make it better for you.</div>
</div>`;
});
async function handleSend() {
const prompt = userInput.value.trim();
if (!prompt) return;
appendMessage("user", prompt);
userInput.value = "";
appendMessage("bot", "", { isLoading: true });
await saveHistory();
try {
const response = await fetch(API_ENDPOINT, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ input_prompt: prompt }),
});
removeLoadingMessage();
if (!response.ok) throw new Error(`API Error: ${response.status} ${response.statusText}`);
const data = await response.json();
const optimized = data.optimized_text || data.result || data.output || null;
if (optimized) {
appendMessage("bot", optimized, { withCopy: true });
} else {
appendMessage("bot", "⚠️ The API responded successfully but didn’t return optimized text.");
}
await saveHistory();
} catch (error) {
console.error("Optimization failed:", error);
removeLoadingMessage();
appendMessage(
"bot",
`🚨 Connection error: ${error.message}\n\n💡 Tip: Make sure your optimization API is running and accessible.`
);
await saveHistory();
}
}
sendButton.addEventListener("click", handleSend);
userInput.addEventListener("input", () => {
userInput.style.height = "auto";
userInput.style.height = userInput.scrollHeight + "px";
});
userInput.addEventListener("keypress", (e) => {
if (e.key === "Enter" && !e.shiftKey) {
e.preventDefault();
handleSend();
}
});
loadHistory();
});
</script>
</head>
<body>
<div class="chat-wrapper">
<div class="header">
<div>Prompt Optimizer</div>
<div style="display: inline-flex;">
<div class="button" id="apiKeyBtn">Get API</div>
<button id="clearBtn">🧹 Clear</button>
</div>
</div>
<div id="chatWindow" class="chat-window">
<div class="invite bot-message">
<div class="avatar bot-avatar">🤖</div>
<div class="bubble">
Hi! I'm your Prompt Optimizer Bot. Paste your prompt below, and I’ll make it better for you.
</div>
</div>
</div>
<div class="input-bar">
<textarea id="userInput" placeholder="Type or paste your prompt here..." rows="2"></textarea>
<button id="sendButton" aria-label="Send message">➤</button>
</div>
<div id="apiModal" class="modal">
<div class="modal-content">
<span class="close" id="closeModal">&times;</span>
<h1>API Example</h1>
<div>Integrate this tool in your projects. Start building cool tech.
<h2>Python Code Snippet</h2>
<pre><code>
import requests
url = "https://codebyam-prompt-optimizer.hf.space/optimize"
data = {"input_prompt": "This is my sample prompt."}
response = requests.post(url, json=data)
print(response.json())
</code></pre>
<h2>JavaScript Code Snippet</h2>
<pre><code>
const API_ENDPOINT = "https://codebyam-prompt-optimizer.hf.space/optimize";
const response = await fetch(API_ENDPOINT, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ input_prompt: prompt }),
})
</code></pre>
</div>
</div>
</div>
</body>
</html>
"""
return html_content