Skip to content

Commit

Permalink
feat: add version check to parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
ssube committed Jan 18, 2023
1 parent 4d9dc05 commit be3a17b
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 71 deletions.
1 change: 1 addition & 0 deletions api/params.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"version": "0.5.0",
"cfg": {
"default": 6,
"min": 1,
Expand Down
1 change: 1 addition & 0 deletions gui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-query": "^3.39.2",
"semver": "^7.3.8",
"tslib": "^2.4.1",
"zustand": "^4.3.1"
},
Expand Down
14 changes: 6 additions & 8 deletions gui/src/components/OnnxError.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { Alert, AlertTitle, Box, Container, Link, Stack, Typography } from '@mui/material';
import { Box, Container, Link, Stack, Typography } from '@mui/material';
import * as React from 'react';
import { ReactNode } from 'react';

export interface OnnxErrorProps {
children?: ReactNode;
root: string;
}

Expand All @@ -17,12 +19,8 @@ export function OnnxError(props: OnnxErrorProps) {
</Box>
<Box sx={{ my: 4 }}>
<Stack spacing={2}>
<Alert severity='error'>
<AlertTitle>
Server Error
</AlertTitle>
Could not fetch parameters from the ONNX web API server at <code>{props.root}</code>.
</Alert>
{props.children}

<Typography variant='body1'>
This is a web UI for running ONNX models with GPU acceleration or in software, running locally or on a
remote machine.
Expand Down Expand Up @@ -50,7 +48,7 @@ export function OnnxError(props: OnnxErrorProps) {
</Typography>
<Typography variant='body1' gutterBottom>
If your server is running and available at <a href={props.root}>{props.root}</a>, make sure you are on
the `main` branch and try updating to the latest version:
the <code>main</code> branch and try updating to the latest version:
<pre>
&gt; git branch{'\n'}
* main{'\n'}
Expand Down
24 changes: 24 additions & 0 deletions gui/src/components/error/ParamsVersion.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Alert, AlertTitle, Typography } from '@mui/material';
import * as React from 'react';
import { PARAM_VERSION } from '../../config';

export interface ParamsVersionErrorProps {
root: string;
version: string;
}

export function ParamsVersionError(props: ParamsVersionErrorProps) {
return <Alert severity='error'>
<AlertTitle>
Parameter Version Error
</AlertTitle>
<Typography>
The server returned parameters that are too old for the client to load.
</Typography>
<Typography>
The server parameters are version <code>{props.version}</code>, but this client's required version
is <code>{PARAM_VERSION}</code>. Please update your server or use a matching version of the client.
</Typography>
</Alert>;
}

31 changes: 31 additions & 0 deletions gui/src/components/error/ServerParams.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Alert, AlertTitle, Typography } from '@mui/material';
import * as React from 'react';

export interface ServerParamsErrorProps {
error: unknown;
root: string;
}

function getErrorMessage(error: unknown): string {
if (error instanceof Error) {
return error.message;
} else if (typeof error === 'string') {
return error;
} else {
return 'unknown error';
}
}

export function ServerParamsError(props: ServerParamsErrorProps) {
return <Alert severity='error'>
<AlertTitle>
Server Error
</AlertTitle>
<Typography>
Could not fetch parameters from the ONNX web API server at <code>{props.root}</code>.
</Typography>
<Typography>
{getErrorMessage(props.error)}
</Typography>
</Alert>;
}
7 changes: 6 additions & 1 deletion gui/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ export type ConfigParams = ConfigRanges<Required<
ModelParams &
OutpaintParams &
UpscaleParams
>>;
>> & {
version: string;
};
/* eslint-enable */

export interface Config {
Expand All @@ -57,7 +59,10 @@ export const DEFAULT_BRUSH = {
color: 255,
size: 8,
};

export const IMAGE_FILTER = '.bmp, .jpg, .jpeg, .png';
export const PARAM_VERSION = '>=0.4.0';

export const STALE_TIME = 300_000; // 5 minutes
export const POLL_TIME = 5_000; // 5 seconds
export const SAVE_TIME = 5_000; // 5 seconds
Expand Down
135 changes: 74 additions & 61 deletions gui/src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
/* eslint-disable no-console */
import { doesExist, mustExist } from '@apextoaster/js-utils';
import { doesExist, mustDefault, mustExist } from '@apextoaster/js-utils';
import { merge } from 'lodash';
import * as React from 'react';
import ReactDOM from 'react-dom/client';
import { QueryClient, QueryClientProvider } from 'react-query';
import { satisfies } from 'semver';
import { createStore } from 'zustand';
import { createJSONStorage, persist } from 'zustand/middleware';

import { makeClient } from './client.js';
import { ParamsVersionError } from './components/error/ParamsVersion.js';
import { ServerParamsError } from './components/error/ServerParams.js';
import { OnnxError } from './components/OnnxError.js';
import { OnnxWeb } from './components/OnnxWeb.js';
import { Config, loadConfig } from './config.js';
import { Config, loadConfig, PARAM_VERSION } from './config.js';
import { ClientContext, ConfigContext, createStateSlices, OnnxState, StateContext } from './state.js';

export function getApiRoot(config: Config): string {
Expand Down Expand Up @@ -39,69 +42,79 @@ export async function main() {
try {
// load full params from the API server and merge with the initial client config
const params = await client.params();
merge(params, config.params);
const version = mustDefault(params.version, '0.0.0');
if (satisfies(version, PARAM_VERSION)) {
// check version here
merge(params, config.params);

// prep zustand with a slice for each tab, using local storage
const {
createBrushSlice,
createDefaultSlice,
createHistorySlice,
createImg2ImgSlice,
createInpaintSlice,
createModelSlice,
createOutpaintSlice,
createTxt2ImgSlice,
createUpscaleSlice,
} = createStateSlices(params);
const state = createStore<OnnxState, [['zustand/persist', OnnxState]]>(persist((...slice) => ({
...createBrushSlice(...slice),
...createDefaultSlice(...slice),
...createHistorySlice(...slice),
...createImg2ImgSlice(...slice),
...createInpaintSlice(...slice),
...createModelSlice(...slice),
...createTxt2ImgSlice(...slice),
...createOutpaintSlice(...slice),
...createUpscaleSlice(...slice),
}), {
name: 'onnx-web',
partialize(s) {
return {
...s,
img2img: {
...s.img2img,
source: undefined,
},
inpaint: {
...s.inpaint,
mask: undefined,
source: undefined,
},
upscaleTab: {
...s.upscaleTab,
source: undefined,
},
};
},
storage: createJSONStorage(() => localStorage),
version: 3,
}));
// prep zustand with a slice for each tab, using local storage
const {
createBrushSlice,
createDefaultSlice,
createHistorySlice,
createImg2ImgSlice,
createInpaintSlice,
createModelSlice,
createOutpaintSlice,
createTxt2ImgSlice,
createUpscaleSlice,
} = createStateSlices(params);
const state = createStore<OnnxState, [['zustand/persist', OnnxState]]>(persist((...slice) => ({
...createBrushSlice(...slice),
...createDefaultSlice(...slice),
...createHistorySlice(...slice),
...createImg2ImgSlice(...slice),
...createInpaintSlice(...slice),
...createModelSlice(...slice),
...createTxt2ImgSlice(...slice),
...createOutpaintSlice(...slice),
...createUpscaleSlice(...slice),
}), {
name: 'onnx-web',
partialize(s) {
return {
...s,
img2img: {
...s.img2img,
source: undefined,
},
inpaint: {
...s.inpaint,
mask: undefined,
source: undefined,
},
upscaleTab: {
...s.upscaleTab,
source: undefined,
},
};
},
storage: createJSONStorage(() => localStorage),
version: 3,
}));

// prep react-query client
const query = new QueryClient();
// prep react-query client
const query = new QueryClient();

// go
app.render(<QueryClientProvider client={query}>
<ClientContext.Provider value={client}>
<ConfigContext.Provider value={params}>
<StateContext.Provider value={state}>
<OnnxWeb />
</StateContext.Provider>
</ConfigContext.Provider>
</ClientContext.Provider>
</QueryClientProvider>);
// go
app.render(<QueryClientProvider client={query}>
<ClientContext.Provider value={client}>
<ConfigContext.Provider value={params}>
<StateContext.Provider value={state}>
<OnnxWeb />
</StateContext.Provider>
</ConfigContext.Provider>
</ClientContext.Provider>
</QueryClientProvider>);
} else {
app.render(<OnnxError root={root}>
<ParamsVersionError root={root} version={version} />
</OnnxError>);
}
} catch (err) {
app.render(<OnnxError root={root} />);
app.render(<OnnxError root={root}>
<ServerParamsError root={root} error={err} />
</OnnxError>);
}
}

Expand Down
2 changes: 1 addition & 1 deletion gui/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2540,7 +2540,7 @@ semver@^6.0.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==

semver@^7.3.7:
semver@^7.3.7, semver@^7.3.8:
version "7.3.8"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798"
integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==
Expand Down

0 comments on commit be3a17b

Please sign in to comment.