fix(recipes): parse loras from civitai hashes

This commit is contained in:
pixelpaws
2025-09-25 15:59:44 +08:00
parent d933308a6f
commit af713470c1
2 changed files with 114 additions and 1 deletions

View File

@@ -284,7 +284,59 @@ class CivitaiApiMetadataParser(RecipeMetadataParser):
logger.error(f"Error fetching Civitai info for model ID {version_id}: {e}")
result["loras"].append(lora_entry)
# If we found LoRA hashes in the metadata but haven't already
# populated entries for them, fall back to creating LoRAs from
# the hashes section. Some Civitai image responses only include
# LoRA information here without explicit resources entries.
for lora_name, lora_hash in lora_hashes.items():
if not lora_hash:
continue
# Skip LoRAs we've already added via resources or other fields
if lora_hash in added_loras:
continue
lora_entry = {
'name': lora_name,
'type': "lora",
'weight': 1.0,
'hash': lora_hash,
'existsLocally': False,
'localPath': None,
'file_name': lora_name,
'thumbnailUrl': '/loras_static/images/no-preview.png',
'baseModel': '',
'size': 0,
'downloadUrl': '',
'isDeleted': False
}
if metadata_provider:
try:
civitai_info = await metadata_provider.get_model_by_hash(lora_hash)
populated_entry = await self.populate_lora_from_civitai(
lora_entry,
civitai_info,
recipe_scanner,
base_model_counts,
lora_hash
)
if populated_entry is None:
continue
lora_entry = populated_entry
if 'id' in lora_entry and lora_entry['id']:
added_loras[str(lora_entry['id'])] = len(result["loras"])
except Exception as e:
logger.error(f"Error fetching Civitai info for LoRA hash {lora_hash}: {e}")
added_loras[lora_hash] = len(result["loras"])
result["loras"].append(lora_entry)
# Check for LoRA info in the format "Lora_0 Model hash", "Lora_0 Model name", etc.
lora_index = 0
while f"Lora_{lora_index} Model hash" in metadata and f"Lora_{lora_index} Model name" in metadata:

View File

@@ -0,0 +1,61 @@
import pytest
from py.recipes.parsers.civitai_image import CivitaiApiMetadataParser
@pytest.mark.asyncio
async def test_parse_metadata_creates_loras_from_hashes(monkeypatch):
async def fake_metadata_provider():
return None
monkeypatch.setattr(
"py.recipes.parsers.civitai_image.get_default_metadata_provider",
fake_metadata_provider,
)
parser = CivitaiApiMetadataParser()
metadata = {
"Size": "1536x2688",
"seed": 3766932689,
"Model": "indexed_v1",
"steps": 30,
"hashes": {
"model": "692186a14a",
"LORA:Jedst1": "fb4063c470",
"LORA:HassaKu_style": "3ce00b926b",
"LORA:DetailedEyes_V3": "2c1c3f889f",
"LORA:jiaocha_illustriousXL": "35d3e6f8b0",
"LORA:绪儿 厚涂构图光影质感增强V3": "d9b5900a59",
},
"prompt": "test",
"Version": "ComfyUI",
"sampler": "er_sde_ays_30",
"cfgScale": 5,
"clipSkip": 2,
"resources": [
{
"hash": "692186a14a",
"name": "indexed_v1",
"type": "model",
}
],
"Model hash": "692186a14a",
"negativePrompt": "bad",
"username": "LumaRift",
"baseModel": "Illustrious",
}
result = await parser.parse_metadata(metadata)
assert result["base_model"] == "Illustrious"
assert len(result["loras"]) == 5
assert all(lora["weight"] == 1.0 for lora in result["loras"])
assert {lora["name"] for lora in result["loras"]} == {
"Jedst1",
"HassaKu_style",
"DetailedEyes_V3",
"jiaocha_illustriousXL",
"绪儿 厚涂构图光影质感增强V3",
}