From 18abd198a15a1dd06017087c28988b792fecbc1f Mon Sep 17 00:00:00 2001 From: Stephane T Date: Sun, 19 Mar 2023 21:18:08 +0000 Subject: [PATCH] my commits --- package-lock.json | 16 ++--- pages/api/generate.js | 45 ++++++++++++ pages/index.js | 162 +++++++++++++++++++++++++++++++++++++----- 3 files changed, 197 insertions(+), 26 deletions(-) create mode 100644 pages/api/generate.js diff --git a/package-lock.json b/package-lock.json index 442e4dc..5e2f64c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "dreambooth-web-app", + "name": "ai-avatar-generator", "version": "0.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "dreambooth-web-app", + "name": "ai-avatar-generator", "version": "0.1.0", "dependencies": { "eslint": "8.29.0", @@ -1984,9 +1984,9 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" }, "node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dependencies": { "minimist": "^1.2.0" }, @@ -4345,9 +4345,9 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" }, "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "requires": { "minimist": "^1.2.0" } diff --git a/pages/api/generate.js b/pages/api/generate.js new file mode 100644 index 0000000..f64c012 --- /dev/null +++ b/pages/api/generate.js @@ -0,0 +1,45 @@ +const bufferToBase64 = (buffer) => { + let arr = new Uint8Array(buffer); + const base64 = btoa( + arr.reduce((data, byte) => data + String.fromCharCode(byte), '') + ) + return `data:image/png;base64,${base64}`; + }; + +const generateAction = async (req, res) => { + console.log('Received request'); + + const input = JSON.parse(req.body).input; + + // Add fetch request to Hugging Face + const response = await fetch( + `https://api-inference.huggingface.co/models/Medicypo/sd-1-5-stephanemed`, + { + headers: { + Authorization: `Bearer ${process.env.HF_AUTH_KEY}`, + 'Content-Type': 'application/json', + 'x-use-cache': 'false' + }, + method: 'POST', + body: JSON.stringify({ + inputs: input, + }), + } + ); + // Check for different statuses to send proper payload + if (response.ok) { + const buffer = await response.arrayBuffer(); + // Convert to base64 + const base64 = bufferToBase64(buffer); + // Make sure to change to base64 + res.status(200).json({ image: base64 }); + } else if (response.status === 503) { + const json = await response.json(); + res.status(503).json(json); + } else { + const json = await response.json(); + res.status(response.status).json({ error: response.statusText }); + } + }; + + export default generateAction; \ No newline at end of file diff --git a/pages/index.js b/pages/index.js index b08f060..e66efa9 100644 --- a/pages/index.js +++ b/pages/index.js @@ -1,36 +1,162 @@ +import { useState, useEffect } from 'react'; import Head from 'next/head'; import Image from 'next/image'; -import buildspaceLogo from '../assets/buildspace-logo.png'; const Home = () => { + const maxRetries = 20; + const [input, setInput] = useState(""); + const [img, setImg] = useState(""); + // Numbers of retries + const [retry, setRetry] = useState(0); + // Number of retries left + const [retryCount, setRetryCount] = useState(maxRetries); + // Add isGenerating state + const [isGenerating, setIsGenerating] = useState(false); + // Add new state here + const [finalPrompt, setFinalPrompt] = useState(''); + + const sleep = (ms) => { + return new Promise((resolve) => { + setTimeout(resolve, ms); + }); + }; + + useEffect(() => { + const runRetry = async () => { + if (retryCount === 0) { + console.log(`Model still loading after ${maxRetries} retries. Try request again in 5 minutes.`); + setRetryCount(maxRetries); + return; + } + + console.log(`Trying again in ${retry} seconds.`); + + await sleep(retry * 1000); + + await generateAction(); + }; + + if (retry === 0) { + return; + } + + runRetry(); + }, [retry]); + + const onChange = (event) => { + setInput(event.target.value); + }; + // Add generateAction + const generateAction = async () => { + console.log("Generating..."); + // Add this check to make sure there is no double click + if (isGenerating && retry === 0) return; + + // Set loading has started + setIsGenerating(true); + + // If this is a retry request, take away retryCount + if (retry > 0) { + setRetryCount((prevState) => { + if (prevState === 0) { + return 0; + } else { + return prevState - 1; + } + }); + + setRetry(0); + } + + // const finalInput = input.replace(/raza/gi, 'abraza'); + + // Add the fetch request + const response = await fetch("/api/generate", { + method: "POST", + headers: { + "Content-Type": "image/jpeg", + }, + // body: JSON.stringify({ finalInput }), + body: JSON.stringify({ input }), + }); + + const data = await response.json(); + if (response.status === 503) { + setRetry(data.estimated_time); + + return; + } + + // If another error, drop error + if (!response.ok) { + console.log(`Error: ${data.error}`); + // Stop loading + setIsGenerating(false); + return; + } + // Set final prompt here + setFinalPrompt(input); + // Remove content from input box + setInput(''); + setImg(data.image); + setIsGenerating(false); + }; + return (
- AI Avatar Generator | buildspace + AI Avatar Generator
-

your generator one-liner

+

FFS Generator

-

description of your generator

+

Write the name of the FFS member and a prompt of your choice. Available FFS members so far: "stephane"

-
-
-
- -
- buildspace logo -

build with buildspace

+ {/* Add prompt container here */} +
+ + +
+
+ {/* Add output container */} + {img && ( +
+ {finalPrompt} + {/* Add prompt here */} +

{finalPrompt}

+
+ )}
- -
- +
+ + + +
+ ); };