Spaces:
Runtime error
Runtime error
| # FastAPI + Gradio + FastMCP MCP server main entry point | |
| import modal | |
| from contextlib import asynccontextmanager | |
| from fastapi import FastAPI | |
| from gradio.routes import mount_gradio_app | |
| import os | |
| from dotenv import load_dotenv | |
| import uvicorn | |
| from mcp.server.fastmcp import FastMCP | |
| # Import modules | |
| from .tools import mcp_tools # Import the module, not get_mcp_server function | |
| from .ui.gradio_ui import create_gradio_interface | |
| from .config.config import is_modal_mode, is_local_mode | |
| # Always import modal config since this module might be imported in modal context | |
| try: | |
| from .config.modal_config import app, image, volume, cache_dir, secrets | |
| _modal_available = True | |
| except ImportError: | |
| _modal_available = False | |
| # ==================== Application Creation Function ==================== | |
| def create_app(): | |
| """Create and return complete Gradio + MCP application""" | |
| print("π Starting Gradio + FastMCP server") | |
| # Create FastMCP server with new tools | |
| mcp = FastMCP("Podcast MCP") | |
| # Register tools using the new service architecture | |
| async def transcribe_audio_file_tool( | |
| audio_file_path: str, | |
| model_size: str = "turbo", | |
| language: str = None, | |
| output_format: str = "srt", | |
| enable_speaker_diarization: bool = False | |
| ): | |
| return await mcp_tools.transcribe_audio_file( | |
| audio_file_path, model_size, language, output_format, enable_speaker_diarization | |
| ) | |
| async def download_apple_podcast_tool(url: str): | |
| return await mcp_tools.download_apple_podcast(url) | |
| async def download_xyz_podcast_tool(url: str): | |
| return await mcp_tools.download_xyz_podcast(url) | |
| async def get_mp3_files_tool(directory: str): | |
| return await mcp_tools.get_mp3_files(directory) | |
| async def get_file_info_tool(file_path: str): | |
| return await mcp_tools.get_file_info(file_path) | |
| async def read_text_file_segments_tool( | |
| file_path: str, | |
| chunk_size: int = 65536, | |
| start_position: int = 0 | |
| ): | |
| return await mcp_tools.read_text_file_segments(file_path, chunk_size, start_position) | |
| # Create FastAPI wrapper | |
| fastapi_wrapper = FastAPI( | |
| title="Modal AudioTranscriber MCP", | |
| description="Gradio UI + FastMCP Tool + Modal Integration AudioTranscriber MCP", | |
| version="1.0.0", | |
| lifespan=lambda app: mcp.session_manager.run() | |
| ) | |
| # Get FastMCP's streamable HTTP app | |
| mcp_app = mcp.streamable_http_app() | |
| # Mount FastMCP application to /api path | |
| fastapi_wrapper.mount("/api", mcp_app) | |
| # Create Gradio interface | |
| ui_app = create_gradio_interface() | |
| # Use Gradio's standard mounting approach | |
| final_app = mount_gradio_app( | |
| app=fastapi_wrapper, | |
| blocks=ui_app, | |
| path="", | |
| app_kwargs={ | |
| "docs_url": "/docs", | |
| "redoc_url": "/redoc", | |
| } | |
| ) | |
| print("β Server startup completed") | |
| print("π¨ Gradio UI: /") | |
| print("π§ MCP Streamable HTTP: /api/mcp") | |
| print(f"π Server name: {mcp.name}") | |
| return final_app | |
| # ==================== Modal Deployment Configuration ==================== | |
| # Create a separate Modal app for the Gradio interface | |
| if _modal_available: | |
| gradio_mcp_app = modal.App(name="gradio-mcp-ui") | |
| def app_entry(): | |
| """Modal deployment function - create and return complete Gradio + MCP application""" | |
| return create_app() | |
| # ==================== Main Entry Point ==================== | |
| def main(): | |
| """Main entry point for all deployment modes""" | |
| if is_modal_mode(): | |
| print("βοΈ Modal mode: Use 'modal deploy src.app::gradio_mcp_app'") | |
| return None | |
| else: | |
| print("π Starting in local mode") | |
| print("π‘ GPU functions will be routed to Modal endpoints") | |
| app = create_app() | |
| return app | |
| def run_local(): | |
| """Run local server with uvicorn (for direct execution)""" | |
| app = main() | |
| if app: | |
| # Use port 7860 for HF Spaces compatibility, 8000 for local | |
| port = int(os.environ.get("PORT", 7860)) # HF Spaces uses port 7860 | |
| uvicorn.run( | |
| app, | |
| host="0.0.0.0", | |
| port=port, | |
| reload=False | |
| ) | |
| # ==================== Hugging Face Spaces Support ==================== | |
| # For Hugging Face Spaces, directly create the app | |
| def get_app(): | |
| """Get app instance for HF Spaces""" | |
| if "DEPLOYMENT_MODE" not in os.environ: | |
| os.environ["DEPLOYMENT_MODE"] = "local" | |
| return main() | |
| # Create app for HF Spaces when imported | |
| app = get_app() # Always create app for HF Spaces | |
| if __name__ == "__main__": | |
| run_local() |