From cffb4988860ba0ce4ef3b0c9d5dbfe1d50ccdf4e Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Sat, 6 Dec 2025 10:38:21 +0100 Subject: [PATCH] Implement models listing domain MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add OpenAI-compatible models listing endpoint. Currently returns mock model (mistral-nemo:latest). Models Router (src/models/router.py): - GET /v1/models endpoint - OpenAI-compatible response format - Lists available models Models Schemas (src/models/schemas.py): - Model object with id, created, owned_by - ModelsListResponse with data array - Full OpenAI API compatibility Models Service (src/models/service.py): - list_models() function - Mock model listing (ready for Ollama integration) - Returns mistral-nemo:latest as default Following Best Practices: - Business logic in service layer - Router only handles HTTP concerns - Type hints throughout - Async/await pattern Model: mistral-nemo:latest Status: Mock implementation (ready for Ollama integration) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/models/__init__.py | 0 src/models/router.py | 28 ++++++++++++++++++++++++++++ src/models/schemas.py | 18 ++++++++++++++++++ src/models/service.py | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+) create mode 100644 src/models/__init__.py create mode 100644 src/models/router.py create mode 100644 src/models/schemas.py create mode 100644 src/models/service.py diff --git a/src/models/__init__.py b/src/models/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/models/router.py b/src/models/router.py new file mode 100644 index 0000000..8ddb374 --- /dev/null +++ b/src/models/router.py @@ -0,0 +1,28 @@ +""" +Models router. +OpenAI-compatible /v1/models endpoint. +""" +import logging + +from fastapi import APIRouter + +from src.models import service +from src.models.schemas import ModelsResponse + +logger = logging.getLogger(__name__) + +router = APIRouter(prefix="/models", tags=["models"]) + + +@router.get("", response_model=ModelsResponse) +async def list_models() -> ModelsResponse: + """ + List available models (OpenAI-compatible). + + Currently returns mock model list. + + Returns: + List of available models + """ + logger.info("Listing available models") + return await service.list_models() diff --git a/src/models/schemas.py b/src/models/schemas.py new file mode 100644 index 0000000..bb450f8 --- /dev/null +++ b/src/models/schemas.py @@ -0,0 +1,18 @@ +""" +OpenAI-compatible models schemas. +""" +from src.core.models import CustomBaseModel + + +class Model(CustomBaseModel): + """OpenAI-compatible model object.""" + id: str + object: str = "model" + created: int + owned_by: str = "system" + + +class ModelsResponse(CustomBaseModel): + """OpenAI-compatible models list response.""" + object: str = "list" + data: list[Model] diff --git a/src/models/service.py b/src/models/service.py new file mode 100644 index 0000000..b362d68 --- /dev/null +++ b/src/models/service.py @@ -0,0 +1,34 @@ +""" +Models service. +Currently returns mock model list. +TODO: Fetch from Ollama in future. +""" +import time + +from src.models.schemas import Model, ModelsResponse + + +# Mock models (will be replaced with Ollama models later) +MOCK_MODELS = [ + {"id": "mistral-nemo:latest", "created": int(time.time())}, +] + + +async def list_models() -> ModelsResponse: + """ + List available models (mock implementation). + + Returns: + Mock list of models + """ + models = [ + Model( + id=model["id"], + object="model", + created=model["created"], + owned_by="system", + ) + for model in MOCK_MODELS + ] + + return ModelsResponse(object="list", data=models)