mirror of
https://github.com/OpenHands/OpenHands.git
synced 2025-12-26 05:48:36 +08:00
Co-authored-by: openhands <openhands@all-hands.dev> Co-authored-by: Rohit Malhotra <rohitvinodmalhotra@gmail.com>
97 lines
3.2 KiB
Python
97 lines
3.2 KiB
Python
import contextlib
|
|
import warnings
|
|
from contextlib import asynccontextmanager
|
|
from typing import AsyncIterator
|
|
|
|
from fastapi.routing import Mount
|
|
|
|
with warnings.catch_warnings():
|
|
warnings.simplefilter('ignore')
|
|
|
|
from fastapi import (
|
|
FastAPI,
|
|
Request,
|
|
)
|
|
from fastapi.responses import JSONResponse
|
|
|
|
import openhands.agenthub # noqa F401 (we import this to get the agents registered)
|
|
from openhands.app_server import v1_router
|
|
from openhands.app_server.config import get_app_lifespan_service
|
|
from openhands.integrations.service_types import AuthenticationError
|
|
from openhands.server.routes.conversation import app as conversation_api_router
|
|
from openhands.server.routes.feedback import app as feedback_api_router
|
|
from openhands.server.routes.files import app as files_api_router
|
|
from openhands.server.routes.git import app as git_api_router
|
|
from openhands.server.routes.health import add_health_endpoints
|
|
from openhands.server.routes.manage_conversations import (
|
|
app as manage_conversation_api_router,
|
|
)
|
|
from openhands.server.routes.mcp import mcp_server
|
|
from openhands.server.routes.public import app as public_api_router
|
|
from openhands.server.routes.secrets import app as secrets_router
|
|
from openhands.server.routes.security import app as security_api_router
|
|
from openhands.server.routes.settings import app as settings_router
|
|
from openhands.server.routes.trajectory import app as trajectory_router
|
|
from openhands.server.shared import conversation_manager, server_config
|
|
from openhands.server.types import AppMode
|
|
from openhands.version import get_version
|
|
|
|
mcp_app = mcp_server.http_app(path='/mcp', stateless_http=True)
|
|
|
|
|
|
def combine_lifespans(*lifespans):
|
|
# Create a combined lifespan to manage multiple session managers
|
|
@contextlib.asynccontextmanager
|
|
async def combined_lifespan(app):
|
|
async with contextlib.AsyncExitStack() as stack:
|
|
for lifespan in lifespans:
|
|
await stack.enter_async_context(lifespan(app))
|
|
yield
|
|
|
|
return combined_lifespan
|
|
|
|
|
|
@asynccontextmanager
|
|
async def _lifespan(app: FastAPI) -> AsyncIterator[None]:
|
|
async with conversation_manager:
|
|
yield
|
|
|
|
|
|
lifespans = [_lifespan, mcp_app.lifespan]
|
|
app_lifespan_ = get_app_lifespan_service()
|
|
if app_lifespan_:
|
|
lifespans.append(app_lifespan_.lifespan)
|
|
|
|
|
|
app = FastAPI(
|
|
title='OpenHands',
|
|
description='OpenHands: Code Less, Make More',
|
|
version=get_version(),
|
|
lifespan=combine_lifespans(*lifespans),
|
|
routes=[Mount(path='/mcp', app=mcp_app)],
|
|
)
|
|
|
|
|
|
@app.exception_handler(AuthenticationError)
|
|
async def authentication_error_handler(request: Request, exc: AuthenticationError):
|
|
return JSONResponse(
|
|
status_code=401,
|
|
content=str(exc),
|
|
)
|
|
|
|
|
|
app.include_router(public_api_router)
|
|
app.include_router(files_api_router)
|
|
app.include_router(security_api_router)
|
|
app.include_router(feedback_api_router)
|
|
app.include_router(conversation_api_router)
|
|
app.include_router(manage_conversation_api_router)
|
|
app.include_router(settings_router)
|
|
app.include_router(secrets_router)
|
|
if server_config.app_mode == AppMode.OSS:
|
|
app.include_router(git_api_router)
|
|
if server_config.enable_v1:
|
|
app.include_router(v1_router.router)
|
|
app.include_router(trajectory_router)
|
|
add_health_endpoints(app)
|