silly-letter / app.py
bencser's picture
Update app.py
5ba04ca verified
raw
history blame
6.65 kB
import os
import logging
from groq import Groq
from flask import Flask, render_template_string, request, Response, stream_with_context
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address
from dotenv import load_dotenv
load_dotenv()
app = Flask(__name__)
# Set up logging
logging.basicConfig(level=logging.DEBUG)
# Set up rate limiter
limiter = Limiter(
get_remote_address,
app=app,
default_limits=["5 per minute"],
storage_uri="memory://"
)
# Set Groq API key
client = Groq(api_key=os.getenv("GROQ_API_KEY"))
# Set model
model = "llama-3.1-70b-versatile"
# Define function to generate text
def generate_text(parent_name, child_name, language):
prompts = {
"posh": f"Generate a concise silly letter written in posh British English used in private schools - to {parent_name} about their child {child_name}'s detention reasons. Write extreme but realistic behaviours.",
"english": f"Generate a concise silly letter in standard English to {parent_name} about their child {child_name}'s detention reasons. Write extreme but realistic behaviours.",
"hungarian": f"Generate a Hungarian language, concise silly letter to {parent_name} about their child {child_name}'s detention reasons. Write extreme but realistic behaviours. Make sur you use formal you."
}
prompt = prompts[language]
try:
completion = client.chat.completions.create(
model=model,
messages=[
{
"role": "user",
"content": prompt
}
],
temperature=0.8,
max_tokens=1024,
top_p=0.65,
stream=True,
stop=None,
)
return completion
except Exception as e:
app.logger.error(f"Error generating text: {str(e)}")
return "An error occurred while generating the text."
# HTML template
html_template = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Silly Detention Letter Generator</title>
<link href="https://fonts.googleapis.com/css2?family=Lora:wght@600&family=Open+Sans&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Open Sans', sans-serif;
line-height: 1.6;
color: #333;
max-width: 800px;
margin: 0 auto;
padding: 20px;
background-color: #f4f4f4;
}
h1 {
font-family: 'Lora', serif;
color: #2c3e50;
text-align: center;
}
#letter {
background-color: white;
border: 1px solid #ddd;
padding: 20px;
border-radius: 5px;
white-space: pre-wrap;
margin-bottom: 20px;
font-family: 'Lora', serif;
font-size: 1.1em;
}
form {
background-color: white;
padding: 20px;
border-radius: 5px;
margin-bottom: 20px;
}
input[type="text"], select {
width: 100%;
padding: 10px;
margin-bottom: 10px;
border: 1px solid #ddd;
border-radius: 5px;
font-family: 'Open Sans', sans-serif;
}
input[type="submit"], #regenerate {
display: block;
width: 200px;
margin: 20px auto;
padding: 10px;
background-color: #3498db;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
font-family: 'Open Sans', sans-serif;
}
input[type="submit"]:hover, #regenerate:hover {
background-color: #2980b9;
}
</style>
</head>
<body>
<h1>Silly Detention Letter Generator</h1>
<div id="letter"></div>
<button id="regenerate" style="display: none;" onclick="regenerateLetter()">Regenerate Letter</button>
<form id="letterForm" onsubmit="generateLetter(event)">
<input type="text" name="parent_name" placeholder="Parent's Name" required>
<input type="text" name="child_name" placeholder="Child's Name" required>
<select name="language" required>
<option value="posh">Posh British English (Private School)</option>
<option value="english">Standard English</option>
<option value="hungarian">Hungarian</option>
</select>
<input type="submit" value="Generate Letter">
</form>
<script>
function generateLetter(event) {
event.preventDefault();
const form = event.target;
const formData = new FormData(form);
fetch('/generate', {
method: 'POST',
body: formData
})
.then(response => {
const reader = response.body.getReader();
const decoder = new TextDecoder();
const letterDiv = document.getElementById('letter');
letterDiv.innerHTML = '';
function read() {
reader.read().then(({ done, value }) => {
if (done) {
document.getElementById('regenerate').style.display = 'block';
return;
}
const chunk = decoder.decode(value);
letterDiv.innerHTML += chunk;
read();
});
}
read();
});
}
function regenerateLetter() {
document.getElementById('letterForm').dispatchEvent(new Event('submit'));
}
</script>
</body>
</html>
"""
# Define Flask routes
@app.route("/", methods=["GET"])
def home():
return render_template_string(html_template)
@app.route("/generate", methods=["POST"])
@limiter.limit("5/minute")
def generate():
parent_name = request.form["parent_name"]
child_name = request.form["child_name"]
language = request.form["language"]
def generate_streaming_response():
for chunk in generate_text(parent_name, child_name, language):
if hasattr(chunk.choices[0].delta, 'content'):
yield chunk.choices[0].delta.content or ""
return Response(stream_with_context(generate_streaming_response()), content_type='text/plain')
if __name__ == "__main__":
app.run(host="0.0.0.0", port=7860)