wire up basic API client
This commit is contained in:
parent
c4e542bc40
commit
85f117823c
|
@ -0,0 +1,28 @@
|
|||
export interface Txt2ImgParams {
|
||||
prompt: string;
|
||||
cfg: number;
|
||||
steps: number;
|
||||
}
|
||||
|
||||
export interface ApiClient {
|
||||
txt2img(params: Txt2ImgParams): Promise<string>;
|
||||
}
|
||||
|
||||
export function makeClient(root: string, f = fetch): ApiClient {
|
||||
return {
|
||||
async txt2img(params: Txt2ImgParams): Promise<string> {
|
||||
const { prompt, cfg, steps } = params;
|
||||
|
||||
const safePrompt = encodeURIComponent(prompt);
|
||||
const url = `${root}/txt2img?prompt=${safePrompt}&steps=${steps.toFixed(0)}&cfg=${cfg.toFixed(0)}`;
|
||||
const res = await f(url);
|
||||
|
||||
if (res.status === 200) {
|
||||
const imageBlob = await res.blob();
|
||||
return URL.createObjectURL(imageBlob);
|
||||
} else {
|
||||
throw new Error('request error');
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
|
@ -1,9 +1,19 @@
|
|||
import { TabContext, TabList, TabPanel } from '@mui/lab';
|
||||
import { Box, Container, Tab, Typography } from '@mui/material';
|
||||
import { Box, Container, MenuItem, Select, Tab, Typography } from '@mui/material';
|
||||
import * as React from 'react';
|
||||
|
||||
export function OnnxWeb() {
|
||||
const [tab, setTab] = React.useState('1');
|
||||
import { ApiClient } from '../api/client.js';
|
||||
import { Txt2Img } from './Txt2Img.js';
|
||||
|
||||
const { useState } = React;
|
||||
|
||||
export interface OnnxWebProps {
|
||||
client: ApiClient;
|
||||
}
|
||||
|
||||
export function OnnxWeb(props: OnnxWebProps) {
|
||||
const [tab, setTab] = useState('1');
|
||||
const [model, setModel] = useState('v1.5');
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
@ -13,6 +23,14 @@ export function OnnxWeb() {
|
|||
ONNX Web GUI
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box sx={{ my: 4 }}>
|
||||
<Select value={model} onChange={(e) => {
|
||||
setModel(e.target.value);
|
||||
}}>
|
||||
<MenuItem value='v1.4'>Stable Diffusion v1.4</MenuItem>
|
||||
<MenuItem value='v1.5'>Stable Diffusion v1.5</MenuItem>
|
||||
</Select>
|
||||
</Box>
|
||||
<TabContext value={tab}>
|
||||
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
|
||||
<TabList onChange={(_e, idx) => {
|
||||
|
@ -23,9 +41,18 @@ export function OnnxWeb() {
|
|||
<Tab label="settings" value="3" />
|
||||
</TabList>
|
||||
</Box>
|
||||
<TabPanel value="1">txt2img</TabPanel>
|
||||
<TabPanel value="2">img2img</TabPanel>
|
||||
<TabPanel value="3">settings</TabPanel>
|
||||
<TabPanel value="1">
|
||||
<Box>
|
||||
txt2img using {model}
|
||||
</Box>
|
||||
<Txt2Img {...props} />
|
||||
</TabPanel>
|
||||
<TabPanel value="2">
|
||||
<Box>
|
||||
img2img using {model}
|
||||
</Box>
|
||||
</TabPanel>
|
||||
<TabPanel value="3">settings for onnx-web</TabPanel>
|
||||
</TabContext>
|
||||
</Container>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
import { Box, Button, TextField } from "@mui/material";
|
||||
import * as React from 'react';
|
||||
import { ApiClient } from "../api/client";
|
||||
|
||||
const { useEffect, useState } = React;
|
||||
|
||||
export interface Txt2ImgProps {
|
||||
client: ApiClient;
|
||||
}
|
||||
|
||||
export function Txt2Img(props: Txt2ImgProps) {
|
||||
const { client } = props;
|
||||
const [image, setImage] = useState('');
|
||||
|
||||
const [cfg, setCfg] = useState(5);
|
||||
const [prompt, setPrompt] = useState('an astronaut eating a hamburger');
|
||||
const [steps, setSteps] = useState(20);
|
||||
|
||||
async function getImage() {
|
||||
const image = await client.txt2img({ prompt, cfg, steps });
|
||||
console.log(prompt, image);
|
||||
setImage(image);
|
||||
}
|
||||
|
||||
function renderImage() {
|
||||
if (image === '') {
|
||||
return <div>No image</div>;
|
||||
} else {
|
||||
return <img src={image} />;
|
||||
}
|
||||
}
|
||||
|
||||
return <Box>
|
||||
<TextField label="CFG" variant="outlined" type="number" inputProps={{ min: 5, max: 30 }} value={cfg} onChange={(event) => {
|
||||
setCfg(parseInt(event.target.value, 10));
|
||||
}} />
|
||||
<TextField label="Steps" variant="outlined" type="number" inputProps={{ min: 15, max: 150 }} value={steps} onChange={(event) => {
|
||||
setSteps(parseInt(event.target.value, 10));
|
||||
}} />
|
||||
<TextField label="Prompt" variant="outlined" value={prompt} onChange={(event) => {
|
||||
console.log('changing prompt', event.target.value);
|
||||
setPrompt(event.target.value);
|
||||
}} />
|
||||
<Button onClick={getImage}>Generate</Button>
|
||||
{renderImage()}
|
||||
</Box>;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
export const CONFIG = {
|
||||
api: {
|
||||
root: 'http://ssube-desktop.home.holdmyran.ch:5000',
|
||||
},
|
||||
};
|
|
@ -1,12 +1,15 @@
|
|||
import { mustExist } from '@apextoaster/js-utils';
|
||||
import * as React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import { makeClient } from './api/client';
|
||||
import { OnnxWeb } from './components/OnnxWeb';
|
||||
import { CONFIG } from './config';
|
||||
|
||||
export function main() {
|
||||
const appElement = mustExist(document.getElementById('app'));
|
||||
const app = ReactDOM.createRoot(appElement);
|
||||
app.render(<OnnxWeb />);
|
||||
const client = makeClient(CONFIG.api.root);
|
||||
app.render(<OnnxWeb client={client} />);
|
||||
}
|
||||
|
||||
main();
|
||||
|
|
Loading…
Reference in New Issue