mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
added route to install huggingface models from model marketplace (#6515)
## Summary added route to install huggingface models from model marketplace <!--A description of the changes in this PR. Include the kind of change (fix, feature, docs, etc), the "why" and the "how". Screenshots or videos are useful for frontend changes.--> ## Related Issues / Discussions <!--WHEN APPLICABLE: List any related issues or discussions on github or discord. If this PR closes an issue, please use the "Closes #1234" format, so that the issue will be automatically closed when the PR merges.--> ## QA Instructions test by going to http://localhost:5173/api/v2/models/install/huggingface?source=${hfRepo} <!--WHEN APPLICABLE: Describe how we can test the changes in this PR.--> ## Merge Plan <!--WHEN APPLICABLE: Large PRs, or PRs that touch sensitive things like DB schemas, may need some care when merging. For example, a careful rebase by the change author, timing to not interfere with a pending release, or a message to contributors on discord after merging.--> ## Checklist - [ ] _The PR has a short but descriptive title, suitable for a changelog_ - [ ] _Tests added / updated (if applicable)_ - [ ] _Documentation added / updated (if applicable)_
This commit is contained in:
commit
70e40fa6c1
@ -9,7 +9,7 @@ from copy import deepcopy
|
|||||||
from typing import Any, Dict, List, Optional, Type
|
from typing import Any, Dict, List, Optional, Type
|
||||||
|
|
||||||
from fastapi import Body, Path, Query, Response, UploadFile
|
from fastapi import Body, Path, Query, Response, UploadFile
|
||||||
from fastapi.responses import FileResponse
|
from fastapi.responses import FileResponse, HTMLResponse
|
||||||
from fastapi.routing import APIRouter
|
from fastapi.routing import APIRouter
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from pydantic import AnyHttpUrl, BaseModel, ConfigDict, Field
|
from pydantic import AnyHttpUrl, BaseModel, ConfigDict, Field
|
||||||
@ -502,6 +502,133 @@ async def install_model(
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
@model_manager_router.get(
|
||||||
|
"/install/huggingface",
|
||||||
|
operation_id="install_hugging_face_model",
|
||||||
|
responses={
|
||||||
|
201: {"description": "The model is being installed"},
|
||||||
|
400: {"description": "Bad request"},
|
||||||
|
409: {"description": "There is already a model corresponding to this path or repo_id"},
|
||||||
|
},
|
||||||
|
status_code=201,
|
||||||
|
response_class=HTMLResponse,
|
||||||
|
)
|
||||||
|
async def install_hugging_face_model(
|
||||||
|
source: str = Query(description="HuggingFace repo_id to install"),
|
||||||
|
) -> HTMLResponse:
|
||||||
|
"""Install a Hugging Face model using a string identifier."""
|
||||||
|
|
||||||
|
def generate_html(title: str, heading: str, repo_id: str, is_error: bool, message: str | None = "") -> str:
|
||||||
|
if message:
|
||||||
|
message = f"<p>{message}</p>"
|
||||||
|
title_class = "error" if is_error else "success"
|
||||||
|
return f"""
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>{title}</title>
|
||||||
|
<style>
|
||||||
|
body {{
|
||||||
|
text-align: center;
|
||||||
|
background-color: hsl(220 12% 10% / 1);
|
||||||
|
font-family: Helvetica, sans-serif;
|
||||||
|
color: hsl(220 12% 86% / 1);
|
||||||
|
}}
|
||||||
|
|
||||||
|
.repo-id {{
|
||||||
|
color: hsl(220 12% 68% / 1);
|
||||||
|
}}
|
||||||
|
|
||||||
|
.error {{
|
||||||
|
color: hsl(0 42% 68% / 1)
|
||||||
|
}}
|
||||||
|
|
||||||
|
.message-box {{
|
||||||
|
display: inline-block;
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: hsl(220 12% 20% / 1);
|
||||||
|
padding-inline-end: 30px;
|
||||||
|
padding: 20px;
|
||||||
|
padding-inline-start: 30px;
|
||||||
|
padding-inline-end: 30px;
|
||||||
|
}}
|
||||||
|
|
||||||
|
.container {{
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}}
|
||||||
|
|
||||||
|
a {{
|
||||||
|
color: inherit
|
||||||
|
}}
|
||||||
|
|
||||||
|
a:visited {{
|
||||||
|
color: inherit
|
||||||
|
}}
|
||||||
|
|
||||||
|
a:active {{
|
||||||
|
color: inherit
|
||||||
|
}}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body style="background-color: hsl(220 12% 10% / 1);">
|
||||||
|
<div class="container">
|
||||||
|
<div class="message-box">
|
||||||
|
<h2 class="{title_class}">{heading}</h2>
|
||||||
|
{message}
|
||||||
|
<p class="repo-id">Repo ID: {repo_id}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
metadata = HuggingFaceMetadataFetch().from_id(source)
|
||||||
|
assert isinstance(metadata, ModelMetadataWithFiles)
|
||||||
|
except UnknownMetadataException:
|
||||||
|
title = "Unable to Install Model"
|
||||||
|
heading = "No HuggingFace repository found with that repo ID."
|
||||||
|
message = "Ensure the repo ID is correct and try again."
|
||||||
|
return HTMLResponse(content=generate_html(title, heading, source, True, message), status_code=400)
|
||||||
|
|
||||||
|
logger = ApiDependencies.invoker.services.logger
|
||||||
|
|
||||||
|
try:
|
||||||
|
installer = ApiDependencies.invoker.services.model_manager.install
|
||||||
|
if metadata.is_diffusers:
|
||||||
|
installer.heuristic_import(
|
||||||
|
source=source,
|
||||||
|
inplace=False,
|
||||||
|
)
|
||||||
|
elif metadata.ckpt_urls is not None and len(metadata.ckpt_urls) == 1:
|
||||||
|
installer.heuristic_import(
|
||||||
|
source=str(metadata.ckpt_urls[0]),
|
||||||
|
inplace=False,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
title = "Unable to Install Model"
|
||||||
|
heading = "This HuggingFace repo has multiple models."
|
||||||
|
message = "Please use the Model Manager to install this model."
|
||||||
|
return HTMLResponse(content=generate_html(title, heading, source, True, message), status_code=200)
|
||||||
|
|
||||||
|
title = "Model Install Started"
|
||||||
|
heading = "Your HuggingFace model is installing now."
|
||||||
|
message = "You can close this tab and check the Model Manager for installation progress."
|
||||||
|
return HTMLResponse(content=generate_html(title, heading, source, False, message), status_code=201)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(str(e))
|
||||||
|
title = "Unable to Install Model"
|
||||||
|
heading = "There was an problem installing this model."
|
||||||
|
message = 'Please use the Model Manager directly to install this model. If the issue persists, ask for help on <a href="https://discord.gg/ZmtBAhwWhy">discord</a>.'
|
||||||
|
return HTMLResponse(content=generate_html(title, heading, source, True, message), status_code=500)
|
||||||
|
|
||||||
|
|
||||||
@model_manager_router.get(
|
@model_manager_router.get(
|
||||||
"/install",
|
"/install",
|
||||||
operation_id="list_model_installs",
|
operation_id="list_model_installs",
|
||||||
|
@ -22,6 +22,7 @@ from invokeai.app.services.events.events_common import (
|
|||||||
ModelInstallCompleteEvent,
|
ModelInstallCompleteEvent,
|
||||||
ModelInstallDownloadProgressEvent,
|
ModelInstallDownloadProgressEvent,
|
||||||
ModelInstallDownloadsCompleteEvent,
|
ModelInstallDownloadsCompleteEvent,
|
||||||
|
ModelInstallDownloadStartedEvent,
|
||||||
ModelInstallErrorEvent,
|
ModelInstallErrorEvent,
|
||||||
ModelInstallStartedEvent,
|
ModelInstallStartedEvent,
|
||||||
ModelLoadCompleteEvent,
|
ModelLoadCompleteEvent,
|
||||||
@ -144,6 +145,10 @@ class EventServiceBase:
|
|||||||
|
|
||||||
# region Model install
|
# region Model install
|
||||||
|
|
||||||
|
def emit_model_install_download_started(self, job: "ModelInstallJob") -> None:
|
||||||
|
"""Emitted at intervals while the install job is started (remote models only)."""
|
||||||
|
self.dispatch(ModelInstallDownloadStartedEvent.build(job))
|
||||||
|
|
||||||
def emit_model_install_download_progress(self, job: "ModelInstallJob") -> None:
|
def emit_model_install_download_progress(self, job: "ModelInstallJob") -> None:
|
||||||
"""Emitted at intervals while the install job is in progress (remote models only)."""
|
"""Emitted at intervals while the install job is in progress (remote models only)."""
|
||||||
self.dispatch(ModelInstallDownloadProgressEvent.build(job))
|
self.dispatch(ModelInstallDownloadProgressEvent.build(job))
|
||||||
|
@ -417,6 +417,42 @@ class ModelLoadCompleteEvent(ModelEventBase):
|
|||||||
return cls(config=config, submodel_type=submodel_type)
|
return cls(config=config, submodel_type=submodel_type)
|
||||||
|
|
||||||
|
|
||||||
|
@payload_schema.register
|
||||||
|
class ModelInstallDownloadStartedEvent(ModelEventBase):
|
||||||
|
"""Event model for model_install_download_started"""
|
||||||
|
|
||||||
|
__event_name__ = "model_install_download_started"
|
||||||
|
|
||||||
|
id: int = Field(description="The ID of the install job")
|
||||||
|
source: str = Field(description="Source of the model; local path, repo_id or url")
|
||||||
|
local_path: str = Field(description="Where model is downloading to")
|
||||||
|
bytes: int = Field(description="Number of bytes downloaded so far")
|
||||||
|
total_bytes: int = Field(description="Total size of download, including all files")
|
||||||
|
parts: list[dict[str, int | str]] = Field(
|
||||||
|
description="Progress of downloading URLs that comprise the model, if any"
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def build(cls, job: "ModelInstallJob") -> "ModelInstallDownloadStartedEvent":
|
||||||
|
parts: list[dict[str, str | int]] = [
|
||||||
|
{
|
||||||
|
"url": str(x.source),
|
||||||
|
"local_path": str(x.download_path),
|
||||||
|
"bytes": x.bytes,
|
||||||
|
"total_bytes": x.total_bytes,
|
||||||
|
}
|
||||||
|
for x in job.download_parts
|
||||||
|
]
|
||||||
|
return cls(
|
||||||
|
id=job.id,
|
||||||
|
source=str(job.source),
|
||||||
|
local_path=job.local_path.as_posix(),
|
||||||
|
parts=parts,
|
||||||
|
bytes=job.bytes,
|
||||||
|
total_bytes=job.total_bytes,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@payload_schema.register
|
@payload_schema.register
|
||||||
class ModelInstallDownloadProgressEvent(ModelEventBase):
|
class ModelInstallDownloadProgressEvent(ModelEventBase):
|
||||||
"""Event model for model_install_download_progress"""
|
"""Event model for model_install_download_progress"""
|
||||||
|
@ -822,7 +822,7 @@ class ModelInstallService(ModelInstallServiceBase):
|
|||||||
install_job.download_parts = download_job.download_parts
|
install_job.download_parts = download_job.download_parts
|
||||||
install_job.bytes = sum(x.bytes for x in download_job.download_parts)
|
install_job.bytes = sum(x.bytes for x in download_job.download_parts)
|
||||||
install_job.total_bytes = download_job.total_bytes
|
install_job.total_bytes = download_job.total_bytes
|
||||||
self._signal_job_downloading(install_job)
|
self._signal_job_download_started(install_job)
|
||||||
|
|
||||||
def _download_progress_callback(self, download_job: MultiFileDownloadJob) -> None:
|
def _download_progress_callback(self, download_job: MultiFileDownloadJob) -> None:
|
||||||
with self._lock:
|
with self._lock:
|
||||||
@ -874,6 +874,13 @@ class ModelInstallService(ModelInstallServiceBase):
|
|||||||
if self._event_bus:
|
if self._event_bus:
|
||||||
self._event_bus.emit_model_install_started(job)
|
self._event_bus.emit_model_install_started(job)
|
||||||
|
|
||||||
|
def _signal_job_download_started(self, job: ModelInstallJob) -> None:
|
||||||
|
if self._event_bus:
|
||||||
|
assert job._multifile_job is not None
|
||||||
|
assert job.bytes is not None
|
||||||
|
assert job.total_bytes is not None
|
||||||
|
self._event_bus.emit_model_install_download_started(job)
|
||||||
|
|
||||||
def _signal_job_downloading(self, job: ModelInstallJob) -> None:
|
def _signal_job_downloading(self, job: ModelInstallJob) -> None:
|
||||||
if self._event_bus:
|
if self._event_bus:
|
||||||
assert job._multifile_job is not None
|
assert job._multifile_job is not None
|
||||||
|
@ -5,15 +5,86 @@ import {
|
|||||||
socketModelInstallCancelled,
|
socketModelInstallCancelled,
|
||||||
socketModelInstallComplete,
|
socketModelInstallComplete,
|
||||||
socketModelInstallDownloadProgress,
|
socketModelInstallDownloadProgress,
|
||||||
|
socketModelInstallDownloadsComplete,
|
||||||
|
socketModelInstallDownloadStarted,
|
||||||
socketModelInstallError,
|
socketModelInstallError,
|
||||||
|
socketModelInstallStarted,
|
||||||
} from 'services/events/actions';
|
} from 'services/events/actions';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A model install has two main stages - downloading and installing. All these events are namespaced under `model_install_`
|
||||||
|
* which is a bit misleading. For example, a `model_install_started` event is actually fired _after_ the model has fully
|
||||||
|
* downloaded and is being "physically" installed.
|
||||||
|
*
|
||||||
|
* Note: the download events are only fired for remote model installs, not local.
|
||||||
|
*
|
||||||
|
* Here's the expected flow:
|
||||||
|
* - API receives install request, model manager preps the install
|
||||||
|
* - `model_install_download_started` fired when the download starts
|
||||||
|
* - `model_install_download_progress` fired continually until the download is complete
|
||||||
|
* - `model_install_download_complete` fired when the download is complete
|
||||||
|
* - `model_install_started` fired when the "physical" installation starts
|
||||||
|
* - `model_install_complete` fired when the installation is complete
|
||||||
|
* - `model_install_cancelled` fired if the installation is cancelled
|
||||||
|
* - `model_install_error` fired if the installation has an error
|
||||||
|
*/
|
||||||
|
|
||||||
|
const selectModelInstalls = modelsApi.endpoints.listModelInstalls.select();
|
||||||
|
|
||||||
export const addModelInstallEventListener = (startAppListening: AppStartListening) => {
|
export const addModelInstallEventListener = (startAppListening: AppStartListening) => {
|
||||||
startAppListening({
|
startAppListening({
|
||||||
actionCreator: socketModelInstallDownloadProgress,
|
actionCreator: socketModelInstallDownloadStarted,
|
||||||
effect: async (action, { dispatch }) => {
|
effect: async (action, { dispatch, getState }) => {
|
||||||
const { bytes, total_bytes, id } = action.payload.data;
|
const { id } = action.payload.data;
|
||||||
|
const { data } = selectModelInstalls(getState());
|
||||||
|
|
||||||
|
if (!data || !data.find((m) => m.id === id)) {
|
||||||
|
dispatch(api.util.invalidateTags([{ type: 'ModelInstalls' }]));
|
||||||
|
} else {
|
||||||
|
dispatch(
|
||||||
|
modelsApi.util.updateQueryData('listModelInstalls', undefined, (draft) => {
|
||||||
|
const modelImport = draft.find((m) => m.id === id);
|
||||||
|
if (modelImport) {
|
||||||
|
modelImport.status = 'downloading';
|
||||||
|
}
|
||||||
|
return draft;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
startAppListening({
|
||||||
|
actionCreator: socketModelInstallStarted,
|
||||||
|
effect: async (action, { dispatch, getState }) => {
|
||||||
|
const { id } = action.payload.data;
|
||||||
|
const { data } = selectModelInstalls(getState());
|
||||||
|
|
||||||
|
if (!data || !data.find((m) => m.id === id)) {
|
||||||
|
dispatch(api.util.invalidateTags([{ type: 'ModelInstalls' }]));
|
||||||
|
} else {
|
||||||
|
dispatch(
|
||||||
|
modelsApi.util.updateQueryData('listModelInstalls', undefined, (draft) => {
|
||||||
|
const modelImport = draft.find((m) => m.id === id);
|
||||||
|
if (modelImport) {
|
||||||
|
modelImport.status = 'running';
|
||||||
|
}
|
||||||
|
return draft;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
startAppListening({
|
||||||
|
actionCreator: socketModelInstallDownloadProgress,
|
||||||
|
effect: async (action, { dispatch, getState }) => {
|
||||||
|
const { bytes, total_bytes, id } = action.payload.data;
|
||||||
|
const { data } = selectModelInstalls(getState());
|
||||||
|
|
||||||
|
if (!data || !data.find((m) => m.id === id)) {
|
||||||
|
dispatch(api.util.invalidateTags([{ type: 'ModelInstalls' }]));
|
||||||
|
} else {
|
||||||
dispatch(
|
dispatch(
|
||||||
modelsApi.util.updateQueryData('listModelInstalls', undefined, (draft) => {
|
modelsApi.util.updateQueryData('listModelInstalls', undefined, (draft) => {
|
||||||
const modelImport = draft.find((m) => m.id === id);
|
const modelImport = draft.find((m) => m.id === id);
|
||||||
@ -25,14 +96,20 @@ export const addModelInstallEventListener = (startAppListening: AppStartListenin
|
|||||||
return draft;
|
return draft;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
startAppListening({
|
startAppListening({
|
||||||
actionCreator: socketModelInstallComplete,
|
actionCreator: socketModelInstallComplete,
|
||||||
effect: (action, { dispatch }) => {
|
effect: (action, { dispatch, getState }) => {
|
||||||
const { id } = action.payload.data;
|
const { id } = action.payload.data;
|
||||||
|
|
||||||
|
const { data } = selectModelInstalls(getState());
|
||||||
|
|
||||||
|
if (!data || !data.find((m) => m.id === id)) {
|
||||||
|
dispatch(api.util.invalidateTags([{ type: 'ModelInstalls' }]));
|
||||||
|
} else {
|
||||||
dispatch(
|
dispatch(
|
||||||
modelsApi.util.updateQueryData('listModelInstalls', undefined, (draft) => {
|
modelsApi.util.updateQueryData('listModelInstalls', undefined, (draft) => {
|
||||||
const modelImport = draft.find((m) => m.id === id);
|
const modelImport = draft.find((m) => m.id === id);
|
||||||
@ -42,6 +119,8 @@ export const addModelInstallEventListener = (startAppListening: AppStartListenin
|
|||||||
return draft;
|
return draft;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
dispatch(api.util.invalidateTags([{ type: 'ModelConfig', id: LIST_TAG }]));
|
dispatch(api.util.invalidateTags([{ type: 'ModelConfig', id: LIST_TAG }]));
|
||||||
dispatch(api.util.invalidateTags([{ type: 'ModelScanFolderResults', id: LIST_TAG }]));
|
dispatch(api.util.invalidateTags([{ type: 'ModelScanFolderResults', id: LIST_TAG }]));
|
||||||
},
|
},
|
||||||
@ -49,9 +128,13 @@ export const addModelInstallEventListener = (startAppListening: AppStartListenin
|
|||||||
|
|
||||||
startAppListening({
|
startAppListening({
|
||||||
actionCreator: socketModelInstallError,
|
actionCreator: socketModelInstallError,
|
||||||
effect: (action, { dispatch }) => {
|
effect: (action, { dispatch, getState }) => {
|
||||||
const { id, error, error_type } = action.payload.data;
|
const { id, error, error_type } = action.payload.data;
|
||||||
|
const { data } = selectModelInstalls(getState());
|
||||||
|
|
||||||
|
if (!data || !data.find((m) => m.id === id)) {
|
||||||
|
dispatch(api.util.invalidateTags([{ type: 'ModelInstalls' }]));
|
||||||
|
} else {
|
||||||
dispatch(
|
dispatch(
|
||||||
modelsApi.util.updateQueryData('listModelInstalls', undefined, (draft) => {
|
modelsApi.util.updateQueryData('listModelInstalls', undefined, (draft) => {
|
||||||
const modelImport = draft.find((m) => m.id === id);
|
const modelImport = draft.find((m) => m.id === id);
|
||||||
@ -63,14 +146,19 @@ export const addModelInstallEventListener = (startAppListening: AppStartListenin
|
|||||||
return draft;
|
return draft;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
startAppListening({
|
startAppListening({
|
||||||
actionCreator: socketModelInstallCancelled,
|
actionCreator: socketModelInstallCancelled,
|
||||||
effect: (action, { dispatch }) => {
|
effect: (action, { dispatch, getState }) => {
|
||||||
const { id } = action.payload.data;
|
const { id } = action.payload.data;
|
||||||
|
const { data } = selectModelInstalls(getState());
|
||||||
|
|
||||||
|
if (!data || !data.find((m) => m.id === id)) {
|
||||||
|
dispatch(api.util.invalidateTags([{ type: 'ModelInstalls' }]));
|
||||||
|
} else {
|
||||||
dispatch(
|
dispatch(
|
||||||
modelsApi.util.updateQueryData('listModelInstalls', undefined, (draft) => {
|
modelsApi.util.updateQueryData('listModelInstalls', undefined, (draft) => {
|
||||||
const modelImport = draft.find((m) => m.id === id);
|
const modelImport = draft.find((m) => m.id === id);
|
||||||
@ -80,6 +168,29 @@ export const addModelInstallEventListener = (startAppListening: AppStartListenin
|
|||||||
return draft;
|
return draft;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
startAppListening({
|
||||||
|
actionCreator: socketModelInstallDownloadsComplete,
|
||||||
|
effect: (action, { dispatch, getState }) => {
|
||||||
|
const { id } = action.payload.data;
|
||||||
|
const { data } = selectModelInstalls(getState());
|
||||||
|
|
||||||
|
if (!data || !data.find((m) => m.id === id)) {
|
||||||
|
dispatch(api.util.invalidateTags([{ type: 'ModelInstalls' }]));
|
||||||
|
} else {
|
||||||
|
dispatch(
|
||||||
|
modelsApi.util.updateQueryData('listModelInstalls', undefined, (draft) => {
|
||||||
|
const modelImport = draft.find((m) => m.id === id);
|
||||||
|
if (modelImport) {
|
||||||
|
modelImport.status = 'downloads_done';
|
||||||
|
}
|
||||||
|
return draft;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -123,6 +123,13 @@ export type paths = {
|
|||||||
*/
|
*/
|
||||||
delete: operations["prune_model_install_jobs"];
|
delete: operations["prune_model_install_jobs"];
|
||||||
};
|
};
|
||||||
|
"/api/v2/models/install/huggingface": {
|
||||||
|
/**
|
||||||
|
* Install Hugging Face Model
|
||||||
|
* @description Install a Hugging Face model using a string identifier.
|
||||||
|
*/
|
||||||
|
get: operations["install_hugging_face_model"];
|
||||||
|
};
|
||||||
"/api/v2/models/install/{id}": {
|
"/api/v2/models/install/{id}": {
|
||||||
/**
|
/**
|
||||||
* Get Model Install Job
|
* Get Model Install Job
|
||||||
@ -3788,23 +3795,6 @@ export type components = {
|
|||||||
* @description Class to monitor and control a model download request.
|
* @description Class to monitor and control a model download request.
|
||||||
*/
|
*/
|
||||||
DownloadJob: {
|
DownloadJob: {
|
||||||
/**
|
|
||||||
* Source
|
|
||||||
* Format: uri
|
|
||||||
* @description Where to download from. Specific types specified in child classes.
|
|
||||||
*/
|
|
||||||
source: string;
|
|
||||||
/**
|
|
||||||
* Dest
|
|
||||||
* Format: path
|
|
||||||
* @description Destination of downloaded model on local disk; a directory or file path
|
|
||||||
*/
|
|
||||||
dest: string;
|
|
||||||
/**
|
|
||||||
* Access Token
|
|
||||||
* @description authorization token for protected resources
|
|
||||||
*/
|
|
||||||
access_token?: string | null;
|
|
||||||
/**
|
/**
|
||||||
* Id
|
* Id
|
||||||
* @description Numeric ID of this job
|
* @description Numeric ID of this job
|
||||||
@ -3812,36 +3802,21 @@ export type components = {
|
|||||||
*/
|
*/
|
||||||
id?: number;
|
id?: number;
|
||||||
/**
|
/**
|
||||||
* Priority
|
* Dest
|
||||||
* @description Queue priority; lower values are higher priority
|
* Format: path
|
||||||
* @default 10
|
* @description Initial destination of downloaded model on local disk; a directory or file path
|
||||||
*/
|
*/
|
||||||
priority?: number;
|
dest: string;
|
||||||
|
/**
|
||||||
|
* Download Path
|
||||||
|
* @description Final location of downloaded file or directory
|
||||||
|
*/
|
||||||
|
download_path?: string | null;
|
||||||
/**
|
/**
|
||||||
* @description Status of the download
|
* @description Status of the download
|
||||||
* @default waiting
|
* @default waiting
|
||||||
*/
|
*/
|
||||||
status?: components["schemas"]["DownloadJobStatus"];
|
status?: components["schemas"]["DownloadJobStatus"];
|
||||||
/**
|
|
||||||
* Download Path
|
|
||||||
* @description Final location of downloaded file
|
|
||||||
*/
|
|
||||||
download_path?: string | null;
|
|
||||||
/**
|
|
||||||
* Job Started
|
|
||||||
* @description Timestamp for when the download job started
|
|
||||||
*/
|
|
||||||
job_started?: string | null;
|
|
||||||
/**
|
|
||||||
* Job Ended
|
|
||||||
* @description Timestamp for when the download job ende1d (completed or errored)
|
|
||||||
*/
|
|
||||||
job_ended?: string | null;
|
|
||||||
/**
|
|
||||||
* Content Type
|
|
||||||
* @description Content type of downloaded file
|
|
||||||
*/
|
|
||||||
content_type?: string | null;
|
|
||||||
/**
|
/**
|
||||||
* Bytes
|
* Bytes
|
||||||
* @description Bytes downloaded so far
|
* @description Bytes downloaded so far
|
||||||
@ -3864,6 +3839,38 @@ export type components = {
|
|||||||
* @description Traceback of the exception that caused an error
|
* @description Traceback of the exception that caused an error
|
||||||
*/
|
*/
|
||||||
error?: string | null;
|
error?: string | null;
|
||||||
|
/**
|
||||||
|
* Source
|
||||||
|
* Format: uri
|
||||||
|
* @description Where to download from. Specific types specified in child classes.
|
||||||
|
*/
|
||||||
|
source: string;
|
||||||
|
/**
|
||||||
|
* Access Token
|
||||||
|
* @description authorization token for protected resources
|
||||||
|
*/
|
||||||
|
access_token?: string | null;
|
||||||
|
/**
|
||||||
|
* Priority
|
||||||
|
* @description Queue priority; lower values are higher priority
|
||||||
|
* @default 10
|
||||||
|
*/
|
||||||
|
priority?: number;
|
||||||
|
/**
|
||||||
|
* Job Started
|
||||||
|
* @description Timestamp for when the download job started
|
||||||
|
*/
|
||||||
|
job_started?: string | null;
|
||||||
|
/**
|
||||||
|
* Job Ended
|
||||||
|
* @description Timestamp for when the download job ende1d (completed or errored)
|
||||||
|
*/
|
||||||
|
job_ended?: string | null;
|
||||||
|
/**
|
||||||
|
* Content Type
|
||||||
|
* @description Content type of downloaded file
|
||||||
|
*/
|
||||||
|
content_type?: string | null;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* DownloadJobStatus
|
* DownloadJobStatus
|
||||||
@ -7276,144 +7283,144 @@ export type components = {
|
|||||||
project_id: string | null;
|
project_id: string | null;
|
||||||
};
|
};
|
||||||
InvocationOutputMap: {
|
InvocationOutputMap: {
|
||||||
pidi_image_processor: components["schemas"]["ImageOutput"];
|
|
||||||
image_mask_to_tensor: components["schemas"]["MaskOutput"];
|
|
||||||
vae_loader: components["schemas"]["VAEOutput"];
|
|
||||||
collect: components["schemas"]["CollectInvocationOutput"];
|
|
||||||
string_join_three: components["schemas"]["StringOutput"];
|
|
||||||
content_shuffle_image_processor: components["schemas"]["ImageOutput"];
|
|
||||||
random_range: components["schemas"]["IntegerCollectionOutput"];
|
|
||||||
ip_adapter: components["schemas"]["IPAdapterOutput"];
|
|
||||||
step_param_easing: components["schemas"]["FloatCollectionOutput"];
|
|
||||||
core_metadata: components["schemas"]["MetadataOutput"];
|
|
||||||
main_model_loader: components["schemas"]["ModelLoaderOutput"];
|
|
||||||
leres_image_processor: components["schemas"]["ImageOutput"];
|
|
||||||
calculate_image_tiles_even_split: components["schemas"]["CalculateImageTilesOutput"];
|
|
||||||
color_correct: components["schemas"]["ImageOutput"];
|
|
||||||
calculate_image_tiles: components["schemas"]["CalculateImageTilesOutput"];
|
|
||||||
float_range: components["schemas"]["FloatCollectionOutput"];
|
|
||||||
infill_cv2: components["schemas"]["ImageOutput"];
|
|
||||||
img_channel_multiply: components["schemas"]["ImageOutput"];
|
|
||||||
img_pad_crop: components["schemas"]["ImageOutput"];
|
|
||||||
sdxl_refiner_compel_prompt: components["schemas"]["ConditioningOutput"];
|
|
||||||
face_mask_detection: components["schemas"]["FaceMaskOutput"];
|
|
||||||
infill_lama: components["schemas"]["ImageOutput"];
|
|
||||||
mask_combine: components["schemas"]["ImageOutput"];
|
|
||||||
sdxl_compel_prompt: components["schemas"]["ConditioningOutput"];
|
|
||||||
segment_anything_processor: components["schemas"]["ImageOutput"];
|
|
||||||
merge_metadata: components["schemas"]["MetadataOutput"];
|
|
||||||
img_ilerp: components["schemas"]["ImageOutput"];
|
|
||||||
heuristic_resize: components["schemas"]["ImageOutput"];
|
|
||||||
cv_inpaint: components["schemas"]["ImageOutput"];
|
|
||||||
div: components["schemas"]["IntegerOutput"];
|
|
||||||
pair_tile_image: components["schemas"]["PairTileImageOutput"];
|
|
||||||
float_math: components["schemas"]["FloatOutput"];
|
|
||||||
img_channel_offset: components["schemas"]["ImageOutput"];
|
|
||||||
canvas_paste_back: components["schemas"]["ImageOutput"];
|
|
||||||
canny_image_processor: components["schemas"]["ImageOutput"];
|
|
||||||
integer_collection: components["schemas"]["IntegerCollectionOutput"];
|
|
||||||
freeu: components["schemas"]["UNetOutput"];
|
|
||||||
lresize: components["schemas"]["LatentsOutput"];
|
|
||||||
range_of_size: components["schemas"]["IntegerCollectionOutput"];
|
|
||||||
depth_anything_image_processor: components["schemas"]["ImageOutput"];
|
|
||||||
float_to_int: components["schemas"]["IntegerOutput"];
|
|
||||||
rand_int: components["schemas"]["IntegerOutput"];
|
|
||||||
lineart_anime_image_processor: components["schemas"]["ImageOutput"];
|
|
||||||
string_split: components["schemas"]["String2Output"];
|
|
||||||
img_nsfw: components["schemas"]["ImageOutput"];
|
|
||||||
string: components["schemas"]["StringOutput"];
|
|
||||||
mask_edge: components["schemas"]["ImageOutput"];
|
|
||||||
i2l: components["schemas"]["LatentsOutput"];
|
|
||||||
face_identifier: components["schemas"]["ImageOutput"];
|
|
||||||
compel: components["schemas"]["ConditioningOutput"];
|
|
||||||
esrgan: components["schemas"]["ImageOutput"];
|
|
||||||
seamless: components["schemas"]["SeamlessModeOutput"];
|
|
||||||
mask_from_id: components["schemas"]["ImageOutput"];
|
|
||||||
invert_tensor_mask: components["schemas"]["MaskOutput"];
|
|
||||||
rectangle_mask: components["schemas"]["MaskOutput"];
|
|
||||||
conditioning: components["schemas"]["ConditioningOutput"];
|
|
||||||
t2i_adapter: components["schemas"]["T2IAdapterOutput"];
|
|
||||||
string_collection: components["schemas"]["StringCollectionOutput"];
|
|
||||||
show_image: components["schemas"]["ImageOutput"];
|
|
||||||
dw_openpose_image_processor: components["schemas"]["ImageOutput"];
|
|
||||||
string_split_neg: components["schemas"]["StringPosNegOutput"];
|
|
||||||
conditioning_collection: components["schemas"]["ConditioningCollectionOutput"];
|
|
||||||
infill_patchmatch: components["schemas"]["ImageOutput"];
|
|
||||||
img_conv: components["schemas"]["ImageOutput"];
|
|
||||||
unsharp_mask: components["schemas"]["ImageOutput"];
|
|
||||||
metadata_item: components["schemas"]["MetadataItemOutput"];
|
|
||||||
image: components["schemas"]["ImageOutput"];
|
|
||||||
image_collection: components["schemas"]["ImageCollectionOutput"];
|
|
||||||
tile_to_properties: components["schemas"]["TileToPropertiesOutput"];
|
|
||||||
lblend: components["schemas"]["LatentsOutput"];
|
|
||||||
float: components["schemas"]["FloatOutput"];
|
|
||||||
boolean_collection: components["schemas"]["BooleanCollectionOutput"];
|
|
||||||
color: components["schemas"]["ColorOutput"];
|
|
||||||
midas_depth_image_processor: components["schemas"]["ImageOutput"];
|
midas_depth_image_processor: components["schemas"]["ImageOutput"];
|
||||||
zoe_depth_image_processor: components["schemas"]["ImageOutput"];
|
lscale: components["schemas"]["LatentsOutput"];
|
||||||
infill_rgba: components["schemas"]["ImageOutput"];
|
string_split: components["schemas"]["String2Output"];
|
||||||
mlsd_image_processor: components["schemas"]["ImageOutput"];
|
mask_edge: components["schemas"]["ImageOutput"];
|
||||||
|
content_shuffle_image_processor: components["schemas"]["ImageOutput"];
|
||||||
|
color_correct: components["schemas"]["ImageOutput"];
|
||||||
|
save_image: components["schemas"]["ImageOutput"];
|
||||||
|
show_image: components["schemas"]["ImageOutput"];
|
||||||
|
segment_anything_processor: components["schemas"]["ImageOutput"];
|
||||||
|
latents: components["schemas"]["LatentsOutput"];
|
||||||
|
lineart_image_processor: components["schemas"]["ImageOutput"];
|
||||||
|
hed_image_processor: components["schemas"]["ImageOutput"];
|
||||||
|
infill_lama: components["schemas"]["ImageOutput"];
|
||||||
|
infill_patchmatch: components["schemas"]["ImageOutput"];
|
||||||
|
float_collection: components["schemas"]["FloatCollectionOutput"];
|
||||||
|
denoise_latents: components["schemas"]["LatentsOutput"];
|
||||||
|
metadata: components["schemas"]["MetadataOutput"];
|
||||||
|
compel: components["schemas"]["ConditioningOutput"];
|
||||||
|
img_blur: components["schemas"]["ImageOutput"];
|
||||||
|
img_crop: components["schemas"]["ImageOutput"];
|
||||||
|
sdxl_lora_collection_loader: components["schemas"]["SDXLLoRALoaderOutput"];
|
||||||
|
img_ilerp: components["schemas"]["ImageOutput"];
|
||||||
|
img_paste: components["schemas"]["ImageOutput"];
|
||||||
|
core_metadata: components["schemas"]["MetadataOutput"];
|
||||||
|
lora_collection_loader: components["schemas"]["LoRALoaderOutput"];
|
||||||
|
lora_selector: components["schemas"]["LoRASelectorOutput"];
|
||||||
|
create_denoise_mask: components["schemas"]["DenoiseMaskOutput"];
|
||||||
|
rectangle_mask: components["schemas"]["MaskOutput"];
|
||||||
|
noise: components["schemas"]["NoiseOutput"];
|
||||||
|
float_to_int: components["schemas"]["IntegerOutput"];
|
||||||
|
esrgan: components["schemas"]["ImageOutput"];
|
||||||
merge_tiles_to_image: components["schemas"]["ImageOutput"];
|
merge_tiles_to_image: components["schemas"]["ImageOutput"];
|
||||||
prompt_from_file: components["schemas"]["StringCollectionOutput"];
|
prompt_from_file: components["schemas"]["StringCollectionOutput"];
|
||||||
boolean: components["schemas"]["BooleanOutput"];
|
infill_rgba: components["schemas"]["ImageOutput"];
|
||||||
create_gradient_mask: components["schemas"]["GradientMaskOutput"];
|
|
||||||
rand_float: components["schemas"]["FloatOutput"];
|
|
||||||
img_mul: components["schemas"]["ImageOutput"];
|
|
||||||
controlnet: components["schemas"]["ControlOutput"];
|
|
||||||
latents_collection: components["schemas"]["LatentsCollectionOutput"];
|
|
||||||
img_lerp: components["schemas"]["ImageOutput"];
|
|
||||||
noise: components["schemas"]["NoiseOutput"];
|
|
||||||
iterate: components["schemas"]["IterateInvocationOutput"];
|
|
||||||
lineart_image_processor: components["schemas"]["ImageOutput"];
|
|
||||||
tomask: components["schemas"]["ImageOutput"];
|
|
||||||
integer: components["schemas"]["IntegerOutput"];
|
|
||||||
create_denoise_mask: components["schemas"]["DenoiseMaskOutput"];
|
|
||||||
clip_skip: components["schemas"]["CLIPSkipInvocationOutput"];
|
|
||||||
denoise_latents: components["schemas"]["LatentsOutput"];
|
|
||||||
string_join: components["schemas"]["StringOutput"];
|
|
||||||
scheduler: components["schemas"]["SchedulerOutput"];
|
|
||||||
model_identifier: components["schemas"]["ModelIdentifierOutput"];
|
|
||||||
normalbae_image_processor: components["schemas"]["ImageOutput"];
|
|
||||||
face_off: components["schemas"]["FaceOffOutput"];
|
|
||||||
hed_image_processor: components["schemas"]["ImageOutput"];
|
|
||||||
img_paste: components["schemas"]["ImageOutput"];
|
|
||||||
img_chan: components["schemas"]["ImageOutput"];
|
|
||||||
img_watermark: components["schemas"]["ImageOutput"];
|
|
||||||
l2i: components["schemas"]["ImageOutput"];
|
|
||||||
string_replace: components["schemas"]["StringOutput"];
|
|
||||||
color_map_image_processor: components["schemas"]["ImageOutput"];
|
|
||||||
tile_image_processor: components["schemas"]["ImageOutput"];
|
|
||||||
crop_latents: components["schemas"]["LatentsOutput"];
|
|
||||||
sdxl_lora_collection_loader: components["schemas"]["SDXLLoRALoaderOutput"];
|
|
||||||
add: components["schemas"]["IntegerOutput"];
|
|
||||||
sub: components["schemas"]["IntegerOutput"];
|
|
||||||
img_scale: components["schemas"]["ImageOutput"];
|
|
||||||
range: components["schemas"]["IntegerCollectionOutput"];
|
|
||||||
dynamic_prompt: components["schemas"]["StringCollectionOutput"];
|
|
||||||
img_crop: components["schemas"]["ImageOutput"];
|
|
||||||
infill_tile: components["schemas"]["ImageOutput"];
|
|
||||||
img_resize: components["schemas"]["ImageOutput"];
|
|
||||||
mediapipe_face_processor: components["schemas"]["ImageOutput"];
|
|
||||||
sdxl_model_loader: components["schemas"]["SDXLModelLoaderOutput"];
|
|
||||||
lora_selector: components["schemas"]["LoRASelectorOutput"];
|
|
||||||
img_hue_adjust: components["schemas"]["ImageOutput"];
|
|
||||||
latents: components["schemas"]["LatentsOutput"];
|
|
||||||
lora_collection_loader: components["schemas"]["LoRALoaderOutput"];
|
|
||||||
img_blur: components["schemas"]["ImageOutput"];
|
|
||||||
ideal_size: components["schemas"]["IdealSizeOutput"];
|
|
||||||
float_collection: components["schemas"]["FloatCollectionOutput"];
|
|
||||||
blank_image: components["schemas"]["ImageOutput"];
|
|
||||||
integer_math: components["schemas"]["IntegerOutput"];
|
|
||||||
lora_loader: components["schemas"]["LoRALoaderOutput"];
|
|
||||||
metadata: components["schemas"]["MetadataOutput"];
|
|
||||||
sdxl_lora_loader: components["schemas"]["SDXLLoRALoaderOutput"];
|
sdxl_lora_loader: components["schemas"]["SDXLLoRALoaderOutput"];
|
||||||
round_float: components["schemas"]["FloatOutput"];
|
lora_loader: components["schemas"]["LoRALoaderOutput"];
|
||||||
sdxl_refiner_model_loader: components["schemas"]["SDXLRefinerModelLoaderOutput"];
|
iterate: components["schemas"]["IterateInvocationOutput"];
|
||||||
mul: components["schemas"]["IntegerOutput"];
|
t2i_adapter: components["schemas"]["T2IAdapterOutput"];
|
||||||
alpha_mask_to_tensor: components["schemas"]["MaskOutput"];
|
color_map_image_processor: components["schemas"]["ImageOutput"];
|
||||||
lscale: components["schemas"]["LatentsOutput"];
|
blank_image: components["schemas"]["ImageOutput"];
|
||||||
save_image: components["schemas"]["ImageOutput"];
|
normalbae_image_processor: components["schemas"]["ImageOutput"];
|
||||||
|
canvas_paste_back: components["schemas"]["ImageOutput"];
|
||||||
|
string_split_neg: components["schemas"]["StringPosNegOutput"];
|
||||||
|
img_channel_offset: components["schemas"]["ImageOutput"];
|
||||||
|
face_mask_detection: components["schemas"]["FaceMaskOutput"];
|
||||||
|
cv_inpaint: components["schemas"]["ImageOutput"];
|
||||||
|
clip_skip: components["schemas"]["CLIPSkipInvocationOutput"];
|
||||||
|
invert_tensor_mask: components["schemas"]["MaskOutput"];
|
||||||
|
tomask: components["schemas"]["ImageOutput"];
|
||||||
|
main_model_loader: components["schemas"]["ModelLoaderOutput"];
|
||||||
|
img_watermark: components["schemas"]["ImageOutput"];
|
||||||
|
img_pad_crop: components["schemas"]["ImageOutput"];
|
||||||
|
random_range: components["schemas"]["IntegerCollectionOutput"];
|
||||||
|
mlsd_image_processor: components["schemas"]["ImageOutput"];
|
||||||
|
merge_metadata: components["schemas"]["MetadataOutput"];
|
||||||
|
string_join: components["schemas"]["StringOutput"];
|
||||||
|
vae_loader: components["schemas"]["VAEOutput"];
|
||||||
|
calculate_image_tiles_even_split: components["schemas"]["CalculateImageTilesOutput"];
|
||||||
calculate_image_tiles_min_overlap: components["schemas"]["CalculateImageTilesOutput"];
|
calculate_image_tiles_min_overlap: components["schemas"]["CalculateImageTilesOutput"];
|
||||||
|
mask_from_id: components["schemas"]["ImageOutput"];
|
||||||
|
zoe_depth_image_processor: components["schemas"]["ImageOutput"];
|
||||||
|
img_resize: components["schemas"]["ImageOutput"];
|
||||||
|
string_replace: components["schemas"]["StringOutput"];
|
||||||
|
face_identifier: components["schemas"]["ImageOutput"];
|
||||||
|
canny_image_processor: components["schemas"]["ImageOutput"];
|
||||||
|
collect: components["schemas"]["CollectInvocationOutput"];
|
||||||
|
infill_tile: components["schemas"]["ImageOutput"];
|
||||||
|
integer_collection: components["schemas"]["IntegerCollectionOutput"];
|
||||||
|
img_lerp: components["schemas"]["ImageOutput"];
|
||||||
|
step_param_easing: components["schemas"]["FloatCollectionOutput"];
|
||||||
|
lresize: components["schemas"]["LatentsOutput"];
|
||||||
|
img_mul: components["schemas"]["ImageOutput"];
|
||||||
|
create_gradient_mask: components["schemas"]["GradientMaskOutput"];
|
||||||
|
img_scale: components["schemas"]["ImageOutput"];
|
||||||
|
rand_float: components["schemas"]["FloatOutput"];
|
||||||
|
tile_to_properties: components["schemas"]["TileToPropertiesOutput"];
|
||||||
|
calculate_image_tiles: components["schemas"]["CalculateImageTilesOutput"];
|
||||||
|
range_of_size: components["schemas"]["IntegerCollectionOutput"];
|
||||||
|
sdxl_refiner_model_loader: components["schemas"]["SDXLRefinerModelLoaderOutput"];
|
||||||
|
heuristic_resize: components["schemas"]["ImageOutput"];
|
||||||
|
controlnet: components["schemas"]["ControlOutput"];
|
||||||
|
string: components["schemas"]["StringOutput"];
|
||||||
|
tile_image_processor: components["schemas"]["ImageOutput"];
|
||||||
|
metadata_item: components["schemas"]["MetadataItemOutput"];
|
||||||
|
freeu: components["schemas"]["UNetOutput"];
|
||||||
|
round_float: components["schemas"]["FloatOutput"];
|
||||||
|
conditioning: components["schemas"]["ConditioningOutput"];
|
||||||
|
ideal_size: components["schemas"]["IdealSizeOutput"];
|
||||||
|
float: components["schemas"]["FloatOutput"];
|
||||||
|
conditioning_collection: components["schemas"]["ConditioningCollectionOutput"];
|
||||||
|
alpha_mask_to_tensor: components["schemas"]["MaskOutput"];
|
||||||
|
integer_math: components["schemas"]["IntegerOutput"];
|
||||||
|
string_collection: components["schemas"]["StringCollectionOutput"];
|
||||||
|
img_conv: components["schemas"]["ImageOutput"];
|
||||||
|
img_channel_multiply: components["schemas"]["ImageOutput"];
|
||||||
|
lblend: components["schemas"]["LatentsOutput"];
|
||||||
|
color: components["schemas"]["ColorOutput"];
|
||||||
|
image: components["schemas"]["ImageOutput"];
|
||||||
|
sdxl_model_loader: components["schemas"]["SDXLModelLoaderOutput"];
|
||||||
|
image_collection: components["schemas"]["ImageCollectionOutput"];
|
||||||
|
model_identifier: components["schemas"]["ModelIdentifierOutput"];
|
||||||
|
l2i: components["schemas"]["ImageOutput"];
|
||||||
|
seamless: components["schemas"]["SeamlessModeOutput"];
|
||||||
|
boolean_collection: components["schemas"]["BooleanCollectionOutput"];
|
||||||
|
string_join_three: components["schemas"]["StringOutput"];
|
||||||
|
ip_adapter: components["schemas"]["IPAdapterOutput"];
|
||||||
|
add: components["schemas"]["IntegerOutput"];
|
||||||
|
crop_latents: components["schemas"]["LatentsOutput"];
|
||||||
|
float_range: components["schemas"]["FloatCollectionOutput"];
|
||||||
|
mul: components["schemas"]["IntegerOutput"];
|
||||||
|
dw_openpose_image_processor: components["schemas"]["ImageOutput"];
|
||||||
|
boolean: components["schemas"]["BooleanOutput"];
|
||||||
|
dynamic_prompt: components["schemas"]["StringCollectionOutput"];
|
||||||
|
mediapipe_face_processor: components["schemas"]["ImageOutput"];
|
||||||
|
i2l: components["schemas"]["LatentsOutput"];
|
||||||
|
latents_collection: components["schemas"]["LatentsCollectionOutput"];
|
||||||
|
integer: components["schemas"]["IntegerOutput"];
|
||||||
|
img_chan: components["schemas"]["ImageOutput"];
|
||||||
|
pair_tile_image: components["schemas"]["PairTileImageOutput"];
|
||||||
|
unsharp_mask: components["schemas"]["ImageOutput"];
|
||||||
|
img_hue_adjust: components["schemas"]["ImageOutput"];
|
||||||
|
lineart_anime_image_processor: components["schemas"]["ImageOutput"];
|
||||||
|
face_off: components["schemas"]["FaceOffOutput"];
|
||||||
|
mask_combine: components["schemas"]["ImageOutput"];
|
||||||
|
leres_image_processor: components["schemas"]["ImageOutput"];
|
||||||
|
image_mask_to_tensor: components["schemas"]["MaskOutput"];
|
||||||
|
sdxl_refiner_compel_prompt: components["schemas"]["ConditioningOutput"];
|
||||||
|
scheduler: components["schemas"]["SchedulerOutput"];
|
||||||
|
sub: components["schemas"]["IntegerOutput"];
|
||||||
|
pidi_image_processor: components["schemas"]["ImageOutput"];
|
||||||
|
infill_cv2: components["schemas"]["ImageOutput"];
|
||||||
|
div: components["schemas"]["IntegerOutput"];
|
||||||
|
img_nsfw: components["schemas"]["ImageOutput"];
|
||||||
|
depth_anything_image_processor: components["schemas"]["ImageOutput"];
|
||||||
|
sdxl_compel_prompt: components["schemas"]["ConditioningOutput"];
|
||||||
|
range: components["schemas"]["IntegerCollectionOutput"];
|
||||||
|
rand_int: components["schemas"]["IntegerOutput"];
|
||||||
|
float_math: components["schemas"]["FloatOutput"];
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* InvocationStartedEvent
|
* InvocationStartedEvent
|
||||||
@ -9443,6 +9450,49 @@ export type components = {
|
|||||||
[key: string]: number | string;
|
[key: string]: number | string;
|
||||||
})[];
|
})[];
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* ModelInstallDownloadStartedEvent
|
||||||
|
* @description Event model for model_install_download_started
|
||||||
|
*/
|
||||||
|
ModelInstallDownloadStartedEvent: {
|
||||||
|
/**
|
||||||
|
* Timestamp
|
||||||
|
* @description The timestamp of the event
|
||||||
|
*/
|
||||||
|
timestamp: number;
|
||||||
|
/**
|
||||||
|
* Id
|
||||||
|
* @description The ID of the install job
|
||||||
|
*/
|
||||||
|
id: number;
|
||||||
|
/**
|
||||||
|
* Source
|
||||||
|
* @description Source of the model; local path, repo_id or url
|
||||||
|
*/
|
||||||
|
source: string;
|
||||||
|
/**
|
||||||
|
* Local Path
|
||||||
|
* @description Where model is downloading to
|
||||||
|
*/
|
||||||
|
local_path: string;
|
||||||
|
/**
|
||||||
|
* Bytes
|
||||||
|
* @description Number of bytes downloaded so far
|
||||||
|
*/
|
||||||
|
bytes: number;
|
||||||
|
/**
|
||||||
|
* Total Bytes
|
||||||
|
* @description Total size of download, including all files
|
||||||
|
*/
|
||||||
|
total_bytes: number;
|
||||||
|
/**
|
||||||
|
* Parts
|
||||||
|
* @description Progress of downloading URLs that comprise the model, if any
|
||||||
|
*/
|
||||||
|
parts: ({
|
||||||
|
[key: string]: number | string;
|
||||||
|
})[];
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* ModelInstallDownloadsCompleteEvent
|
* ModelInstallDownloadsCompleteEvent
|
||||||
* @description Emitted once when an install job becomes active.
|
* @description Emitted once when an install job becomes active.
|
||||||
@ -10671,8 +10721,9 @@ export type components = {
|
|||||||
/**
|
/**
|
||||||
* Size
|
* Size
|
||||||
* @description The size of this file, in bytes
|
* @description The size of this file, in bytes
|
||||||
|
* @default 0
|
||||||
*/
|
*/
|
||||||
size: number;
|
size?: number | null;
|
||||||
/**
|
/**
|
||||||
* Sha256
|
* Sha256
|
||||||
* @description SHA256 hash of this model (not always available)
|
* @description SHA256 hash of this model (not always available)
|
||||||
@ -14050,6 +14101,40 @@ export type operations = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* Install Hugging Face Model
|
||||||
|
* @description Install a Hugging Face model using a string identifier.
|
||||||
|
*/
|
||||||
|
install_hugging_face_model: {
|
||||||
|
parameters: {
|
||||||
|
query: {
|
||||||
|
/** @description Hugging Face repo_id to install */
|
||||||
|
source: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
responses: {
|
||||||
|
/** @description The model is being installed */
|
||||||
|
201: {
|
||||||
|
content: {
|
||||||
|
"text/html": string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/** @description Bad request */
|
||||||
|
400: {
|
||||||
|
content: never;
|
||||||
|
};
|
||||||
|
/** @description There is already a model corresponding to this path or repo_id */
|
||||||
|
409: {
|
||||||
|
content: never;
|
||||||
|
};
|
||||||
|
/** @description Validation Error */
|
||||||
|
422: {
|
||||||
|
content: {
|
||||||
|
"application/json": components["schemas"]["HTTPValidationError"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* Get Model Install Job
|
* Get Model Install Job
|
||||||
* @description Return model install job corresponding to the given source. See the documentation for 'List Model Install Jobs'
|
* @description Return model install job corresponding to the given source. See the documentation for 'List Model Install Jobs'
|
||||||
|
@ -16,6 +16,7 @@ import type {
|
|||||||
ModelInstallCompleteEvent,
|
ModelInstallCompleteEvent,
|
||||||
ModelInstallDownloadProgressEvent,
|
ModelInstallDownloadProgressEvent,
|
||||||
ModelInstallDownloadsCompleteEvent,
|
ModelInstallDownloadsCompleteEvent,
|
||||||
|
ModelInstallDownloadStartedEvent,
|
||||||
ModelInstallErrorEvent,
|
ModelInstallErrorEvent,
|
||||||
ModelInstallStartedEvent,
|
ModelInstallStartedEvent,
|
||||||
ModelLoadCompleteEvent,
|
ModelLoadCompleteEvent,
|
||||||
@ -45,6 +46,9 @@ export const socketModelInstallStarted = createSocketAction<ModelInstallStartedE
|
|||||||
export const socketModelInstallDownloadProgress = createSocketAction<ModelInstallDownloadProgressEvent>(
|
export const socketModelInstallDownloadProgress = createSocketAction<ModelInstallDownloadProgressEvent>(
|
||||||
'ModelInstallDownloadProgressEvent'
|
'ModelInstallDownloadProgressEvent'
|
||||||
);
|
);
|
||||||
|
export const socketModelInstallDownloadStarted = createSocketAction<ModelInstallDownloadStartedEvent>(
|
||||||
|
'ModelInstallDownloadStartedEvent'
|
||||||
|
);
|
||||||
export const socketModelInstallDownloadsComplete = createSocketAction<ModelInstallDownloadsCompleteEvent>(
|
export const socketModelInstallDownloadsComplete = createSocketAction<ModelInstallDownloadsCompleteEvent>(
|
||||||
'ModelInstallDownloadsCompleteEvent'
|
'ModelInstallDownloadsCompleteEvent'
|
||||||
);
|
);
|
||||||
|
@ -9,6 +9,7 @@ export type InvocationCompleteEvent = S['InvocationCompleteEvent'];
|
|||||||
export type InvocationErrorEvent = S['InvocationErrorEvent'];
|
export type InvocationErrorEvent = S['InvocationErrorEvent'];
|
||||||
export type ProgressImage = InvocationDenoiseProgressEvent['progress_image'];
|
export type ProgressImage = InvocationDenoiseProgressEvent['progress_image'];
|
||||||
|
|
||||||
|
export type ModelInstallDownloadStartedEvent = S['ModelInstallDownloadStartedEvent'];
|
||||||
export type ModelInstallDownloadProgressEvent = S['ModelInstallDownloadProgressEvent'];
|
export type ModelInstallDownloadProgressEvent = S['ModelInstallDownloadProgressEvent'];
|
||||||
export type ModelInstallDownloadsCompleteEvent = S['ModelInstallDownloadsCompleteEvent'];
|
export type ModelInstallDownloadsCompleteEvent = S['ModelInstallDownloadsCompleteEvent'];
|
||||||
export type ModelInstallCompleteEvent = S['ModelInstallCompleteEvent'];
|
export type ModelInstallCompleteEvent = S['ModelInstallCompleteEvent'];
|
||||||
@ -49,6 +50,7 @@ export type ServerToClientEvents = {
|
|||||||
download_error: (payload: DownloadErrorEvent) => void;
|
download_error: (payload: DownloadErrorEvent) => void;
|
||||||
model_load_started: (payload: ModelLoadStartedEvent) => void;
|
model_load_started: (payload: ModelLoadStartedEvent) => void;
|
||||||
model_install_started: (payload: ModelInstallStartedEvent) => void;
|
model_install_started: (payload: ModelInstallStartedEvent) => void;
|
||||||
|
model_install_download_started: (payload: ModelInstallDownloadStartedEvent) => void;
|
||||||
model_install_download_progress: (payload: ModelInstallDownloadProgressEvent) => void;
|
model_install_download_progress: (payload: ModelInstallDownloadProgressEvent) => void;
|
||||||
model_install_downloads_complete: (payload: ModelInstallDownloadsCompleteEvent) => void;
|
model_install_downloads_complete: (payload: ModelInstallDownloadsCompleteEvent) => void;
|
||||||
model_install_complete: (payload: ModelInstallCompleteEvent) => void;
|
model_install_complete: (payload: ModelInstallCompleteEvent) => void;
|
||||||
|
@ -17,6 +17,7 @@ from invokeai.app.services.events.events_common import (
|
|||||||
ModelInstallCompleteEvent,
|
ModelInstallCompleteEvent,
|
||||||
ModelInstallDownloadProgressEvent,
|
ModelInstallDownloadProgressEvent,
|
||||||
ModelInstallDownloadsCompleteEvent,
|
ModelInstallDownloadsCompleteEvent,
|
||||||
|
ModelInstallDownloadStartedEvent,
|
||||||
ModelInstallStartedEvent,
|
ModelInstallStartedEvent,
|
||||||
)
|
)
|
||||||
from invokeai.app.services.model_install import (
|
from invokeai.app.services.model_install import (
|
||||||
@ -252,7 +253,7 @@ def test_simple_download(mm2_installer: ModelInstallServiceBase, mm2_app_config:
|
|||||||
assert (mm2_app_config.models_path / model_record.path).exists()
|
assert (mm2_app_config.models_path / model_record.path).exists()
|
||||||
|
|
||||||
assert len(bus.events) == 5
|
assert len(bus.events) == 5
|
||||||
assert isinstance(bus.events[0], ModelInstallDownloadProgressEvent) # download starts
|
assert isinstance(bus.events[0], ModelInstallDownloadStartedEvent) # download starts
|
||||||
assert isinstance(bus.events[1], ModelInstallDownloadProgressEvent) # download progresses
|
assert isinstance(bus.events[1], ModelInstallDownloadProgressEvent) # download progresses
|
||||||
assert isinstance(bus.events[2], ModelInstallDownloadsCompleteEvent) # download completed
|
assert isinstance(bus.events[2], ModelInstallDownloadsCompleteEvent) # download completed
|
||||||
assert isinstance(bus.events[3], ModelInstallStartedEvent) # install started
|
assert isinstance(bus.events[3], ModelInstallStartedEvent) # install started
|
||||||
|
Loading…
x
Reference in New Issue
Block a user