@weirdfingers/baseboards 0.9.6 → 0.9.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +560 -469
- package/dist/index.js.map +1 -1
- package/package.json +2 -5
- package/templates/README.md +0 -122
- package/templates/api/.env.example +0 -65
- package/templates/api/ARTIFACT_RESOLUTION_GUIDE.md +0 -148
- package/templates/api/Dockerfile +0 -32
- package/templates/api/README.md +0 -264
- package/templates/api/alembic/env.py +0 -114
- package/templates/api/alembic/script.py.mako +0 -28
- package/templates/api/alembic/versions/20250101_000000_initial_schema.py +0 -506
- package/templates/api/alembic/versions/20251022_174729_remove_provider_name_from_generations.py +0 -75
- package/templates/api/alembic/versions/20251023_165852_switch_to_declarative_base_and_mapping.py +0 -467
- package/templates/api/alembic/versions/20251202_000000_add_artifact_lineage.py +0 -134
- package/templates/api/alembic/versions/2025925_62735_add_seed_data_for_default_tenant.py +0 -88
- package/templates/api/alembic.ini +0 -36
- package/templates/api/config/generators.yaml +0 -237
- package/templates/api/config/storage_config.yaml +0 -26
- package/templates/api/docs/ADDING_GENERATORS.md +0 -409
- package/templates/api/docs/GENERATORS_API.md +0 -502
- package/templates/api/docs/MIGRATIONS.md +0 -472
- package/templates/api/docs/TESTING_LIVE_APIS.md +0 -417
- package/templates/api/docs/storage_providers.md +0 -337
- package/templates/api/pyproject.toml +0 -205
- package/templates/api/src/boards/__init__.py +0 -10
- package/templates/api/src/boards/api/app.py +0 -172
- package/templates/api/src/boards/api/auth.py +0 -75
- package/templates/api/src/boards/api/endpoints/__init__.py +0 -3
- package/templates/api/src/boards/api/endpoints/jobs.py +0 -76
- package/templates/api/src/boards/api/endpoints/setup.py +0 -505
- package/templates/api/src/boards/api/endpoints/sse.py +0 -129
- package/templates/api/src/boards/api/endpoints/storage.py +0 -155
- package/templates/api/src/boards/api/endpoints/tenant_registration.py +0 -296
- package/templates/api/src/boards/api/endpoints/uploads.py +0 -149
- package/templates/api/src/boards/api/endpoints/webhooks.py +0 -13
- package/templates/api/src/boards/auth/__init__.py +0 -15
- package/templates/api/src/boards/auth/adapters/__init__.py +0 -27
- package/templates/api/src/boards/auth/adapters/auth0.py +0 -220
- package/templates/api/src/boards/auth/adapters/base.py +0 -73
- package/templates/api/src/boards/auth/adapters/clerk.py +0 -172
- package/templates/api/src/boards/auth/adapters/jwt.py +0 -122
- package/templates/api/src/boards/auth/adapters/none.py +0 -102
- package/templates/api/src/boards/auth/adapters/oidc.py +0 -284
- package/templates/api/src/boards/auth/adapters/supabase.py +0 -110
- package/templates/api/src/boards/auth/context.py +0 -35
- package/templates/api/src/boards/auth/factory.py +0 -129
- package/templates/api/src/boards/auth/middleware.py +0 -221
- package/templates/api/src/boards/auth/provisioning.py +0 -129
- package/templates/api/src/boards/auth/tenant_extraction.py +0 -278
- package/templates/api/src/boards/cli.py +0 -354
- package/templates/api/src/boards/config.py +0 -131
- package/templates/api/src/boards/database/__init__.py +0 -7
- package/templates/api/src/boards/database/cli.py +0 -110
- package/templates/api/src/boards/database/connection.py +0 -292
- package/templates/api/src/boards/database/models.py +0 -19
- package/templates/api/src/boards/database/seed_data.py +0 -182
- package/templates/api/src/boards/dbmodels/__init__.py +0 -441
- package/templates/api/src/boards/generators/__init__.py +0 -57
- package/templates/api/src/boards/generators/artifact_resolution.py +0 -405
- package/templates/api/src/boards/generators/artifacts.py +0 -53
- package/templates/api/src/boards/generators/base.py +0 -144
- package/templates/api/src/boards/generators/implementations/__init__.py +0 -14
- package/templates/api/src/boards/generators/implementations/fal/__init__.py +0 -25
- package/templates/api/src/boards/generators/implementations/fal/audio/__init__.py +0 -23
- package/templates/api/src/boards/generators/implementations/fal/audio/beatoven_music_generation.py +0 -171
- package/templates/api/src/boards/generators/implementations/fal/audio/beatoven_sound_effect_generation.py +0 -167
- package/templates/api/src/boards/generators/implementations/fal/audio/chatterbox_text_to_speech.py +0 -176
- package/templates/api/src/boards/generators/implementations/fal/audio/chatterbox_tts_turbo.py +0 -195
- package/templates/api/src/boards/generators/implementations/fal/audio/elevenlabs_sound_effects_v2.py +0 -194
- package/templates/api/src/boards/generators/implementations/fal/audio/elevenlabs_tts_eleven_v3.py +0 -209
- package/templates/api/src/boards/generators/implementations/fal/audio/fal_elevenlabs_tts_turbo_v2_5.py +0 -206
- package/templates/api/src/boards/generators/implementations/fal/audio/fal_minimax_speech_26_hd.py +0 -237
- package/templates/api/src/boards/generators/implementations/fal/audio/minimax_music_v2.py +0 -173
- package/templates/api/src/boards/generators/implementations/fal/audio/minimax_speech_2_6_turbo.py +0 -221
- package/templates/api/src/boards/generators/implementations/fal/image/__init__.py +0 -63
- package/templates/api/src/boards/generators/implementations/fal/image/bytedance_seedream_v45_edit.py +0 -219
- package/templates/api/src/boards/generators/implementations/fal/image/clarity_upscaler.py +0 -220
- package/templates/api/src/boards/generators/implementations/fal/image/crystal_upscaler.py +0 -173
- package/templates/api/src/boards/generators/implementations/fal/image/fal_ideogram_character.py +0 -227
- package/templates/api/src/boards/generators/implementations/fal/image/flux_2.py +0 -203
- package/templates/api/src/boards/generators/implementations/fal/image/flux_2_edit.py +0 -230
- package/templates/api/src/boards/generators/implementations/fal/image/flux_2_pro.py +0 -204
- package/templates/api/src/boards/generators/implementations/fal/image/flux_2_pro_edit.py +0 -221
- package/templates/api/src/boards/generators/implementations/fal/image/flux_pro_kontext.py +0 -216
- package/templates/api/src/boards/generators/implementations/fal/image/flux_pro_ultra.py +0 -197
- package/templates/api/src/boards/generators/implementations/fal/image/gemini_25_flash_image.py +0 -177
- package/templates/api/src/boards/generators/implementations/fal/image/gemini_25_flash_image_edit.py +0 -208
- package/templates/api/src/boards/generators/implementations/fal/image/gpt_image_15_edit.py +0 -216
- package/templates/api/src/boards/generators/implementations/fal/image/gpt_image_1_5.py +0 -177
- package/templates/api/src/boards/generators/implementations/fal/image/gpt_image_1_edit_image.py +0 -182
- package/templates/api/src/boards/generators/implementations/fal/image/gpt_image_1_mini.py +0 -167
- package/templates/api/src/boards/generators/implementations/fal/image/ideogram_character_edit.py +0 -299
- package/templates/api/src/boards/generators/implementations/fal/image/ideogram_v2.py +0 -190
- package/templates/api/src/boards/generators/implementations/fal/image/imagen4_preview.py +0 -191
- package/templates/api/src/boards/generators/implementations/fal/image/imagen4_preview_fast.py +0 -179
- package/templates/api/src/boards/generators/implementations/fal/image/nano_banana.py +0 -183
- package/templates/api/src/boards/generators/implementations/fal/image/nano_banana_edit.py +0 -212
- package/templates/api/src/boards/generators/implementations/fal/image/nano_banana_pro.py +0 -179
- package/templates/api/src/boards/generators/implementations/fal/image/nano_banana_pro_edit.py +0 -226
- package/templates/api/src/boards/generators/implementations/fal/image/qwen_image.py +0 -249
- package/templates/api/src/boards/generators/implementations/fal/image/qwen_image_edit.py +0 -244
- package/templates/api/src/boards/generators/implementations/fal/image/reve_edit.py +0 -178
- package/templates/api/src/boards/generators/implementations/fal/image/reve_text_to_image.py +0 -155
- package/templates/api/src/boards/generators/implementations/fal/image/seedream_v45_text_to_image.py +0 -180
- package/templates/api/src/boards/generators/implementations/fal/utils.py +0 -61
- package/templates/api/src/boards/generators/implementations/fal/video/__init__.py +0 -77
- package/templates/api/src/boards/generators/implementations/fal/video/bytedance_seedance_v1_pro_text_to_video.py +0 -209
- package/templates/api/src/boards/generators/implementations/fal/video/creatify_lipsync.py +0 -161
- package/templates/api/src/boards/generators/implementations/fal/video/fal_bytedance_seedance_v1_pro_image_to_video.py +0 -222
- package/templates/api/src/boards/generators/implementations/fal/video/fal_minimax_hailuo_02_standard_text_to_video.py +0 -152
- package/templates/api/src/boards/generators/implementations/fal/video/fal_pixverse_lipsync.py +0 -197
- package/templates/api/src/boards/generators/implementations/fal/video/fal_sora_2_text_to_video.py +0 -173
- package/templates/api/src/boards/generators/implementations/fal/video/infinitalk.py +0 -221
- package/templates/api/src/boards/generators/implementations/fal/video/kling_video_ai_avatar_v2_pro.py +0 -168
- package/templates/api/src/boards/generators/implementations/fal/video/kling_video_ai_avatar_v2_standard.py +0 -159
- package/templates/api/src/boards/generators/implementations/fal/video/kling_video_v2_5_turbo_pro_image_to_video.py +0 -175
- package/templates/api/src/boards/generators/implementations/fal/video/kling_video_v2_5_turbo_pro_text_to_video.py +0 -168
- package/templates/api/src/boards/generators/implementations/fal/video/minimax_hailuo_2_3_pro_image_to_video.py +0 -153
- package/templates/api/src/boards/generators/implementations/fal/video/sora2_image_to_video.py +0 -172
- package/templates/api/src/boards/generators/implementations/fal/video/sora_2_image_to_video_pro.py +0 -175
- package/templates/api/src/boards/generators/implementations/fal/video/sora_2_text_to_video_pro.py +0 -163
- package/templates/api/src/boards/generators/implementations/fal/video/sync_lipsync_v2.py +0 -167
- package/templates/api/src/boards/generators/implementations/fal/video/sync_lipsync_v2_pro.py +0 -155
- package/templates/api/src/boards/generators/implementations/fal/video/veed_fabric_1_0.py +0 -180
- package/templates/api/src/boards/generators/implementations/fal/video/veed_lipsync.py +0 -174
- package/templates/api/src/boards/generators/implementations/fal/video/veo3.py +0 -194
- package/templates/api/src/boards/generators/implementations/fal/video/veo31.py +0 -190
- package/templates/api/src/boards/generators/implementations/fal/video/veo31_fast.py +0 -190
- package/templates/api/src/boards/generators/implementations/fal/video/veo31_fast_image_to_video.py +0 -191
- package/templates/api/src/boards/generators/implementations/fal/video/veo31_first_last_frame_to_video.py +0 -187
- package/templates/api/src/boards/generators/implementations/fal/video/veo31_image_to_video.py +0 -183
- package/templates/api/src/boards/generators/implementations/fal/video/veo31_reference_to_video.py +0 -172
- package/templates/api/src/boards/generators/implementations/fal/video/wan_25_preview_image_to_video.py +0 -212
- package/templates/api/src/boards/generators/implementations/fal/video/wan_25_preview_text_to_video.py +0 -208
- package/templates/api/src/boards/generators/implementations/fal/video/wan_pro_image_to_video.py +0 -158
- package/templates/api/src/boards/generators/implementations/kie/__init__.py +0 -11
- package/templates/api/src/boards/generators/implementations/kie/base.py +0 -316
- package/templates/api/src/boards/generators/implementations/kie/image/__init__.py +0 -3
- package/templates/api/src/boards/generators/implementations/kie/image/nano_banana_edit.py +0 -190
- package/templates/api/src/boards/generators/implementations/kie/utils.py +0 -98
- package/templates/api/src/boards/generators/implementations/kie/video/__init__.py +0 -8
- package/templates/api/src/boards/generators/implementations/kie/video/veo3.py +0 -161
- package/templates/api/src/boards/generators/implementations/openai/__init__.py +0 -1
- package/templates/api/src/boards/generators/implementations/openai/audio/__init__.py +0 -1
- package/templates/api/src/boards/generators/implementations/openai/audio/whisper.py +0 -69
- package/templates/api/src/boards/generators/implementations/openai/image/__init__.py +0 -1
- package/templates/api/src/boards/generators/implementations/openai/image/dalle3.py +0 -96
- package/templates/api/src/boards/generators/implementations/replicate/__init__.py +0 -1
- package/templates/api/src/boards/generators/implementations/replicate/image/__init__.py +0 -1
- package/templates/api/src/boards/generators/implementations/replicate/image/flux_pro.py +0 -88
- package/templates/api/src/boards/generators/implementations/replicate/video/__init__.py +0 -1
- package/templates/api/src/boards/generators/implementations/replicate/video/lipsync.py +0 -73
- package/templates/api/src/boards/generators/loader.py +0 -253
- package/templates/api/src/boards/generators/registry.py +0 -114
- package/templates/api/src/boards/generators/resolution.py +0 -632
- package/templates/api/src/boards/generators/testmods/class_gen.py +0 -34
- package/templates/api/src/boards/generators/testmods/import_side_effect.py +0 -35
- package/templates/api/src/boards/graphql/__init__.py +0 -7
- package/templates/api/src/boards/graphql/access_control.py +0 -136
- package/templates/api/src/boards/graphql/mutations/root.py +0 -148
- package/templates/api/src/boards/graphql/queries/root.py +0 -116
- package/templates/api/src/boards/graphql/resolvers/__init__.py +0 -8
- package/templates/api/src/boards/graphql/resolvers/auth.py +0 -12
- package/templates/api/src/boards/graphql/resolvers/board.py +0 -1053
- package/templates/api/src/boards/graphql/resolvers/generation.py +0 -666
- package/templates/api/src/boards/graphql/resolvers/generator.py +0 -50
- package/templates/api/src/boards/graphql/resolvers/lineage.py +0 -381
- package/templates/api/src/boards/graphql/resolvers/upload.py +0 -463
- package/templates/api/src/boards/graphql/resolvers/user.py +0 -25
- package/templates/api/src/boards/graphql/schema.py +0 -81
- package/templates/api/src/boards/graphql/types/board.py +0 -102
- package/templates/api/src/boards/graphql/types/generation.py +0 -166
- package/templates/api/src/boards/graphql/types/generator.py +0 -17
- package/templates/api/src/boards/graphql/types/user.py +0 -47
- package/templates/api/src/boards/jobs/repository.py +0 -153
- package/templates/api/src/boards/logging.py +0 -195
- package/templates/api/src/boards/middleware.py +0 -339
- package/templates/api/src/boards/progress/__init__.py +0 -4
- package/templates/api/src/boards/progress/models.py +0 -25
- package/templates/api/src/boards/progress/publisher.py +0 -64
- package/templates/api/src/boards/py.typed +0 -0
- package/templates/api/src/boards/redis_pool.py +0 -118
- package/templates/api/src/boards/storage/__init__.py +0 -52
- package/templates/api/src/boards/storage/base.py +0 -363
- package/templates/api/src/boards/storage/config.py +0 -187
- package/templates/api/src/boards/storage/factory.py +0 -288
- package/templates/api/src/boards/storage/implementations/__init__.py +0 -27
- package/templates/api/src/boards/storage/implementations/gcs.py +0 -340
- package/templates/api/src/boards/storage/implementations/local.py +0 -201
- package/templates/api/src/boards/storage/implementations/s3.py +0 -294
- package/templates/api/src/boards/storage/implementations/supabase.py +0 -218
- package/templates/api/src/boards/tenant_isolation.py +0 -446
- package/templates/api/src/boards/validation.py +0 -262
- package/templates/api/src/boards/workers/__init__.py +0 -1
- package/templates/api/src/boards/workers/actors.py +0 -274
- package/templates/api/src/boards/workers/cli.py +0 -125
- package/templates/api/src/boards/workers/context.py +0 -348
- package/templates/api/src/boards/workers/middleware.py +0 -58
- package/templates/api/src/py.typed +0 -0
- package/templates/compose.web.yaml +0 -35
- package/templates/compose.yaml +0 -116
- package/templates/docker/env.example +0 -23
- package/templates/web/.env.example +0 -28
- package/templates/web/Dockerfile +0 -51
- package/templates/web/components.json +0 -22
- package/templates/web/imageLoader.js +0 -18
- package/templates/web/next-env.d.ts +0 -5
- package/templates/web/next.config.js +0 -36
- package/templates/web/package.json +0 -41
- package/templates/web/postcss.config.mjs +0 -7
- package/templates/web/public/favicon.ico +0 -0
- package/templates/web/src/app/boards/[boardId]/page.tsx +0 -353
- package/templates/web/src/app/globals.css +0 -123
- package/templates/web/src/app/layout.tsx +0 -31
- package/templates/web/src/app/lineage/[generationId]/page.tsx +0 -235
- package/templates/web/src/app/page.tsx +0 -35
- package/templates/web/src/app/providers.tsx +0 -18
- package/templates/web/src/components/boards/ArtifactInputSlots.tsx +0 -206
- package/templates/web/src/components/boards/ArtifactPreview.tsx +0 -466
- package/templates/web/src/components/boards/GenerationGrid.tsx +0 -282
- package/templates/web/src/components/boards/GenerationInput.tsx +0 -370
- package/templates/web/src/components/boards/GeneratorSelector.tsx +0 -272
- package/templates/web/src/components/boards/UploadArtifact.tsx +0 -563
- package/templates/web/src/components/header.tsx +0 -32
- package/templates/web/src/components/theme-provider.tsx +0 -10
- package/templates/web/src/components/theme-toggle.tsx +0 -75
- package/templates/web/src/components/ui/alert-dialog.tsx +0 -157
- package/templates/web/src/components/ui/button.tsx +0 -58
- package/templates/web/src/components/ui/card.tsx +0 -92
- package/templates/web/src/components/ui/dropdown-menu.tsx +0 -200
- package/templates/web/src/components/ui/navigation-menu.tsx +0 -168
- package/templates/web/src/components/ui/toast.tsx +0 -128
- package/templates/web/src/components/ui/toaster.tsx +0 -35
- package/templates/web/src/components/ui/use-toast.ts +0 -187
- package/templates/web/src/hooks/useGeneratorMRU.ts +0 -57
- package/templates/web/src/lib/utils.ts +0 -6
- package/templates/web/tsconfig.json +0 -41
|
@@ -1,253 +0,0 @@
|
|
|
1
|
-
"""Configuration-driven generator loader.
|
|
2
|
-
|
|
3
|
-
Loads and registers generators based on configuration file.
|
|
4
|
-
File path is specified via settings.generators_config_path.
|
|
5
|
-
|
|
6
|
-
Supports three declaration forms: import, class, entrypoint.
|
|
7
|
-
Strict mode is enabled by default and will fail startup on errors.
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
from __future__ import annotations
|
|
11
|
-
|
|
12
|
-
from collections.abc import Iterable
|
|
13
|
-
from dataclasses import dataclass
|
|
14
|
-
from importlib import import_module
|
|
15
|
-
from importlib import metadata as importlib_metadata
|
|
16
|
-
from pathlib import Path
|
|
17
|
-
from typing import Any
|
|
18
|
-
|
|
19
|
-
import yaml
|
|
20
|
-
|
|
21
|
-
from boards.config import settings
|
|
22
|
-
from boards.logging import get_logger
|
|
23
|
-
|
|
24
|
-
from .base import BaseGenerator
|
|
25
|
-
from .registry import registry
|
|
26
|
-
|
|
27
|
-
logger = get_logger(__name__)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
ENTRYPOINT_GROUP = "boards.generators"
|
|
31
|
-
|
|
32
|
-
VALID_ARTIFACT_TYPES: set[str] = {"image", "video", "audio", "text", "lora"}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
@dataclass
|
|
36
|
-
class LoaderConfig:
|
|
37
|
-
strict_mode: bool = True
|
|
38
|
-
allow_unlisted: bool = False
|
|
39
|
-
declarations: list[dict[str, Any]] | None = None
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
def _load_file_config(path: str) -> LoaderConfig | None:
|
|
43
|
-
try:
|
|
44
|
-
with open(path, encoding="utf-8") as f:
|
|
45
|
-
data: dict[str, Any] = yaml.safe_load(f) or {}
|
|
46
|
-
except FileNotFoundError:
|
|
47
|
-
return None
|
|
48
|
-
|
|
49
|
-
strict_mode = bool(data.get("strict_mode", True))
|
|
50
|
-
allow_unlisted = bool(data.get("allow_unlisted", False))
|
|
51
|
-
declarations = list(data.get("generators", []) or [])
|
|
52
|
-
|
|
53
|
-
return LoaderConfig(
|
|
54
|
-
strict_mode=strict_mode,
|
|
55
|
-
allow_unlisted=allow_unlisted,
|
|
56
|
-
declarations=declarations,
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
def _discover_config() -> LoaderConfig | None:
|
|
61
|
-
"""Discover config from settings.generators_config_path."""
|
|
62
|
-
if not settings.generators_config_path:
|
|
63
|
-
return None
|
|
64
|
-
|
|
65
|
-
path = Path(settings.generators_config_path)
|
|
66
|
-
if not path.exists():
|
|
67
|
-
logger.warning("Generators config path set but not found", path=str(path))
|
|
68
|
-
return None
|
|
69
|
-
|
|
70
|
-
cfg = _load_file_config(str(path))
|
|
71
|
-
if cfg:
|
|
72
|
-
logger.info("Loaded generators config from settings", path=str(path))
|
|
73
|
-
return cfg
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
def _resolve_class(qualified_name: str) -> type[BaseGenerator]:
|
|
77
|
-
if ":" in qualified_name:
|
|
78
|
-
module_name, class_name = qualified_name.split(":", 1)
|
|
79
|
-
else:
|
|
80
|
-
# Split on last dot for module path
|
|
81
|
-
module_name, class_name = qualified_name.rsplit(".", 1)
|
|
82
|
-
|
|
83
|
-
module = import_module(module_name)
|
|
84
|
-
cls = getattr(module, class_name)
|
|
85
|
-
if not isinstance(cls, type) or not issubclass(cls, BaseGenerator):
|
|
86
|
-
raise TypeError(f"Resolved object is not a BaseGenerator subclass: {qualified_name}")
|
|
87
|
-
return cls
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
def _resolve_entrypoint(name: str) -> type[BaseGenerator]:
|
|
91
|
-
try:
|
|
92
|
-
eps = importlib_metadata.entry_points()
|
|
93
|
-
# Python 3.12 returns a Selection object with .select
|
|
94
|
-
group_filtered: Iterable[Any]
|
|
95
|
-
if hasattr(eps, "select"):
|
|
96
|
-
group_filtered = eps.select(group=ENTRYPOINT_GROUP)
|
|
97
|
-
else:
|
|
98
|
-
group_filtered = eps.get(ENTRYPOINT_GROUP, []) # type: ignore[attr-defined]
|
|
99
|
-
except Exception as e: # pragma: no cover - edge cases
|
|
100
|
-
raise RuntimeError(f"Failed to read entry points: {e}") from e
|
|
101
|
-
|
|
102
|
-
for ep in group_filtered:
|
|
103
|
-
if getattr(ep, "name", None) == name:
|
|
104
|
-
obj = ep.load()
|
|
105
|
-
if not isinstance(obj, type) or not issubclass(obj, BaseGenerator):
|
|
106
|
-
raise TypeError(f"Entry point '{name}' is not a BaseGenerator class")
|
|
107
|
-
return obj
|
|
108
|
-
|
|
109
|
-
raise LookupError(f"Entry point not found: {name}")
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
def _validate_artifact_type(instance: BaseGenerator) -> None:
|
|
113
|
-
artifact_type = getattr(instance, "artifact_type", None)
|
|
114
|
-
if not artifact_type or artifact_type not in VALID_ARTIFACT_TYPES:
|
|
115
|
-
raise ValueError(f"Invalid artifact_type: {artifact_type}")
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
def _register_instance(instance: BaseGenerator, name_override: str | None) -> None:
|
|
119
|
-
if name_override:
|
|
120
|
-
# Override instance name if provided
|
|
121
|
-
try:
|
|
122
|
-
instance.name = name_override
|
|
123
|
-
except Exception as e:
|
|
124
|
-
raise ValueError(f"Failed to set generator name override: {e}") from e
|
|
125
|
-
|
|
126
|
-
_validate_artifact_type(instance)
|
|
127
|
-
registry.register(instance)
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
def _enforce_unlisted_policy(
|
|
131
|
-
allowed_names: set[str], strict_mode: bool, allow_unlisted: bool
|
|
132
|
-
) -> None:
|
|
133
|
-
registered = set(registry.list_names())
|
|
134
|
-
extras = registered - allowed_names
|
|
135
|
-
if not extras:
|
|
136
|
-
return
|
|
137
|
-
|
|
138
|
-
msg = f"Found unlisted generator registrations: {sorted(extras)}"
|
|
139
|
-
if allow_unlisted:
|
|
140
|
-
logger.warning(msg)
|
|
141
|
-
return
|
|
142
|
-
|
|
143
|
-
# Not allowed. Attempt to unregister extras then decide based on strict_mode.
|
|
144
|
-
for name in extras:
|
|
145
|
-
try:
|
|
146
|
-
registry.unregister(name)
|
|
147
|
-
except Exception: # pragma: no cover - defensive
|
|
148
|
-
pass
|
|
149
|
-
|
|
150
|
-
if strict_mode:
|
|
151
|
-
raise RuntimeError(msg)
|
|
152
|
-
else:
|
|
153
|
-
logger.error(msg)
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
def load_generators_from_config(config_path: str | None = None) -> None:
|
|
157
|
-
"""Load and register generators according to configuration.
|
|
158
|
-
|
|
159
|
-
Raises on errors when strict mode is enabled (default).
|
|
160
|
-
"""
|
|
161
|
-
|
|
162
|
-
# Discover configuration
|
|
163
|
-
cfg: LoaderConfig | None
|
|
164
|
-
if config_path:
|
|
165
|
-
cfg = _load_file_config(config_path)
|
|
166
|
-
if cfg:
|
|
167
|
-
logger.info("Loaded generators config from explicit path", path=config_path)
|
|
168
|
-
else:
|
|
169
|
-
cfg = _discover_config()
|
|
170
|
-
|
|
171
|
-
# If nothing configured, do nothing (no implicit imports)
|
|
172
|
-
if not cfg or not cfg.declarations:
|
|
173
|
-
logger.info("No generators configuration found; skipping generator loading")
|
|
174
|
-
return
|
|
175
|
-
|
|
176
|
-
strict_mode = cfg.strict_mode
|
|
177
|
-
allow_unlisted = cfg.allow_unlisted
|
|
178
|
-
|
|
179
|
-
requested_names: set[str] = set()
|
|
180
|
-
|
|
181
|
-
# Process declarations in order
|
|
182
|
-
for decl in cfg.declarations:
|
|
183
|
-
if not isinstance(decl, dict):
|
|
184
|
-
msg = f"Invalid generator declaration type: {type(decl)}"
|
|
185
|
-
if strict_mode:
|
|
186
|
-
raise ValueError(msg)
|
|
187
|
-
logger.error(msg)
|
|
188
|
-
continue
|
|
189
|
-
|
|
190
|
-
if decl.get("enabled") is False:
|
|
191
|
-
continue
|
|
192
|
-
|
|
193
|
-
name_override = decl.get("name")
|
|
194
|
-
|
|
195
|
-
try:
|
|
196
|
-
if "import" in decl:
|
|
197
|
-
import_path = decl["import"]
|
|
198
|
-
import_module(import_path)
|
|
199
|
-
# Back-compat path relies on module side-effect registration.
|
|
200
|
-
# We cannot infer the name here reliably; collect after loop.
|
|
201
|
-
logger.info("Imported generator module", import_path=import_path)
|
|
202
|
-
elif "class" in decl:
|
|
203
|
-
qualified = decl["class"]
|
|
204
|
-
options = decl.get("options", {}) or {}
|
|
205
|
-
cls = _resolve_class(qualified)
|
|
206
|
-
instance = cls(**options) if options else cls()
|
|
207
|
-
_register_instance(instance, name_override)
|
|
208
|
-
requested_names.add(instance.name)
|
|
209
|
-
logger.info(
|
|
210
|
-
"Registered generator via class",
|
|
211
|
-
class_path=qualified,
|
|
212
|
-
name=instance.name,
|
|
213
|
-
)
|
|
214
|
-
elif "entrypoint" in decl:
|
|
215
|
-
ep_name = decl["entrypoint"]
|
|
216
|
-
options = decl.get("options", {}) or {}
|
|
217
|
-
cls = _resolve_entrypoint(ep_name)
|
|
218
|
-
instance = cls(**options) if options else cls()
|
|
219
|
-
_register_instance(instance, name_override)
|
|
220
|
-
requested_names.add(instance.name)
|
|
221
|
-
logger.info(
|
|
222
|
-
"Registered generator via entrypoint",
|
|
223
|
-
entrypoint=ep_name,
|
|
224
|
-
name=instance.name,
|
|
225
|
-
)
|
|
226
|
-
else:
|
|
227
|
-
raise ValueError(
|
|
228
|
-
"Generator declaration must include one of: import, class, entrypoint"
|
|
229
|
-
)
|
|
230
|
-
|
|
231
|
-
except Exception as e:
|
|
232
|
-
msg = f"Failed to load generator declaration: {e}"
|
|
233
|
-
if strict_mode:
|
|
234
|
-
raise RuntimeError(msg) from e
|
|
235
|
-
logger.error(msg)
|
|
236
|
-
continue
|
|
237
|
-
|
|
238
|
-
# After imports, collect names to enforce allow_unlisted policy
|
|
239
|
-
# requested_names may be incomplete for `import` declarations; fill with registry state
|
|
240
|
-
for name in registry.list_names():
|
|
241
|
-
requested_names.add(name)
|
|
242
|
-
|
|
243
|
-
_enforce_unlisted_policy(requested_names, strict_mode, allow_unlisted)
|
|
244
|
-
|
|
245
|
-
# Final summary
|
|
246
|
-
logger.info(
|
|
247
|
-
"Generators loading complete",
|
|
248
|
-
requested=len(cfg.declarations or []),
|
|
249
|
-
registered=len(registry),
|
|
250
|
-
names=registry.list_names(),
|
|
251
|
-
strict_mode=strict_mode,
|
|
252
|
-
allow_unlisted=allow_unlisted,
|
|
253
|
-
)
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Generator registry system for discovering and managing generators.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
from boards.logging import get_logger
|
|
6
|
-
|
|
7
|
-
from .base import BaseGenerator
|
|
8
|
-
|
|
9
|
-
logger = get_logger(__name__)
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class GeneratorRegistry:
|
|
13
|
-
"""
|
|
14
|
-
Central registry for generator discovery and management.
|
|
15
|
-
|
|
16
|
-
Provides methods to register generators, look them up by name,
|
|
17
|
-
and list available generators by various criteria.
|
|
18
|
-
"""
|
|
19
|
-
|
|
20
|
-
def __init__(self):
|
|
21
|
-
self._generators: dict[str, BaseGenerator] = {}
|
|
22
|
-
|
|
23
|
-
def register(self, generator: BaseGenerator) -> None:
|
|
24
|
-
"""
|
|
25
|
-
Register a generator instance with the registry.
|
|
26
|
-
|
|
27
|
-
Args:
|
|
28
|
-
generator: Generator instance to register
|
|
29
|
-
|
|
30
|
-
Raises:
|
|
31
|
-
ValueError: If a generator with the same name is already registered
|
|
32
|
-
"""
|
|
33
|
-
logger.info("Registering generator", name=generator.name)
|
|
34
|
-
if generator.name in self._generators:
|
|
35
|
-
raise ValueError(f"Generator '{generator.name}' is already registered")
|
|
36
|
-
|
|
37
|
-
self._generators[generator.name] = generator
|
|
38
|
-
|
|
39
|
-
def get(self, name: str) -> BaseGenerator | None:
|
|
40
|
-
"""
|
|
41
|
-
Get a generator by name.
|
|
42
|
-
|
|
43
|
-
Args:
|
|
44
|
-
name: Name of the generator to retrieve
|
|
45
|
-
|
|
46
|
-
Returns:
|
|
47
|
-
BaseGenerator instance or None if not found
|
|
48
|
-
"""
|
|
49
|
-
return self._generators.get(name)
|
|
50
|
-
|
|
51
|
-
def list_all(self) -> list[BaseGenerator]:
|
|
52
|
-
"""
|
|
53
|
-
List all registered generators.
|
|
54
|
-
|
|
55
|
-
Returns:
|
|
56
|
-
List of all generator instances
|
|
57
|
-
"""
|
|
58
|
-
return list(self._generators.values())
|
|
59
|
-
|
|
60
|
-
def list_by_artifact_type(self, artifact_type: str) -> list[BaseGenerator]:
|
|
61
|
-
"""
|
|
62
|
-
List generators that produce a specific artifact type.
|
|
63
|
-
|
|
64
|
-
Args:
|
|
65
|
-
artifact_type: Type of artifact (image, video, audio, text, lora)
|
|
66
|
-
|
|
67
|
-
Returns:
|
|
68
|
-
List of generators that produce the specified artifact type
|
|
69
|
-
"""
|
|
70
|
-
return [
|
|
71
|
-
generator
|
|
72
|
-
for generator in self._generators.values()
|
|
73
|
-
if generator.artifact_type == artifact_type
|
|
74
|
-
]
|
|
75
|
-
|
|
76
|
-
def list_names(self) -> list[str]:
|
|
77
|
-
"""
|
|
78
|
-
List all registered generator names.
|
|
79
|
-
|
|
80
|
-
Returns:
|
|
81
|
-
List of generator names
|
|
82
|
-
"""
|
|
83
|
-
return list(self._generators.keys())
|
|
84
|
-
|
|
85
|
-
def unregister(self, name: str) -> bool:
|
|
86
|
-
"""
|
|
87
|
-
Unregister a generator by name.
|
|
88
|
-
|
|
89
|
-
Args:
|
|
90
|
-
name: Name of the generator to unregister
|
|
91
|
-
|
|
92
|
-
Returns:
|
|
93
|
-
True if the generator was found and removed, False otherwise
|
|
94
|
-
"""
|
|
95
|
-
if name in self._generators:
|
|
96
|
-
del self._generators[name]
|
|
97
|
-
return True
|
|
98
|
-
return False
|
|
99
|
-
|
|
100
|
-
def clear(self) -> None:
|
|
101
|
-
"""Clear all registered generators."""
|
|
102
|
-
self._generators.clear()
|
|
103
|
-
|
|
104
|
-
def __len__(self) -> int:
|
|
105
|
-
"""Return the number of registered generators."""
|
|
106
|
-
return len(self._generators)
|
|
107
|
-
|
|
108
|
-
def __contains__(self, name: str) -> bool:
|
|
109
|
-
"""Check if a generator with the given name is registered."""
|
|
110
|
-
return name in self._generators
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
# Global registry instance
|
|
114
|
-
registry = GeneratorRegistry()
|