Skip to content

Commit 412aaab

Browse files
synap5eguill
andauthored
feat(api): expose registered extension filters on /experiment/models (Comfy-Org#14797)
Each folder in the listing now carries its registered extension allowlist verbatim; an empty array means the folder accepts any extension (match-all), mirroring filter_files_extensions semantics. Gives consumers the filtering rule itself rather than just its output: /models/{folder} lists files by the per-folder rule but the rule is not exposed anywhere, and /experiment/models/{folder} filters everything by the global supported_pt_extensions regardless of registration. Presentation-level filtering of match-all folders (e.g. hiding README/config noise that repository-downloading custom nodes leave in model directories) is deliberately left to the consumer. Co-authored-by: guill <jacob.e.segal@gmail.com>
1 parent 04a30fb commit 412aaab

3 files changed

Lines changed: 35 additions & 1 deletion

File tree

app/model_manager.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,11 @@ async def get_model_folders(request):
3535
for folder in model_types:
3636
if folder in folder_black_list:
3737
continue
38-
output_folders.append({"name": folder, "folders": folder_paths.get_folder_paths(folder)})
38+
output_folders.append({
39+
"name": folder,
40+
"folders": folder_paths.get_folder_paths(folder),
41+
"extensions": sorted(folder_paths.folder_names_and_paths[folder][1]),
42+
})
3943
return web.json_response(output_folders)
4044

4145
# NOTE: This is an experiment to replace `/models/{folder}`

openapi.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,14 @@ components:
775775
ModelFolder:
776776
description: Represents a folder containing models
777777
properties:
778+
extensions:
779+
description: The folder's registered file-extension allowlist. An empty array means the folder accepts any extension (match-all).
780+
example:
781+
- .ckpt
782+
- .safetensors
783+
items:
784+
type: string
785+
type: array
778786
folders:
779787
description: List of paths where models of this type are stored
780788
example:

tests-unit/app_test/model_manager_test.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,28 @@ def app(model_manager):
2424
app.add_routes(routes)
2525
return app
2626

27+
async def test_get_model_folders_includes_registered_extensions(aiohttp_client, app, tmp_path):
28+
"""Folders expose their registered extension set verbatim; an empty list
29+
means match-all (filter_files_extensions semantics)."""
30+
with patch('folder_paths.folder_names_and_paths', {
31+
'test_checkpoints': ([str(tmp_path)], {'.safetensors', '.ckpt'}),
32+
'test_configs': ([str(tmp_path)], ['.yaml']),
33+
'test_match_all': ([str(tmp_path)], set()),
34+
'configs': ([str(tmp_path)], ['.yaml']),
35+
}):
36+
client = await aiohttp_client(app)
37+
response = await client.get('/experiment/models')
38+
39+
assert response.status == 200
40+
folders = {f['name']: f for f in await response.json()}
41+
42+
assert 'configs' not in folders # blocklisted
43+
assert folders['test_checkpoints']['folders'] == [str(tmp_path)]
44+
assert folders['test_checkpoints']['extensions'] == ['.ckpt', '.safetensors']
45+
assert folders['test_configs']['extensions'] == ['.yaml']
46+
# Match-all registrations are exposed honestly, not substituted.
47+
assert folders['test_match_all']['extensions'] == []
48+
2749
async def test_get_model_preview_safetensors(aiohttp_client, app, tmp_path):
2850
img = Image.new('RGB', (100, 100), 'white')
2951
img_byte_arr = BytesIO()

0 commit comments

Comments
 (0)