Skip to content

Instantly share code, notes, and snippets.

@alexalbertt
Created April 16, 2024 18:47
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save alexalbertt/f5ab98044e7450d9d952fbc0b7f20013 to your computer and use it in GitHub Desktop.
Save alexalbertt/f5ab98044e7450d9d952fbc0b7f20013 to your computer and use it in GitHub Desktop.
Me:
I am looking to build a simple GUI site that allows me to paste in some text, click "rewrite", and get rewritten, cleaned-up text back. This input text is ran through the Claude API to rewrite it. The GUI should be very simple. I just want a text box for input and a text box for output. I also two sliders on the side with labels on the ends:
Tone: casual on the left, formal on the right. The middle instructs the model to keep the tone/voice the same.
Length: shorter on the left, longer on the right.
Above these sliders, I want a model selector dropdown that let's me pick which Claude model to use. I also want a copy text button under the output textbox. The three Claude models are:
claude-3-opus-20240229. Display name "Claude 3 Opus".
claude-3-sonnet-20240229. Display name "Claude 3 Sonnet".
claude-3-haiku-20240307. Display name "Claude 3 Haiku".
Here's how you call the Claude API in Python:
import os
from anthropic import Anthropic
client = Anthropic(
# This is the default and can be omitted
api_key=os.environ.get("ANTHROPIC_API_KEY"),
)
message = client.messages.create(
max_tokens=1024,
messages=[
{
"role": "user",
"content": "Hello, Claude",
}
],
model="claude-3-opus-20240229",
)
print(message.content[0].text)
Make sure your user prompt instructs the model on what to do.
Can you create this with HTML, CSS, and JS in a single file for the frontend and a single Python file for the backend (take CORS into account here to)?
Claude:
Certainly! Here's a simple implementation of the frontend and backend for your text rewriting application using HTML, CSS, JavaScript, and Python:
Frontend (index.html):
```html
<!DOCTYPE html>
<html>
<head>
<title>Text Rewriter</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
}
.container {
display: flex;
}
.text-container {
flex-grow: 1;
margin-right: 20px;
}
textarea {
width: 100%;
height: 200px;
margin-bottom: 10px;
}
.controls-container {
display: flex;
flex-direction: column;
align-items: flex-start;
}
.slider-container {
display: flex;
align-items: center;
margin-bottom: 10px;
}
.slider-label {
margin-right: 10px;
}
.slider {
width: 200px;
}
.slider-value {
margin-left: 10px;
}
.copy-button {
margin-top: 10px;
}
</style>
</head>
<body>
<h1>Text Rewriter</h1>
<div class="container">
<div class="text-container">
<textarea id="input-text" placeholder="Enter text to rewrite"></textarea>
<button onclick="rewriteText()">Rewrite</button>
<textarea id="output-text" placeholder="Rewritten text will appear here" readonly></textarea>
<button class="copy-button" onclick="copyText()">Copy</button>
</div>
<div class="controls-container">
<select id="model-selector">
<option value="claude-3-opus-20240229">Claude 3 Opus</option>
<option value="claude-3-sonnet-20240229">Claude 3 Sonnet</option>
<option value="claude-3-haiku-20240307">Claude 3 Haiku</option>
</select>
<br>
<div class="slider-container">
<label for="tone-slider" class="slider-label">Tone:</label>
<input type="range" id="tone-slider" class="slider" min="0" max="2" value="1" step="1">
<span class="slider-value" id="tone-value">Same as input</span>
</div>
<div class="slider-container">
<label for="length-slider" class="slider-label">Length:</label>
<input type="range" id="length-slider" class="slider" min="0" max="2" value="1" step="1">
<span class="slider-value" id="length-value">Same as input</span>
</div>
</div>
</div>
<script>
function updateSliderValue(sliderId, valueId) {
const slider = document.getElementById(sliderId);
const value = document.getElementById(valueId);
const sliderValue = parseInt(slider.value);
if (sliderId === 'tone-slider') {
value.textContent = sliderValue === 0 ? 'Casual' : sliderValue === 2 ? 'Formal' : 'Same as input';
} else if (sliderId === 'length-slider') {
value.textContent = sliderValue === 0 ? 'Shorter' : sliderValue === 2 ? 'Longer' : 'Same as input';
}
}
document.getElementById('tone-slider').addEventListener('input', function() {
updateSliderValue('tone-slider', 'tone-value');
});
document.getElementById('length-slider').addEventListener('input', function() {
updateSliderValue('length-slider', 'length-value');
});
function rewriteText() {
const inputText = document.getElementById('input-text').value;
const modelSelector = document.getElementById('model-selector');
const selectedModel = modelSelector.options[modelSelector.selectedIndex].value;
const toneSlider = document.getElementById('tone-slider').value;
const lengthSlider = document.getElementById('length-slider').value;
fetch('http://localhost:5000/rewrite', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
inputText: inputText,
model: selectedModel,
tone: toneSlider,
length: lengthSlider
})
})
.then(response => response.json())
.then(data => {
document.getElementById('output-text').value = data.rewrittenText;
})
.catch(error => {
console.error('Error:', error);
});
}
function copyText() {
const outputText = document.getElementById('output-text');
outputText.select();
document.execCommand('copy');
}
</script>
</body>
</html>
```
Backend (app.py):
```python
from flask import Flask, request, jsonify
from flask_cors import CORS
import os
from anthropic import Anthropic
app = Flask(__name__)
CORS(app) # Enable CORS for all routes and origins
client = Anthropic(api_key=os.environ.get("ANTHROPIC_API_KEY"))
@app.route('/rewrite', methods=['POST'])
def rewrite():
data = request.get_json()
input_text = data['inputText']
model = data['model']
tone = int(data['tone'])
length = int(data['length'])
# Generate user prompt based on the selected options
user_prompt = f"Please rewrite the text according to the following specifications:"
user_prompt += f"Tone: {'More casual' if tone > 50 else 'More formal' if tone < 50 else 'Same as input'}\n"
user_prompt += f"Length: {'Shorter' if length > 50 else 'Longer' if length < 50 else 'Same as input'}"
user_prompt += f"\n\nInput text:\n{input_text}"
message = client.messages.create(
max_tokens=1024,
messages=[
{
"role": "user",
"content": user_prompt,
}
],
model=model,
)
rewritten_text = message.content[0].text
return jsonify({'rewrittenText': rewritten_text})
if __name__ == '__main__':
app.run()
```
To run this application:
1. Make sure you have the necessary dependencies installed, including Flask and the Anthropic Python library.
2. Set your Anthropic API key as an environment variable named `ANTHROPIC_API_KEY`.
3. Save the HTML code in a file named `index.html` and the Python code in a file named `app.py`.
4. Run the Python script using `python app.py` to start the backend server.
5. Open `index.html` in a web browser to access the frontend.
Now you can enter text in the input text box, select the desired model, adjust the tone and length sliders, and click the "Rewrite" button to get the rewritten text using the Claude API.
Note: Make sure to handle error cases and add appropriate validation and security measures in a production environment.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment