app.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. # Copyright (C) 2025 AIDC-AI
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. # http://www.apache.org/licenses/LICENSE-2.0
  7. # Unless required by applicable law or agreed to in writing, software
  8. # distributed under the License is distributed on an "AS IS" BASIS,
  9. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. # See the License for the specific language governing permissions and
  11. # limitations under the License.
  12. """
  13. Pixelle-Video FastAPI Application
  14. Main FastAPI app with all routers and middleware.
  15. Run this script to start the FastAPI server:
  16. uv run python api/app.py
  17. Or with custom settings:
  18. uv run python api/app.py --host 0.0.0.0 --port 8080 --reload
  19. """
  20. import sys
  21. from pathlib import Path
  22. # Add project root to sys.path for module imports
  23. # This ensures imports work correctly in both development and packaged environments
  24. _script_dir = Path(__file__).resolve().parent
  25. _project_root = _script_dir.parent
  26. if str(_project_root) not in sys.path:
  27. sys.path.insert(0, str(_project_root))
  28. import argparse
  29. from contextlib import asynccontextmanager
  30. from fastapi import FastAPI
  31. from fastapi.middleware.cors import CORSMiddleware
  32. from loguru import logger
  33. from api.config import api_config
  34. from api.tasks import task_manager
  35. from api.dependencies import shutdown_pixelle_video
  36. # Import routers
  37. from api.routers import (
  38. health_router,
  39. llm_router,
  40. tts_router,
  41. image_router,
  42. content_router,
  43. video_router,
  44. tasks_router,
  45. files_router,
  46. resources_router,
  47. frame_router,
  48. )
  49. @asynccontextmanager
  50. async def lifespan(app: FastAPI):
  51. """
  52. Application lifespan manager
  53. Handles startup and shutdown events.
  54. """
  55. # Startup
  56. logger.info("๐Ÿš€ Starting Pixelle-Video API...")
  57. await task_manager.start()
  58. logger.info("โœ… Pixelle-Video API started successfully\n")
  59. yield
  60. # Shutdown
  61. logger.info("๐Ÿ›‘ Shutting down Pixelle-Video API...")
  62. await task_manager.stop()
  63. await shutdown_pixelle_video()
  64. logger.info("โœ… Pixelle-Video API shutdown complete")
  65. # Create FastAPI app
  66. app = FastAPI(
  67. title="Pixelle-Video API",
  68. description="""
  69. ## Pixelle-Video - AI Video Generation Platform API
  70. ### Features
  71. - ๐Ÿค– **LLM**: Large language model integration
  72. - ๐Ÿ”Š **TTS**: Text-to-speech synthesis
  73. - ๐ŸŽจ **Image**: AI image generation
  74. - ๐Ÿ“ **Content**: Automated content generation
  75. - ๐ŸŽฌ **Video**: End-to-end video generation
  76. ### Video Generation Modes
  77. - **Sync**: `/api/video/generate/sync` - For small videos (< 30s)
  78. - **Async**: `/api/video/generate/async` - For large videos with task tracking
  79. ### Getting Started
  80. 1. Check health: `GET /health`
  81. 2. Generate narrations: `POST /api/content/narration`
  82. 3. Generate video: `POST /api/video/generate/sync` or `/async`
  83. 4. Track task progress: `GET /api/tasks/{task_id}`
  84. """,
  85. version="0.1.0",
  86. docs_url=api_config.docs_url,
  87. redoc_url=api_config.redoc_url,
  88. openapi_url=api_config.openapi_url,
  89. lifespan=lifespan,
  90. )
  91. # Add CORS middleware
  92. if api_config.cors_enabled:
  93. app.add_middleware(
  94. CORSMiddleware,
  95. allow_origins=api_config.cors_origins,
  96. allow_credentials=True,
  97. allow_methods=["*"],
  98. allow_headers=["*"],
  99. )
  100. logger.info(f"CORS enabled for origins: {api_config.cors_origins}")
  101. # Include routers
  102. # Health check (no prefix)
  103. app.include_router(health_router)
  104. # API routers (with /api prefix)
  105. app.include_router(llm_router, prefix=api_config.api_prefix)
  106. app.include_router(tts_router, prefix=api_config.api_prefix)
  107. app.include_router(image_router, prefix=api_config.api_prefix)
  108. app.include_router(content_router, prefix=api_config.api_prefix)
  109. app.include_router(video_router, prefix=api_config.api_prefix)
  110. app.include_router(tasks_router, prefix=api_config.api_prefix)
  111. app.include_router(files_router, prefix=api_config.api_prefix)
  112. app.include_router(resources_router, prefix=api_config.api_prefix)
  113. app.include_router(frame_router, prefix=api_config.api_prefix)
  114. @app.get("/")
  115. async def root():
  116. """Root endpoint with API information"""
  117. return {
  118. "service": "Pixelle-Video API",
  119. "version": "0.1.0",
  120. "docs": api_config.docs_url,
  121. "health": "/health",
  122. "api": {
  123. "llm": f"{api_config.api_prefix}/llm",
  124. "tts": f"{api_config.api_prefix}/tts",
  125. "image": f"{api_config.api_prefix}/image",
  126. "content": f"{api_config.api_prefix}/content",
  127. "video": f"{api_config.api_prefix}/video",
  128. "tasks": f"{api_config.api_prefix}/tasks",
  129. "files": f"{api_config.api_prefix}/files",
  130. "resources": f"{api_config.api_prefix}/resources",
  131. "frame": f"{api_config.api_prefix}/frame",
  132. }
  133. }
  134. if __name__ == "__main__":
  135. import uvicorn
  136. # Parse command line arguments
  137. parser = argparse.ArgumentParser(description="Start Pixelle-Video API Server")
  138. parser.add_argument("--host", default="0.0.0.0", help="Host to bind to")
  139. parser.add_argument("--port", type=int, default=8000, help="Port to bind to")
  140. parser.add_argument("--reload", action="store_true", help="Enable auto-reload")
  141. args = parser.parse_args()
  142. # Print startup banner
  143. print(f"""
  144. โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
  145. โ•‘ Pixelle-Video API Server โ•‘
  146. โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
  147. Starting server at http://{args.host}:{args.port}
  148. API Docs: http://{args.host}:{args.port}/docs
  149. ReDoc: http://{args.host}:{args.port}/redoc
  150. Press Ctrl+C to stop the server
  151. """)
  152. # Start server
  153. uvicorn.run(
  154. "api.app:app",
  155. host=args.host,
  156. port=args.port,
  157. reload=args.reload,
  158. )