mirror of
https://github.com/vladmandic/automatic
synced 2026-09-19 09:14:35 +02:00
feat(civitai): show search failures in the models tab
CivitSearchResponse carries the server's error text; the Gradio page renders it, or a no-results line, in the details area instead of a blank card list. The legacy route reads items from the response.
This commit is contained in:
@@ -681,7 +681,7 @@ def legacy_get_civitai(
|
||||
query=query, tag=tag, types=types, sort=sort, period=period,
|
||||
nsfw=nsfw, limit=limit, base=base, token=token, exact=exact,
|
||||
)
|
||||
return [model_to_legacy_dict(m) for m in models]
|
||||
return [model_to_legacy_dict(m) for m in models.items]
|
||||
return JSONResponse(content=[], status_code=200)
|
||||
|
||||
|
||||
|
||||
@@ -141,8 +141,9 @@ class CivitaiClient:
|
||||
params['favorites'] = 'true'
|
||||
r = self._get('/models', params=params, token=token)
|
||||
if r.status_code != 200:
|
||||
log.error(f'CivitAI search: code={r.status_code} message="{response_message(r)}"')
|
||||
return CivitSearchResponse()
|
||||
message = response_message(r)
|
||||
log.error(f'CivitAI search: code={r.status_code} message="{message}"')
|
||||
return CivitSearchResponse(error=message)
|
||||
data = r.json()
|
||||
if 'items' not in data:
|
||||
# single model by numeric query — wrap in search response
|
||||
@@ -155,7 +156,7 @@ class CivitaiClient:
|
||||
response = CivitSearchResponse.parse_obj(data)
|
||||
except Exception as e:
|
||||
log.error(f'CivitAI search parse error: {e}')
|
||||
return CivitSearchResponse()
|
||||
return CivitSearchResponse(error='search response could not be parsed')
|
||||
# /models rejects server-side level filtering and its nsfw boolean leaks
|
||||
# Mature+ content, so filter on each model's aggregate nsfwLevel here:
|
||||
# nsfw on keeps every level, nsfw off/unset keeps SFW (None + Soft).
|
||||
|
||||
@@ -188,6 +188,7 @@ class CivitSearchResponse(BaseModel):
|
||||
items: list[CivitModel] = Field(default_factory=list)
|
||||
metadata: CivitSearchMetadata = Field(default_factory=CivitSearchMetadata)
|
||||
request_url: str | None = Field(None, alias="requestUrl")
|
||||
error: str | None = None # server or parse failure text; items is empty when set
|
||||
|
||||
|
||||
class CivitTag(BaseModel):
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import re
|
||||
import time
|
||||
from html import escape
|
||||
from installer import log
|
||||
from modules.civitai.client_civitai import client
|
||||
from modules.civitai.models_civitai import CivitModel, CivitSearchResponse
|
||||
@@ -16,10 +17,10 @@ def search_civitai(
|
||||
base: str = '',
|
||||
token: str | None = None,
|
||||
exact: bool = True,
|
||||
) -> list[CivitModel]:
|
||||
) -> CivitSearchResponse:
|
||||
if not query and not tag and not sort:
|
||||
log.error('CivitAI: no search criteria provided')
|
||||
return []
|
||||
return CivitSearchResponse(error='no search criteria provided')
|
||||
|
||||
t0 = time.time()
|
||||
|
||||
@@ -35,8 +36,8 @@ def search_civitai(
|
||||
if model:
|
||||
t1 = time.time()
|
||||
log.info(f'CivitAI result: id={query} time={t1 - t0:.2f}')
|
||||
return [model]
|
||||
return []
|
||||
return CivitSearchResponse(items=[model])
|
||||
return CivitSearchResponse(error=f'model {query} not found')
|
||||
|
||||
response: CivitSearchResponse = client.search_models(
|
||||
query=query,
|
||||
@@ -61,17 +62,20 @@ def search_civitai(
|
||||
if any(q_lower in name for name in names):
|
||||
exact_models.append(model)
|
||||
|
||||
result = exact_models if exact_models else all_models
|
||||
response.items = exact_models if exact_models else all_models
|
||||
t1 = time.time()
|
||||
log.info(f'CivitAI result: exact={len(exact_models)} total={len(all_models)} time={t1 - t0:.2f}')
|
||||
return result
|
||||
return response
|
||||
|
||||
|
||||
def create_model_cards(all_models: list[CivitModel]) -> str:
|
||||
details = """
|
||||
<div id="model-details">
|
||||
</div>
|
||||
"""
|
||||
def create_model_cards(response: CivitSearchResponse) -> str:
|
||||
if response.error:
|
||||
notice = f'CivitAI: {escape(response.error)}'
|
||||
elif not response.items:
|
||||
notice = 'No models found'
|
||||
else:
|
||||
notice = ''
|
||||
details = f'<div id="model-details">{notice}</div>'
|
||||
cards = """
|
||||
<div id="model-cards" class="extra-network-cards">
|
||||
{cards}
|
||||
@@ -85,7 +89,7 @@ def create_model_cards(all_models: list[CivitModel]) -> str:
|
||||
</div>
|
||||
"""
|
||||
all_cards = ''
|
||||
for model in all_models:
|
||||
for model in response.items:
|
||||
previews = []
|
||||
for version in model.versions:
|
||||
for image in version.images:
|
||||
|
||||
Reference in New Issue
Block a user