@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,172 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Main FastAPI application for Boards backend
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
import os
|
|
6
|
-
from contextlib import asynccontextmanager
|
|
7
|
-
|
|
8
|
-
from fastapi import FastAPI
|
|
9
|
-
from fastapi.middleware.cors import CORSMiddleware
|
|
10
|
-
|
|
11
|
-
from ..config import initialize_generator_api_keys, settings
|
|
12
|
-
from ..database import init_database
|
|
13
|
-
from ..generators.loader import load_generators_from_config
|
|
14
|
-
from ..logging import configure_logging, get_logger
|
|
15
|
-
from ..middleware import LoggingContextMiddleware, TenantRoutingMiddleware
|
|
16
|
-
|
|
17
|
-
# Configure logging before creating logger
|
|
18
|
-
configure_logging(debug=settings.debug)
|
|
19
|
-
logger = get_logger(__name__)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
@asynccontextmanager
|
|
23
|
-
async def lifespan(app: FastAPI):
|
|
24
|
-
"""Application lifespan manager."""
|
|
25
|
-
# Startup
|
|
26
|
-
logger.info("Starting Boards API...")
|
|
27
|
-
init_database()
|
|
28
|
-
logger.info("Database initialized")
|
|
29
|
-
|
|
30
|
-
# Initialize generator API keys from settings
|
|
31
|
-
initialize_generator_api_keys()
|
|
32
|
-
logger.info("Generator API keys initialized")
|
|
33
|
-
|
|
34
|
-
# Load generators based on configuration
|
|
35
|
-
try:
|
|
36
|
-
load_generators_from_config()
|
|
37
|
-
logger.info(
|
|
38
|
-
"Generators configured and registered",
|
|
39
|
-
names=list(
|
|
40
|
-
__import__(
|
|
41
|
-
"boards.generators.registry", fromlist=["registry"]
|
|
42
|
-
).registry.list_names()
|
|
43
|
-
),
|
|
44
|
-
)
|
|
45
|
-
except Exception as e:
|
|
46
|
-
# Fail fast: strict mode default may raise here
|
|
47
|
-
logger.error("Failed to configure generators", error=str(e))
|
|
48
|
-
raise
|
|
49
|
-
|
|
50
|
-
# Run comprehensive startup validation
|
|
51
|
-
try:
|
|
52
|
-
from ..validation import (
|
|
53
|
-
ValidationError,
|
|
54
|
-
get_startup_recommendations,
|
|
55
|
-
validate_startup_configuration,
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
validation_results = await validate_startup_configuration()
|
|
59
|
-
|
|
60
|
-
if not validation_results["overall_valid"]:
|
|
61
|
-
# Log detailed error information
|
|
62
|
-
logger.error(
|
|
63
|
-
"Application configuration validation failed - some features may not work properly",
|
|
64
|
-
database_errors=validation_results.get("database", {}).get("errors", []),
|
|
65
|
-
tenant_errors=validation_results["tenant"].get("errors", []),
|
|
66
|
-
auth_errors=validation_results["auth"].get("errors", []),
|
|
67
|
-
)
|
|
68
|
-
|
|
69
|
-
# In production, we might want to fail hard here
|
|
70
|
-
if settings.environment.lower() in ("production", "prod"):
|
|
71
|
-
raise ValidationError("Critical configuration validation failed in production")
|
|
72
|
-
|
|
73
|
-
# Log recommendations
|
|
74
|
-
recommendations = get_startup_recommendations(validation_results)
|
|
75
|
-
if recommendations:
|
|
76
|
-
logger.info("Configuration recommendations", recommendations=recommendations)
|
|
77
|
-
|
|
78
|
-
except ValidationError:
|
|
79
|
-
# Re-raise validation errors to fail startup
|
|
80
|
-
raise
|
|
81
|
-
except Exception as e:
|
|
82
|
-
logger.error(
|
|
83
|
-
"Unexpected error during startup validation",
|
|
84
|
-
error=str(e),
|
|
85
|
-
note="Application will continue but may have configuration issues",
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
yield
|
|
89
|
-
|
|
90
|
-
# Shutdown
|
|
91
|
-
logger.info("Shutting down Boards API...")
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
def create_app() -> FastAPI:
|
|
95
|
-
"""Create and configure the FastAPI application."""
|
|
96
|
-
|
|
97
|
-
app = FastAPI(
|
|
98
|
-
title="Boards API",
|
|
99
|
-
description="Open-source creative toolkit for AI-generated content",
|
|
100
|
-
version="0.1.0",
|
|
101
|
-
lifespan=lifespan,
|
|
102
|
-
debug=settings.debug,
|
|
103
|
-
)
|
|
104
|
-
|
|
105
|
-
# Add tenant routing middleware first (runs before logging)
|
|
106
|
-
app.add_middleware(TenantRoutingMiddleware)
|
|
107
|
-
|
|
108
|
-
# Add logging context middleware
|
|
109
|
-
app.add_middleware(LoggingContextMiddleware)
|
|
110
|
-
|
|
111
|
-
# CORS configuration
|
|
112
|
-
app.add_middleware(
|
|
113
|
-
CORSMiddleware,
|
|
114
|
-
allow_origins=settings.cors_origins,
|
|
115
|
-
allow_credentials=True,
|
|
116
|
-
allow_methods=["*"],
|
|
117
|
-
allow_headers=["*"],
|
|
118
|
-
)
|
|
119
|
-
|
|
120
|
-
# Health check endpoint
|
|
121
|
-
@app.get("/health")
|
|
122
|
-
async def health_check(): # pyright: ignore [reportUnusedFunction]
|
|
123
|
-
"""Health check endpoint."""
|
|
124
|
-
return {"status": "healthy", "version": "0.1.0"}
|
|
125
|
-
|
|
126
|
-
# GraphQL endpoint (allow disabling for tests)
|
|
127
|
-
if not os.getenv("BOARDS_DISABLE_GRAPHQL"):
|
|
128
|
-
try:
|
|
129
|
-
from ..graphql.schema import create_graphql_router, validate_schema
|
|
130
|
-
|
|
131
|
-
# Validate schema at startup to catch circular reference errors early
|
|
132
|
-
logger.info("Validating GraphQL schema...")
|
|
133
|
-
validate_schema()
|
|
134
|
-
|
|
135
|
-
# Create and mount the GraphQL router
|
|
136
|
-
graphql_router = create_graphql_router()
|
|
137
|
-
app.include_router(graphql_router, prefix="")
|
|
138
|
-
logger.info("GraphQL endpoint initialized successfully", endpoint="/graphql")
|
|
139
|
-
except Exception as e: # pragma: no cover
|
|
140
|
-
logger.error("Failed to initialize GraphQL endpoint", error=str(e))
|
|
141
|
-
# Re-raise to fail fast - server should not start with broken GraphQL
|
|
142
|
-
raise
|
|
143
|
-
|
|
144
|
-
# REST API endpoints (for SSE, webhooks, etc.)
|
|
145
|
-
from .endpoints import jobs, setup, sse, storage, tenant_registration, uploads, webhooks
|
|
146
|
-
|
|
147
|
-
app.include_router(sse.router, prefix="/api/sse", tags=["SSE"])
|
|
148
|
-
app.include_router(jobs.router, prefix="/api/jobs", tags=["Jobs"])
|
|
149
|
-
app.include_router(webhooks.router, prefix="/api/webhooks", tags=["Webhooks"])
|
|
150
|
-
app.include_router(storage.router, prefix="/api/storage", tags=["Storage"])
|
|
151
|
-
app.include_router(setup.router, prefix="/api/setup", tags=["Setup"])
|
|
152
|
-
app.include_router(uploads.router, prefix="/api", tags=["Uploads"])
|
|
153
|
-
app.include_router(
|
|
154
|
-
tenant_registration.router, prefix="/api/tenants", tags=["Tenant Registration"]
|
|
155
|
-
)
|
|
156
|
-
|
|
157
|
-
return app
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
# Create the main application instance
|
|
161
|
-
app = create_app()
|
|
162
|
-
|
|
163
|
-
if __name__ == "__main__":
|
|
164
|
-
import uvicorn
|
|
165
|
-
|
|
166
|
-
uvicorn.run(
|
|
167
|
-
"boards.api.app:app",
|
|
168
|
-
host=settings.api_host,
|
|
169
|
-
port=settings.api_port,
|
|
170
|
-
reload=settings.api_reload,
|
|
171
|
-
log_level=settings.log_level.lower(),
|
|
172
|
-
)
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
"""Authentication dependencies for API endpoints."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
from uuid import UUID
|
|
6
|
-
|
|
7
|
-
from fastapi import Depends, HTTPException
|
|
8
|
-
from pydantic import BaseModel
|
|
9
|
-
|
|
10
|
-
from ..auth import AuthContext, get_auth_context, get_auth_context_optional
|
|
11
|
-
from ..logging import get_logger
|
|
12
|
-
|
|
13
|
-
logger = get_logger(__name__)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class AuthenticatedUser(BaseModel):
|
|
17
|
-
"""Represents an authenticated user."""
|
|
18
|
-
|
|
19
|
-
user_id: UUID
|
|
20
|
-
tenant_id: UUID
|
|
21
|
-
email: str | None = None
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
async def get_current_user(
|
|
25
|
-
auth_context: AuthContext = Depends(get_auth_context),
|
|
26
|
-
) -> AuthenticatedUser:
|
|
27
|
-
"""
|
|
28
|
-
Get the current authenticated user from the auth context.
|
|
29
|
-
|
|
30
|
-
Args:
|
|
31
|
-
auth_context: Authentication context from middleware
|
|
32
|
-
|
|
33
|
-
Returns:
|
|
34
|
-
AuthenticatedUser object with user information
|
|
35
|
-
|
|
36
|
-
Raises:
|
|
37
|
-
HTTPException: If user is not authenticated
|
|
38
|
-
"""
|
|
39
|
-
if not auth_context.is_authenticated or not auth_context.user_id:
|
|
40
|
-
raise HTTPException(
|
|
41
|
-
status_code=401,
|
|
42
|
-
detail="Authentication required",
|
|
43
|
-
headers={"WWW-Authenticate": "Bearer"},
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
return AuthenticatedUser(
|
|
47
|
-
user_id=auth_context.user_id,
|
|
48
|
-
tenant_id=auth_context.tenant_id,
|
|
49
|
-
email=auth_context.principal.get("email") if auth_context.principal else None,
|
|
50
|
-
)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
async def get_current_user_optional(
|
|
54
|
-
auth_context: AuthContext = Depends(get_auth_context_optional),
|
|
55
|
-
) -> AuthenticatedUser | None:
|
|
56
|
-
"""
|
|
57
|
-
Optional authentication - returns None if not authenticated.
|
|
58
|
-
|
|
59
|
-
Use this for endpoints that can work both authenticated and unauthenticated,
|
|
60
|
-
but may provide different functionality based on auth status.
|
|
61
|
-
"""
|
|
62
|
-
if not auth_context.is_authenticated or not auth_context.user_id:
|
|
63
|
-
return None
|
|
64
|
-
|
|
65
|
-
return AuthenticatedUser(
|
|
66
|
-
user_id=auth_context.user_id,
|
|
67
|
-
tenant_id=auth_context.tenant_id,
|
|
68
|
-
email=auth_context.principal.get("email") if auth_context.principal else None,
|
|
69
|
-
)
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
# Legacy support - keep the old function names for backward compatibility
|
|
73
|
-
async def get_auth_context_dependency() -> AuthContext:
|
|
74
|
-
"""Get auth context directly (for advanced use cases)."""
|
|
75
|
-
return await get_auth_context()
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
"""Job submission endpoints."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
from uuid import UUID
|
|
6
|
-
|
|
7
|
-
from fastapi import APIRouter, Depends, HTTPException
|
|
8
|
-
from pydantic import BaseModel
|
|
9
|
-
from sqlalchemy.ext.asyncio import AsyncSession
|
|
10
|
-
|
|
11
|
-
from ...database.connection import get_db_session
|
|
12
|
-
from ...jobs import repository as jobs_repo
|
|
13
|
-
from ...logging import get_logger
|
|
14
|
-
from ...workers.actors import process_generation
|
|
15
|
-
from ..auth import AuthenticatedUser, get_current_user
|
|
16
|
-
|
|
17
|
-
logger = get_logger(__name__)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
router = APIRouter()
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class SubmitGenerationRequest(BaseModel):
|
|
24
|
-
tenant_id: UUID
|
|
25
|
-
board_id: UUID
|
|
26
|
-
user_id: UUID
|
|
27
|
-
generator_name: str
|
|
28
|
-
artifact_type: str
|
|
29
|
-
input_params: dict
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
class SubmitGenerationResponse(BaseModel):
|
|
33
|
-
generation_id: UUID
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
@router.post("/generations", response_model=SubmitGenerationResponse)
|
|
37
|
-
async def submit_generation(
|
|
38
|
-
body: SubmitGenerationRequest,
|
|
39
|
-
db: AsyncSession = Depends(get_db_session),
|
|
40
|
-
current_user: AuthenticatedUser = Depends(get_current_user),
|
|
41
|
-
) -> SubmitGenerationResponse:
|
|
42
|
-
"""Submit a new generation job.
|
|
43
|
-
|
|
44
|
-
Requires authentication. The authenticated user's ID and tenant will be used
|
|
45
|
-
for the generation, overriding any values provided in the request body.
|
|
46
|
-
"""
|
|
47
|
-
try:
|
|
48
|
-
# Validate that user has access to the specified board
|
|
49
|
-
# TODO: Add board access validation logic here
|
|
50
|
-
|
|
51
|
-
# Override user_id and tenant_id with authenticated values for security
|
|
52
|
-
# This prevents users from submitting jobs on behalf of others
|
|
53
|
-
gen = await jobs_repo.create_generation(
|
|
54
|
-
db,
|
|
55
|
-
tenant_id=current_user.tenant_id, # Use authenticated tenant
|
|
56
|
-
board_id=body.board_id,
|
|
57
|
-
user_id=current_user.user_id, # Use authenticated user
|
|
58
|
-
generator_name=body.generator_name,
|
|
59
|
-
artifact_type=body.artifact_type,
|
|
60
|
-
input_params=body.input_params,
|
|
61
|
-
)
|
|
62
|
-
|
|
63
|
-
# Commit the transaction to ensure job is persisted before enqueueing
|
|
64
|
-
await db.commit()
|
|
65
|
-
logger.info(f"Created generation job {gen.id} for user {current_user.user_id}")
|
|
66
|
-
|
|
67
|
-
# Enqueue job for processing
|
|
68
|
-
process_generation.send(str(gen.id))
|
|
69
|
-
logger.info(f"Enqueued generation job {gen.id}")
|
|
70
|
-
|
|
71
|
-
return SubmitGenerationResponse(generation_id=gen.id)
|
|
72
|
-
|
|
73
|
-
except Exception as e:
|
|
74
|
-
logger.error(f"Failed to submit generation: {e}")
|
|
75
|
-
await db.rollback()
|
|
76
|
-
raise HTTPException(status_code=500, detail=f"Failed to submit generation: {str(e)}") from e
|