from __future__ import annotations from dataclasses import dataclass from app.ai.service import AiStudioService from app.brand.repositories.brand_repository import BrandKitRepository from app.brand.services.brand_service import BrandKitService from app.analytics.service import AnalyticsDomainService from app.analytics.workers.sync import AnalyticsSyncWorker from app.copilot.actions import CopilotActionRegistry from app.copilot.planner import CopilotPlanner from app.copilot.repository import CopilotRepository from app.copilot.service import CopilotService from app.core.config import Settings from app.generation.model_registry import GenerationModelRegistration, GenerationModelRegistry from app.generation.providers.flux import ( FLUX_BASE_MODEL_ID, FLUX_DISTILLED_MODEL_ID, FLUX_MODEL_CAPABILITY, FLUX_PROVIDER_ID, FLUX_TASK, FluxProviderAdapter, ) from app.generation.providers.registry import GenerationProviderRegistry from app.generation.providers.wan import WAN_MODEL_CAPABILITY, WAN_PROVIDER_ID, WanProviderAdapter from app.generation.repositories.generation import GenerationRepository from app.generation.services.generation_service import GenerationService from app.generation.services.output_ingestion import GenerationOutputIngestor from app.generation.workers.generation_worker import GenerationWorker from app.projects.repositories.editor_repository import ProjectEditorRepository from app.projects.repositories.project_repository import ProjectRepository from app.projects.repositories.render_repository import ProjectRenderRepository from app.projects.repositories.collaboration_repository import CollaborationRepository from app.projects.repositories.approval_repository import ApprovalRepository from app.projects.services.editor_service import ProjectEditorService from app.projects.services.project_service import ProjectService from app.projects.services.collaboration_service import CollaborationService from app.projects.services.approval_service import ApprovalService from app.projects.services.render_service import ProjectRenderService from app.projects.workers.render_worker import ProjectRenderWorker from app.security.assets import CanonicalAssetService from app.security.audit import AuditService from app.security.database import SecurityDatabase from app.security.rate_limit import APIKeyRateLimiter from app.security.service import APIKeyService from app.security.tenancy import TenantService from app.services.cleanup import CleanupService from app.services.downloader import Downloader from app.services.ffmpeg_service import FFmpegService from app.services.ffprobe_service import FFprobeService from app.services.input_resolver import InputResolver from app.services.media_service import MediaProcessor from app.services.validator import MediaValidator from app.services.whisper_service import WhisperService from app.services.ytdlp_service import YTDLPService from app.social.database import SocialDatabase from app.social.oauth.encryption import TokenCipher from app.social.oauth.state import OAuthStateService from app.social.providers.registry import build_provider_registry from app.social.repositories.accounts import AccountRepository from app.social.repositories.assets import SocialMediaAssetRepository from app.social.repositories.batches import PublishingBatchRepository from app.social.repositories.jobs import JobRepository from app.social.repositories.posts import PostRepository from app.social.repositories.tokens import TokenRepository from app.social.services.account_service import AccountService from app.social.services.analytics_service import AnalyticsService from app.social.services.audit_service import SocialAuditService from app.social.services.job_service import JobService from app.social.services.media_asset_service import SocialMediaAssetService from app.social.services.oauth_service import OAuthService from app.social.services.publishing_operations_service import PublishingOperationsService from app.social.services.publishing_service import PublishingService from app.social.services.scheduling_service import SchedulingService from app.social.services.social_service import SocialService from app.social.services.token_service import TokenService from app.templates.executor import OperationExecutor, TemplateExecutor from app.templates.loader import TemplateLoader from app.templates.marketplace_repository import MarketplaceTemplateRepository from app.templates.marketplace_service import MarketplaceTemplateService from app.templates.registry import TemplateRegistry from app.templates.validator import TemplateValidator from app.analytics.repository import AnalyticsRepository from app.projects.repositories.notification_repository import NotificationRepository from app.projects.services.notification_service import NotificationService @dataclass(slots=True) class Container: settings: Settings cleanup: CleanupService validator: MediaValidator downloader: Downloader ytdlp: YTDLPService ffmpeg: FFmpegService ffprobe: FFprobeService whisper: WhisperService resolver: InputResolver processor: MediaProcessor template_registry: TemplateRegistry template_executor: TemplateExecutor template_marketplace: MarketplaceTemplateService security_database: SecurityDatabase tenants: TenantService assets: CanonicalAssetService api_keys: APIKeyService rate_limiter: APIKeyRateLimiter audit: AuditService social: SocialService ai: AiStudioService copilot: CopilotService generation: GenerationService generation_models: GenerationModelRegistry generation_worker: GenerationWorker projects: ProjectService editor: ProjectEditorService renders: ProjectRenderService render_worker: ProjectRenderWorker analytics: AnalyticsDomainService analytics_worker: AnalyticsSyncWorker brand_kits: BrandKitService collaboration: CollaborationService approval: ApprovalService notifications: NotificationService def build_container(settings: Settings) -> Container: security_database = SecurityDatabase( settings.database_url, auto_migrate=settings.security_auto_migrate ) tenants = TenantService(security_database) assets = CanonicalAssetService(security_database) api_keys = APIKeyService(security_database, settings, tenants) rate_limiter = APIKeyRateLimiter(security_database) audit = AuditService(security_database) brand_repository = BrandKitRepository(security_database) brand_kits = BrandKitService(brand_repository, assets, audit) projects = ProjectService(ProjectRepository(security_database), assets, audit, brand_kits) collaboration = CollaborationService(CollaborationRepository(security_database)) approval = ApprovalService(ApprovalRepository(security_database), ProjectEditorRepository(security_database)) notifications = NotificationService(NotificationRepository(security_database)) cleanup = CleanupService(settings) # Generation output validation shares the established FFprobe/validator # services. Construct them before the output ingestor, without changing # existing media or social provider behavior. validator = MediaValidator(settings) ffprobe = FFprobeService(settings) wan = WanProviderAdapter.from_settings(settings) flux = FluxProviderAdapter.from_settings(settings) generation_providers = GenerationProviderRegistry([wan, flux]) generation_models = GenerationModelRegistry( [ GenerationModelRegistration( provider_id=WAN_PROVIDER_ID, model=WAN_MODEL_CAPABILITY, configuration_reference="wan-space", metadata={ "underlying_model_id": "Wan-AI/Wan2.2-I2V-A14B-Diffusers", "task": "image-to-video", "fps": 16, }, ), GenerationModelRegistration( provider_id=FLUX_PROVIDER_ID, model=FLUX_MODEL_CAPABILITY, configuration_reference="flux-space", metadata={ "task": FLUX_TASK, "license": "Apache-2.0", "models": { "distilled": FLUX_DISTILLED_MODEL_ID, "base": FLUX_BASE_MODEL_ID, }, }, ), ] ) generation = GenerationService( settings=settings, database=security_database, assets=assets, repository=GenerationRepository(security_database), providers=generation_providers, models=generation_models, output_ingestor=GenerationOutputIngestor( settings=settings, cleanup=cleanup, assets=assets, ffprobe=ffprobe, validator=validator, ), ) generation_worker = GenerationWorker( settings=settings, generation=generation, assets=assets, cleanup=cleanup, audit=audit, ) ai = AiStudioService(generation, projects, assets, audit) # Social publishing validates the same file-backed outputs as the normal # media pipeline, so build those shared services before wiring Social. downloader = Downloader(settings, validator) ytdlp = YTDLPService(settings, validator) ffmpeg = FFmpegService(settings) editor_repository = ProjectEditorRepository(security_database) editor = ProjectEditorService( editor_repository, assets, audit, state_max_bytes=settings.editor_state_max_bytes, max_tracks=settings.render_max_tracks, max_clips=settings.render_max_clips, max_duration_seconds=settings.render_max_duration_seconds, ) render_repository = ProjectRenderRepository(security_database) renders = ProjectRenderService( settings, render_repository, editor_repository, assets, cleanup, audit ) render_worker = ProjectRenderWorker( settings, render_repository, renders, ffmpeg, cleanup, audit ) template_marketplace = MarketplaceTemplateService( MarketplaceTemplateRepository(security_database), assets, ai, audit ) copilot_actions = CopilotActionRegistry( projects=projects, assets=assets, editor=editor, renders=renders, ai=ai, templates=template_marketplace, ) copilot = CopilotService( repository=CopilotRepository(security_database), planner=CopilotPlanner(), actions=copilot_actions, projects=projects, assets=assets, editor=editor, ai=ai, audit=audit, ) whisper = WhisperService(settings) social_database = SocialDatabase(settings) providers = build_provider_registry(settings) account_repository = AccountRepository(social_database) post_repository = PostRepository(social_database) token_cipher = TokenCipher( settings.social_oauth_encryption_key.get_secret_value() if settings.social_oauth_encryption_key else None ) job_repository = JobRepository(social_database, token_cipher) token_service = TokenService( TokenRepository(social_database), settings, token_cipher, ) account_service = AccountService(account_repository, token_service, providers) social_audit = SocialAuditService(social_database) oauth_service = OAuthService( settings, providers, OAuthStateService(social_database, token_service.cipher), account_service, social_audit, ) social_media_assets = SocialMediaAssetService( settings, SocialMediaAssetRepository(social_database), assets, cleanup, ffprobe, validator ) publishing_service = PublishingService( settings, post_repository, job_repository, account_repository, providers, social_media_assets, oauth_service, brand_kits, projects, ) scheduling_service = SchedulingService(post_repository, social_media_assets) social_analytics = AnalyticsService( social_database, account_repository, providers, oauth_service ) social = SocialService( settings=settings, database=social_database, accounts=account_service, oauth=oauth_service, publishing=publishing_service, operations=PublishingOperationsService( security_database=security_database, posts=post_repository, jobs=job_repository, accounts=account_repository, batches=PublishingBatchRepository(social_database), publishing=publishing_service, scheduling=scheduling_service, audit=social_audit, ), scheduling=scheduling_service, jobs=JobService(job_repository), media_assets=social_media_assets, analytics=social_analytics, audit=social_audit, ) analytics = AnalyticsDomainService( AnalyticsRepository(social_database), providers, social_analytics, account_repository, social_audit, projects, ) brand_repository = BrandKitRepository(security_database) brand_kits = BrandKitService(brand_repository, assets, audit) analytics_worker = AnalyticsSyncWorker( analytics, social_database, interval_seconds=settings.social_scheduler_interval_seconds, ) copilot_actions.analytics = analytics copilot_actions.publishing = social.publishing copilot_actions.scheduling = social.scheduling resolver = InputResolver(settings, cleanup, downloader, ytdlp, validator) processor = MediaProcessor( settings, resolver, cleanup, validator, ffmpeg, ffprobe, ytdlp, whisper, assets ) operation_executor = OperationExecutor(processor) template_validator = TemplateValidator(operation_executor.supported_operations) template_registry = TemplateRegistry( TemplateLoader(settings.template_dir, template_validator), template_validator ) template_executor = TemplateExecutor(template_registry, operation_executor, processor) return Container( settings=settings, cleanup=cleanup, validator=validator, downloader=downloader, ytdlp=ytdlp, ffmpeg=ffmpeg, ffprobe=ffprobe, whisper=whisper, resolver=resolver, processor=processor, template_registry=template_registry, template_executor=template_executor, template_marketplace=template_marketplace, security_database=security_database, tenants=tenants, assets=assets, api_keys=api_keys, rate_limiter=rate_limiter, audit=audit, social=social, ai=ai, copilot=copilot, generation=generation, generation_models=generation.models, generation_worker=generation_worker, projects=projects, editor=editor, renders=renders, render_worker=render_worker, analytics=analytics, analytics_worker=analytics_worker, brand_kits=brand_kits, collaboration=collaboration, approval=approval, notifications=notifications, )