mirror of
https://github.com/meta-llama/llama-stack.git
synced 2025-12-21 23:02:25 +00:00
feat: migrate Inspect API to FastAPI router (#4403)
# What does this PR do? Migrate the Inspect API to the FastAPI router pattern. Changes: - Add inspect API to FastAPI router registry - Add PUBLIC_ROUTE_KEY support for routes that don't require auth - Update WebMethod creation to respect route's openapi_extra for authentication requirements Fixes: https://github.com/llamastack/llama-stack/issues/4346 <!-- Provide a short summary of what this PR does and why. Link to relevant issues if applicable. --> <!-- If resolving an issue, uncomment and update the line below --> <!-- Closes #[issue-number] --> ## Test Plan CI and various curls on /v1/inspect/routes, /v1/health, /v1/version Signed-off-by: Sébastien Han <seb@redhat.com>
This commit is contained in:
parent
cd5095a247
commit
a7d509aaf9
14 changed files with 281 additions and 182 deletions
|
|
@ -1,103 +0,0 @@
|
|||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under the terms described in the LICENSE file in
|
||||
# the root directory of this source tree.
|
||||
|
||||
from typing import Literal, Protocol, runtime_checkable
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from llama_stack_api.datatypes import HealthStatus
|
||||
from llama_stack_api.schema_utils import json_schema_type, webmethod
|
||||
from llama_stack_api.version import (
|
||||
LLAMA_STACK_API_V1,
|
||||
)
|
||||
|
||||
# Valid values for the route filter parameter.
|
||||
# Actual API levels: v1, v1alpha, v1beta (filters by level, excludes deprecated)
|
||||
# Special filter value: "deprecated" (shows deprecated routes regardless of level)
|
||||
ApiFilter = Literal["v1", "v1alpha", "v1beta", "deprecated"]
|
||||
|
||||
|
||||
@json_schema_type
|
||||
class RouteInfo(BaseModel):
|
||||
"""Information about an API route including its path, method, and implementing providers.
|
||||
|
||||
:param route: The API endpoint path
|
||||
:param method: HTTP method for the route
|
||||
:param provider_types: List of provider types that implement this route
|
||||
"""
|
||||
|
||||
route: str
|
||||
method: str
|
||||
provider_types: list[str]
|
||||
|
||||
|
||||
@json_schema_type
|
||||
class HealthInfo(BaseModel):
|
||||
"""Health status information for the service.
|
||||
|
||||
:param status: Current health status of the service
|
||||
"""
|
||||
|
||||
status: HealthStatus
|
||||
|
||||
|
||||
@json_schema_type
|
||||
class VersionInfo(BaseModel):
|
||||
"""Version information for the service.
|
||||
|
||||
:param version: Version number of the service
|
||||
"""
|
||||
|
||||
version: str
|
||||
|
||||
|
||||
@json_schema_type
|
||||
class ListRoutesResponse(BaseModel):
|
||||
"""Response containing a list of all available API routes.
|
||||
|
||||
:param data: List of available route information objects
|
||||
"""
|
||||
|
||||
data: list[RouteInfo]
|
||||
|
||||
|
||||
@runtime_checkable
|
||||
class Inspect(Protocol):
|
||||
"""Inspect
|
||||
|
||||
APIs for inspecting the Llama Stack service, including health status, available API routes with methods and implementing providers.
|
||||
"""
|
||||
|
||||
@webmethod(route="/inspect/routes", method="GET", level=LLAMA_STACK_API_V1)
|
||||
async def list_routes(self, api_filter: ApiFilter | None = None) -> ListRoutesResponse:
|
||||
"""List routes.
|
||||
|
||||
List all available API routes with their methods and implementing providers.
|
||||
|
||||
:param api_filter: Optional filter to control which routes are returned. Can be an API level ('v1', 'v1alpha', 'v1beta') to show non-deprecated routes at that level, or 'deprecated' to show deprecated routes across all levels. If not specified, returns all non-deprecated routes.
|
||||
:returns: Response containing information about all available routes.
|
||||
"""
|
||||
...
|
||||
|
||||
@webmethod(route="/health", method="GET", level=LLAMA_STACK_API_V1, require_authentication=False)
|
||||
async def health(self) -> HealthInfo:
|
||||
"""Get health status.
|
||||
|
||||
Get the current health status of the service.
|
||||
|
||||
:returns: Health information indicating if the service is operational.
|
||||
"""
|
||||
...
|
||||
|
||||
@webmethod(route="/version", method="GET", level=LLAMA_STACK_API_V1, require_authentication=False)
|
||||
async def version(self) -> VersionInfo:
|
||||
"""Get version.
|
||||
|
||||
Get the version of the service.
|
||||
|
||||
:returns: Version information containing the service version number.
|
||||
"""
|
||||
...
|
||||
37
src/llama_stack_api/inspect_api/__init__.py
Normal file
37
src/llama_stack_api/inspect_api/__init__.py
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under the terms described in the LICENSE file in
|
||||
# the root directory of this source tree.
|
||||
|
||||
"""Inspect API protocol and models.
|
||||
|
||||
This module contains the Inspect protocol definition.
|
||||
Pydantic models are defined in llama_stack_api.inspect.models.
|
||||
The FastAPI router is defined in llama_stack_api.inspect.fastapi_routes.
|
||||
"""
|
||||
|
||||
# Import fastapi_routes for router factory access
|
||||
from . import fastapi_routes
|
||||
|
||||
# Import protocol for re-export
|
||||
from .api import Inspect
|
||||
|
||||
# Import models for re-export
|
||||
from .models import (
|
||||
ApiFilter,
|
||||
HealthInfo,
|
||||
ListRoutesResponse,
|
||||
RouteInfo,
|
||||
VersionInfo,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"Inspect",
|
||||
"ApiFilter",
|
||||
"HealthInfo",
|
||||
"ListRoutesResponse",
|
||||
"RouteInfo",
|
||||
"VersionInfo",
|
||||
"fastapi_routes",
|
||||
]
|
||||
25
src/llama_stack_api/inspect_api/api.py
Normal file
25
src/llama_stack_api/inspect_api/api.py
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under the terms described in the LICENSE file in
|
||||
# the root directory of this source tree.
|
||||
|
||||
from typing import Protocol, runtime_checkable
|
||||
|
||||
from .models import (
|
||||
ApiFilter,
|
||||
HealthInfo,
|
||||
ListRoutesResponse,
|
||||
VersionInfo,
|
||||
)
|
||||
|
||||
|
||||
@runtime_checkable
|
||||
class Inspect(Protocol):
|
||||
"""APIs for inspecting the Llama Stack service, including health status, available API routes with methods and implementing providers."""
|
||||
|
||||
async def list_routes(self, api_filter: ApiFilter | None = None) -> ListRoutesResponse: ...
|
||||
|
||||
async def health(self) -> HealthInfo: ...
|
||||
|
||||
async def version(self) -> VersionInfo: ...
|
||||
76
src/llama_stack_api/inspect_api/fastapi_routes.py
Normal file
76
src/llama_stack_api/inspect_api/fastapi_routes.py
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under the terms described in the LICENSE file in
|
||||
# the root directory of this source tree.
|
||||
|
||||
"""FastAPI router for the Inspect API.
|
||||
|
||||
This module defines the FastAPI router for the Inspect API using standard
|
||||
FastAPI route decorators.
|
||||
"""
|
||||
|
||||
from typing import Annotated
|
||||
|
||||
from fastapi import APIRouter, Query
|
||||
|
||||
from llama_stack_api.router_utils import PUBLIC_ROUTE_KEY, standard_responses
|
||||
from llama_stack_api.version import LLAMA_STACK_API_V1
|
||||
|
||||
from .api import Inspect
|
||||
from .models import (
|
||||
ApiFilter,
|
||||
HealthInfo,
|
||||
ListRoutesResponse,
|
||||
VersionInfo,
|
||||
)
|
||||
|
||||
|
||||
def create_router(impl: Inspect) -> APIRouter:
|
||||
"""Create a FastAPI router for the Inspect API."""
|
||||
router = APIRouter(
|
||||
prefix=f"/{LLAMA_STACK_API_V1}",
|
||||
tags=["Inspect"],
|
||||
responses=standard_responses,
|
||||
)
|
||||
|
||||
@router.get(
|
||||
"/inspect/routes",
|
||||
response_model=ListRoutesResponse,
|
||||
summary="List routes.",
|
||||
description="List all available API routes with their methods and implementing providers.",
|
||||
responses={200: {"description": "Response containing information about all available routes."}},
|
||||
)
|
||||
async def list_routes(
|
||||
api_filter: Annotated[
|
||||
ApiFilter | None,
|
||||
Query(
|
||||
description="Optional filter to control which routes are returned. Can be an API level ('v1', 'v1alpha', 'v1beta') to show non-deprecated routes at that level, or 'deprecated' to show deprecated routes across all levels. If not specified, returns all non-deprecated routes."
|
||||
),
|
||||
] = None,
|
||||
) -> ListRoutesResponse:
|
||||
return await impl.list_routes(api_filter)
|
||||
|
||||
@router.get(
|
||||
"/health",
|
||||
response_model=HealthInfo,
|
||||
summary="Get health status.",
|
||||
description="Get the current health status of the service.",
|
||||
responses={200: {"description": "Health information indicating if the service is operational."}},
|
||||
openapi_extra={PUBLIC_ROUTE_KEY: True},
|
||||
)
|
||||
async def health() -> HealthInfo:
|
||||
return await impl.health()
|
||||
|
||||
@router.get(
|
||||
"/version",
|
||||
response_model=VersionInfo,
|
||||
summary="Get version.",
|
||||
description="Get the version of the service.",
|
||||
responses={200: {"description": "Version information containing the service version number."}},
|
||||
openapi_extra={PUBLIC_ROUTE_KEY: True},
|
||||
)
|
||||
async def version() -> VersionInfo:
|
||||
return await impl.version()
|
||||
|
||||
return router
|
||||
53
src/llama_stack_api/inspect_api/models.py
Normal file
53
src/llama_stack_api/inspect_api/models.py
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under the terms described in the LICENSE file in
|
||||
# the root directory of this source tree.
|
||||
|
||||
"""Pydantic models for Inspect API requests and responses.
|
||||
|
||||
This module defines the request and response models for the Inspect API
|
||||
using Pydantic with Field descriptions for OpenAPI schema generation.
|
||||
"""
|
||||
|
||||
from typing import Literal
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from llama_stack_api.datatypes import HealthStatus
|
||||
from llama_stack_api.schema_utils import json_schema_type
|
||||
|
||||
# Valid values for the route filter parameter.
|
||||
# Actual API levels: v1, v1alpha, v1beta (filters by level, excludes deprecated)
|
||||
# Special filter value: "deprecated" (shows deprecated routes regardless of level)
|
||||
ApiFilter = Literal["v1", "v1alpha", "v1beta", "deprecated"]
|
||||
|
||||
|
||||
@json_schema_type
|
||||
class RouteInfo(BaseModel):
|
||||
"""Information about an API route including its path, method, and implementing providers."""
|
||||
|
||||
route: str = Field(description="The API route path")
|
||||
method: str = Field(description="The HTTP method for the route")
|
||||
provider_types: list[str] = Field(description="List of provider types implementing this route")
|
||||
|
||||
|
||||
@json_schema_type
|
||||
class HealthInfo(BaseModel):
|
||||
"""Health status information for the service."""
|
||||
|
||||
status: HealthStatus = Field(description="The health status of the service")
|
||||
|
||||
|
||||
@json_schema_type
|
||||
class VersionInfo(BaseModel):
|
||||
"""Version information for the service."""
|
||||
|
||||
version: str = Field(description="The version string of the service")
|
||||
|
||||
|
||||
@json_schema_type
|
||||
class ListRoutesResponse(BaseModel):
|
||||
"""Response containing a list of all available API routes."""
|
||||
|
||||
data: list[RouteInfo] = Field(description="List of available API routes")
|
||||
|
|
@ -18,6 +18,11 @@ from typing import Annotated, Any, TypeVar
|
|||
from fastapi import Path, Query
|
||||
from pydantic import BaseModel
|
||||
|
||||
# OpenAPI extension key to mark routes that don't require authentication.
|
||||
# Use this in FastAPI route decorators: @router.get("/health", openapi_extra={PUBLIC_ROUTE_KEY: True})
|
||||
PUBLIC_ROUTE_KEY = "x-public"
|
||||
|
||||
|
||||
standard_responses: dict[int | str, dict[str, Any]] = {
|
||||
400: {"$ref": "#/components/responses/BadRequest400"},
|
||||
429: {"$ref": "#/components/responses/TooManyRequests429"},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue