1
0
Fork 0

convert to list of outputs

This commit is contained in:
Sean Sube 2023-02-20 23:47:43 -06:00
parent b65e4e7cbe
commit 33ab23a474
Signed by: ssube
GPG Key ID: 3EED7B957D362AF1
8 changed files with 50 additions and 37 deletions

View File

@ -30,7 +30,7 @@ def hash_value(sha, param: Param):
def json_params(
output: str,
output: List[str],
params: ImageParams,
size: Size,
upscale: Optional[UpscaleParams] = None,

View File

@ -542,11 +542,12 @@ def img2img():
)
output = make_output_name(context, "img2img", params, size, extras=(strength,))
logger.info("img2img job queued for: %s", output)
job_name = output[0]
logger.info("img2img job queued for: %s", job_name)
source = valid_image(source, min_dims=size, max_dims=size)
executor.submit(
output,
job_name,
run_img2img_pipeline,
context,
params,
@ -566,10 +567,11 @@ def txt2img():
upscale = upscale_from_request()
output = make_output_name(context, "txt2img", params, size)
logger.info("txt2img job queued for: %s", output)
job_name = output[0]
logger.info("txt2img job queued for: %s", job_name)
executor.submit(
output,
job_name,
run_txt2img_pipeline,
context,
params,
@ -623,12 +625,13 @@ def inpaint():
tile_order,
),
)
logger.info("inpaint job queued for: %s", output)
job_name = output[0]
logger.info("inpaint job queued for: %s", job_name)
source = valid_image(source, min_dims=size, max_dims=size)
mask = valid_image(mask, min_dims=size, max_dims=size)
executor.submit(
output,
job_name,
run_inpaint_pipeline,
context,
params,
@ -660,11 +663,12 @@ def upscale():
upscale = upscale_from_request()
output = make_output_name(context, "upscale", params, size)
logger.info("upscale job queued for: %s", output)
job_name = output[0]
logger.info("upscale job queued for: %s", job_name)
source = valid_image(source, min_dims=size, max_dims=size)
executor.submit(
output,
job_name,
run_upscale_pipeline,
context,
params,
@ -697,6 +701,7 @@ def chain():
# get defaults from the regular parameters
device, params, size = pipeline_from_request()
output = make_output_name(context, "chain", params, size)
job_name = output[0]
pipeline = ChainPipeline()
for stage_data in data.get("stages", []):
@ -750,7 +755,7 @@ def chain():
# build and run chain pipeline
empty_source = Image.new("RGB", (size.width, size.height))
executor.submit(
output,
job_name,
pipeline,
context,
params,
@ -785,10 +790,11 @@ def blend():
upscale = upscale_from_request()
output = make_output_name(context, "upscale", params, size)
logger.info("upscale job queued for: %s", output)
job_name = output[0]
logger.info("upscale job queued for: %s", job_name)
executor.submit(
output,
job_name,
run_blend_pipeline,
context,
params,

View File

@ -32,7 +32,7 @@
"default": 0.0,
"min": 0,
"max": 1,
"step": 0.1
"step": 0.01
},
"faceOutscale": {
"default": 1,

View File

@ -145,10 +145,10 @@ export interface BlendParams {
* General response for most image requests.
*/
export interface ImageResponse {
output: {
output: Array<{
key: string;
url: string;
};
}>;
params: Required<BaseImgParams> & Required<ModelParams>;
size: {
width: number;
@ -237,9 +237,9 @@ export interface ApiClient {
/**
* Check whether some pipeline's output is ready yet.
*/
ready(params: ImageResponse): Promise<ReadyResponse>;
ready(key: string): Promise<ReadyResponse>;
cancel(params: ImageResponse): Promise<boolean>;
cancel(key: string): Promise<boolean>;
}
/**
@ -520,16 +520,16 @@ export function makeClient(root: string, f = fetch): ApiClient {
method: 'POST',
});
},
async ready(params: ImageResponse): Promise<ReadyResponse> {
async ready(key: string): Promise<ReadyResponse> {
const path = makeApiUrl(root, 'ready');
path.searchParams.append('output', params.output.key);
path.searchParams.append('output', key);
const res = await f(path);
return await res.json() as ReadyResponse;
},
async cancel(params: ImageResponse): Promise<boolean> {
async cancel(key: string): Promise<boolean> {
const path = makeApiUrl(root, 'cancel');
path.searchParams.append('output', params.output.key);
path.searchParams.append('output', key);
const res = await f(path, {
method: 'PUT',
@ -546,17 +546,22 @@ export function makeClient(root: string, f = fetch): ApiClient {
* that into a full URL, since it already knows the root URL of the server.
*/
export async function parseApiResponse(root: string, res: Response): Promise<ImageResponse> {
type LimitedResponse = Omit<ImageResponse, 'output'> & { output: string };
type LimitedResponse = Omit<ImageResponse, 'output'> & { output: Array<string> };
if (res.status === STATUS_SUCCESS) {
const data = await res.json() as LimitedResponse;
const url = new URL(joinPath('output', data.output), root).toString();
const images = data.output.map((output) => {
const url = new URL(joinPath('output', output), root).toString();
return {
key: output,
url,
};
});
return {
...data,
output: {
key: data.output,
url,
},
output: images,
};
} else {
throw new Error('request error');

View File

@ -42,7 +42,7 @@ export function ImageCard(props: ImageCardProps) {
const setBlend = useStore(state, (s) => s.setBlend);
async function loadSource() {
const req = await fetch(output.url);
const req = await fetch(output[0].url);
return req.blob();
}
@ -88,7 +88,7 @@ export function ImageCard(props: ImageCardProps) {
}
function downloadImage() {
window.open(output.url, '_blank');
window.open(output[0].url, '_blank');
}
function close() {
@ -101,7 +101,7 @@ export function ImageCard(props: ImageCardProps) {
return <Card sx={{ maxWidth: config.params.width.default }} elevation={2}>
<CardMedia sx={{ height: config.params.height.default }}
component='img'
image={output.url}
image={output[0].url}
title={params.prompt}
/>
<CardContent>

View File

@ -18,11 +18,11 @@ export function ImageHistory() {
const children = [];
if (loading.length > 0) {
children.push(...loading.map((item) => <LoadingCard key={`loading-${item.image.output.key}`} loading={item.image} />));
children.push(...loading.map((item) => <LoadingCard key={`loading-${item.image.output[0].key}`} index={0} loading={item.image} />));
}
if (history.length > 0) {
children.push(...history.map((item) => <ImageCard key={`history-${item.output.key}`} value={item} onDelete={removeHistory} />));
children.push(...history.map((item) => <ImageCard key={`history-${item.output[0].key}`} value={item} onDelete={removeHistory} />));
} else {
if (doesExist(loading) === false) {
children.push(<Typography>No results. Press Generate.</Typography>);

View File

@ -14,10 +14,12 @@ const LOADING_PERCENT = 100;
const LOADING_OVERAGE = 99;
export interface LoadingCardProps {
index: number;
loading: ImageResponse;
}
export function LoadingCard(props: LoadingCardProps) {
const { index, loading } = props;
const { steps } = props.loading.params;
const client = mustExist(React.useContext(ClientContext));
@ -31,8 +33,8 @@ export function LoadingCard(props: LoadingCardProps) {
// eslint-disable-next-line @typescript-eslint/unbound-method
const setReady = useStore(state, (s) => s.setReady);
const cancel = useMutation(() => client.cancel(props.loading));
const ready = useQuery(`ready-${props.loading.output.key}`, () => client.ready(props.loading), {
const cancel = useMutation(() => client.cancel(loading.output[index].key));
const ready = useQuery(`ready-${loading.output[index].key}`, () => client.ready(loading.output[index].key), {
// data will always be ready without this, even if the API says its not
cacheTime: 0,
refetchInterval: POLL_TIME,

View File

@ -311,7 +311,7 @@ export function createStateSlices(server: ServerParams) {
clearLoading(image) {
set((prev) => ({
...prev,
loading: prev.loading.filter((it) => it.image.output.key !== image.output.key),
loading: prev.loading.filter((it) => it.image.output[0].key !== image.output[0].key),
}));
},
pushHistory(image) {
@ -321,7 +321,7 @@ export function createStateSlices(server: ServerParams) {
image,
...prev.history,
].slice(0, prev.limit + DEFAULT_HISTORY.scrollback),
loading: prev.loading.filter((it) => it.image.output.key !== image.output.key),
loading: prev.loading.filter((it) => it.image.output[0].key !== image.output[0].key),
}));
},
pushLoading(image) {
@ -354,7 +354,7 @@ export function createStateSlices(server: ServerParams) {
setReady(image, ready) {
set((prev) => {
const loading = [...prev.loading];
const idx = loading.findIndex((it) => it.image.output.key === image.output.key);
const idx = loading.findIndex((it) => it.image.output[0].key === image.output[0].key);
if (idx >= 0) {
loading[idx].ready = ready;
} else {