@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,166 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Generation GraphQL type definitions
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
from datetime import datetime
|
|
6
|
-
from enum import Enum
|
|
7
|
-
from typing import TYPE_CHECKING, Annotated
|
|
8
|
-
from uuid import UUID
|
|
9
|
-
|
|
10
|
-
import strawberry
|
|
11
|
-
|
|
12
|
-
if TYPE_CHECKING:
|
|
13
|
-
from .board import Board
|
|
14
|
-
from .user import User
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@strawberry.enum
|
|
18
|
-
class ArtifactType(Enum):
|
|
19
|
-
"""Artifact type enumeration."""
|
|
20
|
-
|
|
21
|
-
IMAGE = "image"
|
|
22
|
-
VIDEO = "video"
|
|
23
|
-
AUDIO = "audio"
|
|
24
|
-
TEXT = "text"
|
|
25
|
-
LORA = "lora"
|
|
26
|
-
MODEL = "model"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
@strawberry.enum
|
|
30
|
-
class GenerationStatus(Enum):
|
|
31
|
-
"""Generation status enumeration."""
|
|
32
|
-
|
|
33
|
-
PENDING = "pending"
|
|
34
|
-
PROCESSING = "processing"
|
|
35
|
-
COMPLETED = "completed"
|
|
36
|
-
FAILED = "failed"
|
|
37
|
-
CANCELLED = "cancelled"
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
@strawberry.type
|
|
41
|
-
class AdditionalFile:
|
|
42
|
-
"""Additional file associated with a generation."""
|
|
43
|
-
|
|
44
|
-
url: str
|
|
45
|
-
type: str
|
|
46
|
-
metadata: strawberry.scalars.JSON # type: ignore[reportInvalidTypeForm]
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
@strawberry.input
|
|
50
|
-
class UploadArtifactInput:
|
|
51
|
-
"""Input for uploading an artifact from URL."""
|
|
52
|
-
|
|
53
|
-
board_id: UUID
|
|
54
|
-
artifact_type: ArtifactType
|
|
55
|
-
file_url: str | None = None
|
|
56
|
-
original_filename: str | None = None
|
|
57
|
-
user_description: str | None = None
|
|
58
|
-
parent_generation_id: UUID | None = None
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
@strawberry.type
|
|
62
|
-
class ArtifactLineage:
|
|
63
|
-
"""Represents a single input artifact relationship with role metadata."""
|
|
64
|
-
|
|
65
|
-
generation_id: UUID
|
|
66
|
-
role: str
|
|
67
|
-
artifact_type: ArtifactType
|
|
68
|
-
|
|
69
|
-
@strawberry.field
|
|
70
|
-
async def generation(
|
|
71
|
-
self, info: strawberry.Info
|
|
72
|
-
) -> Annotated["Generation", strawberry.lazy(".generation")] | None:
|
|
73
|
-
"""Resolve the full generation object for this input."""
|
|
74
|
-
from ..resolvers.lineage import resolve_generation_by_id
|
|
75
|
-
|
|
76
|
-
return await resolve_generation_by_id(info, self.generation_id)
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
@strawberry.type
|
|
80
|
-
class AncestryNode:
|
|
81
|
-
"""Represents a node in the ancestry tree."""
|
|
82
|
-
|
|
83
|
-
generation: Annotated["Generation", strawberry.lazy(".generation")]
|
|
84
|
-
depth: int
|
|
85
|
-
role: str | None
|
|
86
|
-
parents: list["AncestryNode"]
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
@strawberry.type
|
|
90
|
-
class DescendantNode:
|
|
91
|
-
"""Represents a node in the descendants tree."""
|
|
92
|
-
|
|
93
|
-
generation: Annotated["Generation", strawberry.lazy(".generation")]
|
|
94
|
-
depth: int
|
|
95
|
-
role: str | None
|
|
96
|
-
children: list["DescendantNode"]
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
@strawberry.type
|
|
100
|
-
class Generation:
|
|
101
|
-
"""Generation type for GraphQL API."""
|
|
102
|
-
|
|
103
|
-
id: UUID
|
|
104
|
-
tenant_id: UUID
|
|
105
|
-
board_id: UUID
|
|
106
|
-
user_id: UUID
|
|
107
|
-
|
|
108
|
-
# Generation details
|
|
109
|
-
generator_name: str
|
|
110
|
-
artifact_type: ArtifactType
|
|
111
|
-
|
|
112
|
-
# Storage
|
|
113
|
-
storage_url: str | None
|
|
114
|
-
thumbnail_url: str | None
|
|
115
|
-
additional_files: list[AdditionalFile]
|
|
116
|
-
|
|
117
|
-
# Parameters and metadata
|
|
118
|
-
input_params: strawberry.scalars.JSON # type: ignore[reportInvalidTypeForm]
|
|
119
|
-
output_metadata: strawberry.scalars.JSON # type: ignore[reportInvalidTypeForm]
|
|
120
|
-
|
|
121
|
-
# Job tracking
|
|
122
|
-
external_job_id: str | None
|
|
123
|
-
status: GenerationStatus
|
|
124
|
-
progress: float
|
|
125
|
-
error_message: str | None
|
|
126
|
-
|
|
127
|
-
# Timestamps
|
|
128
|
-
started_at: datetime | None
|
|
129
|
-
completed_at: datetime | None
|
|
130
|
-
created_at: datetime
|
|
131
|
-
updated_at: datetime
|
|
132
|
-
|
|
133
|
-
@strawberry.field
|
|
134
|
-
async def board(self, info: strawberry.Info) -> Annotated["Board", strawberry.lazy(".board")]:
|
|
135
|
-
"""Get the board this generation belongs to."""
|
|
136
|
-
from ..resolvers.generation import resolve_generation_board
|
|
137
|
-
|
|
138
|
-
return await resolve_generation_board(self, info)
|
|
139
|
-
|
|
140
|
-
@strawberry.field
|
|
141
|
-
async def user(self, info: strawberry.Info) -> Annotated["User", strawberry.lazy(".user")]:
|
|
142
|
-
"""Get the user who created this generation."""
|
|
143
|
-
from ..resolvers.generation import resolve_generation_user
|
|
144
|
-
|
|
145
|
-
return await resolve_generation_user(self, info)
|
|
146
|
-
|
|
147
|
-
@strawberry.field
|
|
148
|
-
async def input_artifacts(self, info: strawberry.Info) -> list[ArtifactLineage]:
|
|
149
|
-
"""Get input artifacts with role metadata."""
|
|
150
|
-
from ..resolvers.lineage import resolve_input_artifacts
|
|
151
|
-
|
|
152
|
-
return await resolve_input_artifacts(self, info)
|
|
153
|
-
|
|
154
|
-
@strawberry.field
|
|
155
|
-
async def ancestry(self, info: strawberry.Info, max_depth: int = 25) -> AncestryNode:
|
|
156
|
-
"""Get complete ancestry tree up to max_depth levels."""
|
|
157
|
-
from ..resolvers.lineage import resolve_ancestry
|
|
158
|
-
|
|
159
|
-
return await resolve_ancestry(self, info, max_depth)
|
|
160
|
-
|
|
161
|
-
@strawberry.field
|
|
162
|
-
async def descendants(self, info: strawberry.Info, max_depth: int = 25) -> DescendantNode:
|
|
163
|
-
"""Get complete descendants tree up to max_depth levels."""
|
|
164
|
-
from ..resolvers.lineage import resolve_descendants
|
|
165
|
-
|
|
166
|
-
return await resolve_descendants(self, info, max_depth)
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Generator GraphQL type definitions
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
import strawberry
|
|
6
|
-
|
|
7
|
-
from .generation import ArtifactType
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
@strawberry.type
|
|
11
|
-
class GeneratorInfo:
|
|
12
|
-
"""Information about an available generator."""
|
|
13
|
-
|
|
14
|
-
name: str
|
|
15
|
-
description: str
|
|
16
|
-
artifact_type: ArtifactType
|
|
17
|
-
input_schema: strawberry.scalars.JSON # type: ignore[reportInvalidTypeForm]
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
User GraphQL type definitions
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
from datetime import datetime
|
|
6
|
-
from typing import TYPE_CHECKING, Annotated
|
|
7
|
-
from uuid import UUID
|
|
8
|
-
|
|
9
|
-
import strawberry
|
|
10
|
-
|
|
11
|
-
if TYPE_CHECKING:
|
|
12
|
-
from .board import Board
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
@strawberry.type
|
|
16
|
-
class User:
|
|
17
|
-
"""User type for GraphQL API."""
|
|
18
|
-
|
|
19
|
-
id: UUID
|
|
20
|
-
tenant_id: UUID
|
|
21
|
-
auth_provider: str
|
|
22
|
-
auth_subject: str
|
|
23
|
-
email: str | None
|
|
24
|
-
display_name: str | None
|
|
25
|
-
avatar_url: str | None
|
|
26
|
-
created_at: datetime
|
|
27
|
-
updated_at: datetime
|
|
28
|
-
|
|
29
|
-
@strawberry.field
|
|
30
|
-
async def boards(
|
|
31
|
-
self, info: strawberry.Info
|
|
32
|
-
) -> list[Annotated["Board", strawberry.lazy(".board")]]: # noqa: E501
|
|
33
|
-
"""Get boards owned by this user."""
|
|
34
|
-
# TODO: Implement data loader
|
|
35
|
-
from ..resolvers.user import resolve_user_boards
|
|
36
|
-
|
|
37
|
-
return await resolve_user_boards(self, info)
|
|
38
|
-
|
|
39
|
-
@strawberry.field
|
|
40
|
-
async def member_boards(
|
|
41
|
-
self, info: strawberry.Info
|
|
42
|
-
) -> list[Annotated["Board", strawberry.lazy(".board")]]: # noqa: E501
|
|
43
|
-
"""Get boards where user is a member."""
|
|
44
|
-
# TODO: Implement data loader
|
|
45
|
-
from ..resolvers.user import resolve_user_member_boards
|
|
46
|
-
|
|
47
|
-
return await resolve_user_member_boards(self, info)
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
"""Repository helpers for Generations job lifecycle."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
from datetime import UTC, datetime
|
|
6
|
-
from decimal import Decimal
|
|
7
|
-
from typing import Any
|
|
8
|
-
from uuid import UUID
|
|
9
|
-
|
|
10
|
-
from sqlalchemy import select, update
|
|
11
|
-
from sqlalchemy.ext.asyncio import AsyncSession
|
|
12
|
-
|
|
13
|
-
from ..dbmodels import Generations
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
async def get_generation(session: AsyncSession, generation_id: str | UUID) -> Generations:
|
|
17
|
-
stmt = select(Generations).where(Generations.id == str(generation_id))
|
|
18
|
-
res = await session.execute(stmt)
|
|
19
|
-
row = res.scalar_one()
|
|
20
|
-
return row
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
async def update_progress(
|
|
24
|
-
session: AsyncSession,
|
|
25
|
-
generation_id: str | UUID,
|
|
26
|
-
*,
|
|
27
|
-
status: str,
|
|
28
|
-
progress: float,
|
|
29
|
-
error_message: str | None = None,
|
|
30
|
-
) -> None:
|
|
31
|
-
now = datetime.now(UTC)
|
|
32
|
-
stmt = (
|
|
33
|
-
update(Generations)
|
|
34
|
-
.where(Generations.id == str(generation_id))
|
|
35
|
-
.values(
|
|
36
|
-
status=status,
|
|
37
|
-
progress=progress,
|
|
38
|
-
error_message=error_message,
|
|
39
|
-
updated_at=now,
|
|
40
|
-
started_at=now if status == "processing" else Generations.started_at,
|
|
41
|
-
completed_at=(now if status in {"completed", "failed", "cancelled"} else None),
|
|
42
|
-
)
|
|
43
|
-
)
|
|
44
|
-
await session.execute(stmt)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
async def create_generation(
|
|
48
|
-
session: AsyncSession,
|
|
49
|
-
*,
|
|
50
|
-
tenant_id: UUID,
|
|
51
|
-
board_id: UUID,
|
|
52
|
-
user_id: UUID,
|
|
53
|
-
generator_name: str,
|
|
54
|
-
artifact_type: str,
|
|
55
|
-
input_params: dict,
|
|
56
|
-
) -> Generations:
|
|
57
|
-
gen = Generations()
|
|
58
|
-
gen.tenant_id = tenant_id
|
|
59
|
-
gen.board_id = board_id
|
|
60
|
-
gen.user_id = user_id
|
|
61
|
-
gen.generator_name = generator_name
|
|
62
|
-
gen.artifact_type = artifact_type
|
|
63
|
-
gen.input_params = input_params
|
|
64
|
-
gen.status = "pending"
|
|
65
|
-
gen.progress = Decimal(0.0)
|
|
66
|
-
session.add(gen)
|
|
67
|
-
await session.flush()
|
|
68
|
-
return gen
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
async def set_external_job_id(
|
|
72
|
-
session: AsyncSession, generation_id: str | UUID, external_job_id: str
|
|
73
|
-
) -> None:
|
|
74
|
-
stmt = (
|
|
75
|
-
update(Generations)
|
|
76
|
-
.where(Generations.id == str(generation_id))
|
|
77
|
-
.values(external_job_id=external_job_id)
|
|
78
|
-
)
|
|
79
|
-
await session.execute(stmt)
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
async def finalize_success(
|
|
83
|
-
session: AsyncSession,
|
|
84
|
-
generation_id: str | UUID,
|
|
85
|
-
*,
|
|
86
|
-
storage_url: str | None = None,
|
|
87
|
-
thumbnail_url: str | None = None,
|
|
88
|
-
output_metadata: dict[str, Any] | None = None,
|
|
89
|
-
) -> None:
|
|
90
|
-
now = datetime.now(UTC)
|
|
91
|
-
stmt = (
|
|
92
|
-
update(Generations)
|
|
93
|
-
.where(Generations.id == str(generation_id))
|
|
94
|
-
.values(
|
|
95
|
-
status="completed",
|
|
96
|
-
progress=100.0,
|
|
97
|
-
storage_url=storage_url,
|
|
98
|
-
thumbnail_url=thumbnail_url,
|
|
99
|
-
output_metadata=output_metadata or {},
|
|
100
|
-
updated_at=now,
|
|
101
|
-
completed_at=now,
|
|
102
|
-
)
|
|
103
|
-
)
|
|
104
|
-
await session.execute(stmt)
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
async def create_batch_generation(
|
|
108
|
-
session: AsyncSession,
|
|
109
|
-
*,
|
|
110
|
-
tenant_id: UUID,
|
|
111
|
-
board_id: UUID,
|
|
112
|
-
user_id: UUID,
|
|
113
|
-
generator_name: str,
|
|
114
|
-
artifact_type: str,
|
|
115
|
-
input_params: dict,
|
|
116
|
-
batch_id: str,
|
|
117
|
-
batch_index: int,
|
|
118
|
-
) -> str:
|
|
119
|
-
"""Create a batch generation record for multi-output generators.
|
|
120
|
-
|
|
121
|
-
This creates a new generation record that is part of a batch, with
|
|
122
|
-
batch metadata stored in output_metadata.
|
|
123
|
-
|
|
124
|
-
Args:
|
|
125
|
-
session: Database session
|
|
126
|
-
tenant_id: Tenant ID
|
|
127
|
-
board_id: Board ID
|
|
128
|
-
user_id: User ID
|
|
129
|
-
generator_name: Name of the generator
|
|
130
|
-
artifact_type: Type of artifact (image, video, etc.)
|
|
131
|
-
input_params: Input parameters (same as primary generation)
|
|
132
|
-
batch_id: Unique ID for this batch
|
|
133
|
-
batch_index: Index of this output in the batch
|
|
134
|
-
|
|
135
|
-
Returns:
|
|
136
|
-
ID of the created generation record
|
|
137
|
-
"""
|
|
138
|
-
gen = Generations()
|
|
139
|
-
gen.tenant_id = tenant_id
|
|
140
|
-
gen.board_id = board_id
|
|
141
|
-
gen.user_id = user_id
|
|
142
|
-
gen.generator_name = generator_name
|
|
143
|
-
gen.artifact_type = artifact_type
|
|
144
|
-
gen.input_params = input_params
|
|
145
|
-
gen.status = "processing"
|
|
146
|
-
gen.progress = Decimal(0.0)
|
|
147
|
-
gen.output_metadata = {
|
|
148
|
-
"batch_id": batch_id,
|
|
149
|
-
"batch_index": batch_index,
|
|
150
|
-
}
|
|
151
|
-
session.add(gen)
|
|
152
|
-
await session.flush()
|
|
153
|
-
return str(gen.id)
|
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Centralized logging configuration using structlog
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
import base64
|
|
6
|
-
import logging
|
|
7
|
-
import secrets
|
|
8
|
-
import sys
|
|
9
|
-
import time
|
|
10
|
-
from contextvars import ContextVar
|
|
11
|
-
from typing import Any
|
|
12
|
-
|
|
13
|
-
import structlog
|
|
14
|
-
from fastapi import Request
|
|
15
|
-
|
|
16
|
-
# Context variables for request tracking
|
|
17
|
-
request_id_ctx: ContextVar[str | None] = ContextVar("request_id", default=None)
|
|
18
|
-
user_id_ctx: ContextVar[str | None] = ContextVar("user_id", default=None)
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
class RequestContextFilter:
|
|
22
|
-
"""Add request context to log records."""
|
|
23
|
-
|
|
24
|
-
def __call__(self, logger: Any, method_name: str, event_dict: dict[str, Any]) -> dict[str, Any]:
|
|
25
|
-
"""Add request context to the event dict."""
|
|
26
|
-
# Suppress unused parameter warnings - these are required by structlog interface
|
|
27
|
-
_ = logger, method_name
|
|
28
|
-
|
|
29
|
-
request_id = request_id_ctx.get()
|
|
30
|
-
user_id = user_id_ctx.get()
|
|
31
|
-
|
|
32
|
-
if request_id:
|
|
33
|
-
event_dict["request_id"] = request_id
|
|
34
|
-
|
|
35
|
-
if user_id:
|
|
36
|
-
event_dict["user_id"] = user_id
|
|
37
|
-
|
|
38
|
-
return event_dict
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
def configure_logging(debug: bool = False) -> None:
|
|
42
|
-
"""Configure structlog with appropriate processors and formatters.
|
|
43
|
-
|
|
44
|
-
Args:
|
|
45
|
-
debug: If True, use human-readable console output. If False, use JSON.
|
|
46
|
-
"""
|
|
47
|
-
|
|
48
|
-
# Determine log level
|
|
49
|
-
log_level = logging.DEBUG if debug else logging.INFO
|
|
50
|
-
|
|
51
|
-
# Configure stdlib logging
|
|
52
|
-
logging.basicConfig(
|
|
53
|
-
level=log_level,
|
|
54
|
-
stream=sys.stdout,
|
|
55
|
-
format="%(message)s",
|
|
56
|
-
force=True,
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
# Configure structlog processors
|
|
60
|
-
processors = [
|
|
61
|
-
# Filter out keys with underscores (internal)
|
|
62
|
-
structlog.stdlib.filter_by_level,
|
|
63
|
-
# Add logger name to event dict
|
|
64
|
-
structlog.stdlib.add_logger_name,
|
|
65
|
-
# Add log level to event dict
|
|
66
|
-
structlog.stdlib.add_log_level,
|
|
67
|
-
# Add request context
|
|
68
|
-
RequestContextFilter(),
|
|
69
|
-
# Add timestamp
|
|
70
|
-
structlog.processors.TimeStamper(fmt="ISO", utc=True),
|
|
71
|
-
# Perform %-style string formatting
|
|
72
|
-
structlog.stdlib.PositionalArgumentsFormatter(),
|
|
73
|
-
# Stack info processor (for exceptions)
|
|
74
|
-
structlog.processors.StackInfoRenderer(),
|
|
75
|
-
# Exception info processor
|
|
76
|
-
structlog.processors.format_exc_info,
|
|
77
|
-
# Unicode decoder processor
|
|
78
|
-
structlog.processors.UnicodeDecoder(),
|
|
79
|
-
]
|
|
80
|
-
|
|
81
|
-
if debug:
|
|
82
|
-
# Development: human-readable console output
|
|
83
|
-
processors.append(structlog.dev.ConsoleRenderer(colors=True))
|
|
84
|
-
else:
|
|
85
|
-
# Production: JSON output
|
|
86
|
-
processors.append(structlog.processors.JSONRenderer())
|
|
87
|
-
|
|
88
|
-
# Configure structlog
|
|
89
|
-
structlog.configure(
|
|
90
|
-
processors=processors,
|
|
91
|
-
wrapper_class=structlog.stdlib.BoundLogger,
|
|
92
|
-
logger_factory=structlog.stdlib.LoggerFactory(),
|
|
93
|
-
context_class=dict,
|
|
94
|
-
cache_logger_on_first_use=True,
|
|
95
|
-
)
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
def get_logger(name: str) -> structlog.BoundLogger:
|
|
99
|
-
"""Get a structlog logger instance.
|
|
100
|
-
|
|
101
|
-
Args:
|
|
102
|
-
name: Logger name (typically __name__)
|
|
103
|
-
|
|
104
|
-
Returns:
|
|
105
|
-
Configured structlog logger
|
|
106
|
-
"""
|
|
107
|
-
return structlog.get_logger(name)
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
def generate_request_id() -> str:
|
|
111
|
-
"""Generate a compact, secure request ID with timestamp and randomness.
|
|
112
|
-
|
|
113
|
-
Uses microsecond precision timestamp with added randomness for security.
|
|
114
|
-
Format: 11-character base64 string (e.g., 'Ab3X9mF2xYz')
|
|
115
|
-
|
|
116
|
-
Provides high uniqueness probability while preventing predictable enumeration.
|
|
117
|
-
"""
|
|
118
|
-
# Get microseconds since epoch (8 bytes when encoded as int64)
|
|
119
|
-
timestamp_us = int(time.time() * 1_000_000)
|
|
120
|
-
|
|
121
|
-
# Add 2 bytes of cryptographically secure randomness
|
|
122
|
-
random_bytes = secrets.token_bytes(2)
|
|
123
|
-
|
|
124
|
-
# Convert timestamp to bytes (8 bytes for int64) and combine with random bytes
|
|
125
|
-
timestamp_bytes = timestamp_us.to_bytes(8, byteorder="big")
|
|
126
|
-
combined_bytes = timestamp_bytes + random_bytes
|
|
127
|
-
|
|
128
|
-
# Encode as base64 and strip padding
|
|
129
|
-
b64 = base64.urlsafe_b64encode(combined_bytes).decode("ascii").rstrip("=")
|
|
130
|
-
|
|
131
|
-
return b64
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
def set_request_context(request_id: str | None = None, user_id: str | None = None) -> None:
|
|
135
|
-
"""Set request context variables.
|
|
136
|
-
|
|
137
|
-
Args:
|
|
138
|
-
request_id: Request ID to set (generates one if None)
|
|
139
|
-
user_id: User ID to set
|
|
140
|
-
"""
|
|
141
|
-
if request_id is None:
|
|
142
|
-
request_id = generate_request_id()
|
|
143
|
-
|
|
144
|
-
request_id_ctx.set(request_id)
|
|
145
|
-
if user_id is not None:
|
|
146
|
-
user_id_ctx.set(user_id)
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
def clear_request_context() -> None:
|
|
150
|
-
"""Clear request context variables."""
|
|
151
|
-
request_id_ctx.set(None)
|
|
152
|
-
user_id_ctx.set(None)
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
def get_request_id() -> str | None:
|
|
156
|
-
"""Get the current request ID."""
|
|
157
|
-
return request_id_ctx.get()
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
def get_user_id() -> str | None:
|
|
161
|
-
"""Get the current user ID."""
|
|
162
|
-
return user_id_ctx.get()
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
def extract_user_id_from_request(request: Request) -> str | None:
|
|
166
|
-
"""Extract user ID from FastAPI request.
|
|
167
|
-
|
|
168
|
-
This should be customized based on your authentication implementation.
|
|
169
|
-
|
|
170
|
-
Args:
|
|
171
|
-
request: FastAPI request object
|
|
172
|
-
|
|
173
|
-
Returns:
|
|
174
|
-
User ID if authenticated, None otherwise
|
|
175
|
-
"""
|
|
176
|
-
# TODO: Implement based on your auth strategy
|
|
177
|
-
# Examples:
|
|
178
|
-
# - JWT token in Authorization header
|
|
179
|
-
# - Session data
|
|
180
|
-
# - Supabase auth token
|
|
181
|
-
|
|
182
|
-
# For now, look for a user ID in headers (customize as needed)
|
|
183
|
-
auth_header = request.headers.get("authorization")
|
|
184
|
-
if auth_header:
|
|
185
|
-
# This is a placeholder - implement actual token parsing
|
|
186
|
-
# For example, if using Bearer tokens:
|
|
187
|
-
# if auth_header.startswith("Bearer "):
|
|
188
|
-
# token = auth_header[7:]
|
|
189
|
-
# # Parse JWT token to extract user_id
|
|
190
|
-
# return parsed_user_id
|
|
191
|
-
|
|
192
|
-
# For now, return None until auth is implemented
|
|
193
|
-
return None
|
|
194
|
-
|
|
195
|
-
return None
|