From d8c5306bf4093274fab5dabca810ac2a4f37ccdd Mon Sep 17 00:00:00 2001 From: Denys Fedoryshchenko Date: Tue, 2 Sep 2025 09:28:09 +0300 Subject: [PATCH] Fix: FastAPI /docs OpenAPI schema generation for PydanticObjectId Trying to fix by monkey-patching the PydanticObjectId class to provide a proper JSON schema Signed-off-by: Denys Fedoryshchenko --- api/main.py | 12 +++++++++--- api/models.py | 5 ++--- api/user_manager.py | 4 ++-- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/api/main.py b/api/main.py index 3a415ee4..4869bf38 100644 --- a/api/main.py +++ b/api/main.py @@ -39,8 +39,9 @@ from fastapi_versioning import VersionedFastAPI from bson import ObjectId, errors from fastapi_users import FastAPIUsers -from beanie import PydanticObjectId from pydantic import BaseModel +from typing import Any +from kernelci.api.models_base import PyObjectId from kernelci.api.models import ( Node, Hierarchy, @@ -73,6 +74,8 @@ SUBSCRIPTION_CLEANUP_RETRY_MINUTES = 1 # Retry interval if cleanup fails + + @asynccontextmanager async def lifespan(app: FastAPI): # pylint: disable=redefined-outer-name """Lifespan functions for startup and shutdown events""" @@ -87,13 +90,16 @@ async def lifespan(app: FastAPI): # pylint: disable=redefined-outer-name API_VERSIONS = ['v0'] metrics = Metrics() -app = FastAPI(lifespan=lifespan, debug=True, docs_url=None, redoc_url=None) +app = FastAPI( + lifespan=lifespan, + debug=True +) db = Database(service=(os.getenv('MONGO_SERVICE') or 'mongodb://db:27017')) auth = Authentication(token_url="user/login") pubsub = None # pylint: disable=invalid-name auth_backend = auth.get_user_authentication_backend() -fastapi_users_instance = FastAPIUsers[User, PydanticObjectId]( +fastapi_users_instance = FastAPIUsers[User, PyObjectId]( get_user_manager, [auth_backend], ) diff --git a/api/models.py b/api/models.py index 9f5b063d..ee50d52f 100644 --- a/api/models.py +++ b/api/models.py @@ -26,9 +26,8 @@ from beanie import ( Indexed, Document, - PydanticObjectId, ) -from kernelci.api.models_base import DatabaseModel, ModelId +from kernelci.api.models_base import DatabaseModel, ModelId, PyObjectId # PubSub model definitions @@ -107,7 +106,7 @@ def get_indexes(cls): ] -class UserRead(schemas.BaseUser[PydanticObjectId], ModelId): +class UserRead(schemas.BaseUser[PyObjectId], ModelId): """Schema for reading a user""" username: Annotated[str, Indexed(unique=True)] groups: List[UserGroup] = Field(default=[]) diff --git a/api/user_manager.py b/api/user_manager.py index 946f1ca8..93680de0 100644 --- a/api/user_manager.py +++ b/api/user_manager.py @@ -13,14 +13,14 @@ BeanieUserDatabase, ObjectIDIDMixin, ) -from beanie import PydanticObjectId import jinja2 from .models import User +from kernelci.api.models_base import PyObjectId from .config import AuthSettings from .email_sender import EmailSender -class UserManager(ObjectIDIDMixin, BaseUserManager[User, PydanticObjectId]): +class UserManager(ObjectIDIDMixin, BaseUserManager[User, PyObjectId]): """User management logic""" settings = AuthSettings() reset_password_token_secret = settings.secret_key