Skip to content

Instantly share code, notes, and snippets.

@johnowhitaker
Last active July 30, 2024 14:45
Show Gist options
  • Save johnowhitaker/89538c8abcd2410c1c25fdc9ef8697e0 to your computer and use it in GitHub Desktop.
Save johnowhitaker/89538c8abcd2410c1c25fdc9ef8697e0 to your computer and use it in GitHub Desktop.
Canvas demo polling
from fasthtml.all import *
import anthropic, base64, time
client = anthropic.Anthropic(
api_key="your_key_here",
)
canvas_js = """
const canvas = document.getElementById('drawingCanvas');
const context = canvas.getContext('2d');
let drawing = false;
canvas.addEventListener('mousedown', startDrawing);
canvas.addEventListener('mouseup', stopDrawing);
canvas.addEventListener('mousemove', draw);
function startDrawing(e) {
drawing = true;
draw(e);
}
function stopDrawing() {
drawing = false;
context.beginPath();
sendCanvasData();
}
function draw(e) {
if (!drawing) return;
context.lineWidth = 5;
context.lineCap = 'round';
context.strokeStyle = 'black';
context.lineTo(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop);
context.stroke();
context.beginPath();
context.moveTo(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop);
}
function sendCanvasData() {
canvas.toBlob((blob) => {
const formData = new FormData();
formData.append('image', blob, 'canvas.png');
fetch('/process-canvas', {
method: 'POST',
body: formData,
});
});
}
"""
canvas_css = """
canvas {
border: 1px solid black;
background-color: #f0f0f0;
}
"""
caption = "Draw something!"
app = FastHTML(hdrs=(picolink,
Script(NotStr(canvas_js), type="module"),
Style(NotStr(canvas_css))))
# Main page
@app.get("/")
def home():
return Title('Drawing Demo'), Main(
H1("Haiku Canvas Demo"),
Canvas(id="drawingCanvas", width="500", height="500"),
P(), get_caption(), cls='container')
@app.post("/caption")
def get_caption():
return Div(*[P(c) for c in caption.split("\n")], id="response",
hx_trigger="every 1s",hx_swap="outerHTML", hx_post="/caption")
@threaded
def process_image(image_base64):
global caption
message = client.messages.create(
model="claude-3-haiku-20240307",
max_tokens=100,
temperature=0.5,
messages=[
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/png",
"data": image_base64,
},
},
{
"type": "text",
"text": "Write a haiku about this drawing, respond with only that."
}
],
}
],
)
caption = message.content[0].text
@app.post("/process-canvas")
async def process_canvas(request):
global caption
form = await request.form()
image = await form.get('image').read()
process_image(base64.b64encode(image).decode('utf-8'))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment