Spaces:
Sleeping
Sleeping
| 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( | |
| key_func=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; | |
| } | |
| #error-message { | |
| color: red; | |
| text-align: center; | |
| margin-top: 10px; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <h1>Silly Detention Letter Generator</h1> | |
| <div id="letter"></div> | |
| <div id="error-message"></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 => { | |
| if (!response.ok) { | |
| throw new Error('Slow down. Please wait 1 minute before generating another letter.'); | |
| } | |
| return response; | |
| }) | |
| .then(response => { | |
| const reader = response.body.getReader(); | |
| const decoder = new TextDecoder(); | |
| const letterDiv = document.getElementById('letter'); | |
| letterDiv.innerHTML = ''; | |
| document.getElementById('error-message').textContent = ''; | |
| 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(); | |
| }) | |
| .catch(error => { | |
| document.getElementById('error-message').textContent = error.message; | |
| }); | |
| } | |
| function regenerateLetter() { | |
| document.getElementById('letterForm').dispatchEvent(new Event('submit')); | |
| } | |
| </script> | |
| </body> | |
| </html> | |
| """ | |
| # Define Flask routes | |
| def home(): | |
| return render_template_string(html_template) | |
| 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) |