diff --git a/.github/workflows/test_full.yml b/.github/workflows/test_full.yml index 48df86583..45ce929f7 100644 --- a/.github/workflows/test_full.yml +++ b/.github/workflows/test_full.yml @@ -34,7 +34,7 @@ jobs: with: python-version: ${{ matrix.python-version }} - name: Install core - run: pip install "Django${{ matrix.django-version }}" + run: pip install "Django${{ matrix.django-version }}" "pydantic-settings>=2.0.0" - name: Install tests run: pip install pytest pytest-asyncio pytest-django django-ninja-extra 'python-jose==3.3.0' 'pyjwt[crypto]' freezegun - name: Test diff --git a/ninja_jwt/schema.py b/ninja_jwt/schema.py index 97ad251ef..57323613d 100644 --- a/ninja_jwt/schema.py +++ b/ninja_jwt/schema.py @@ -141,9 +141,7 @@ def validate_inputs(cls, values: SCHEMA_INPUT) -> dict: return values @model_validator(mode="after") - def post_validate( - self, info: ValidationInfo - ) -> BaseModel: + def post_validate(self, info: ValidationInfo) -> BaseModel: schema_input = SchemaInputService( self.model_dump(), self.__class__.model_config, info.context.get("request") ) diff --git a/ninja_jwt/settings.py b/ninja_jwt/settings.py index 1f73483b5..a77912a30 100644 --- a/ninja_jwt/settings.py +++ b/ninja_jwt/settings.py @@ -4,7 +4,8 @@ from django.conf import settings from django.test.signals import setting_changed from ninja_extra.lazy import LazyStrImport -from pydantic.v1 import AnyUrl, BaseModel, Field, root_validator +from pydantic import AnyUrl, Field +from pydantic_settings import BaseSettings, SettingsConfigDict class NinjaJWTUserDefinedSettingsMapper: @@ -27,10 +28,11 @@ def __init__(self, data: dict) -> None: ) -class NinjaJWTSettings(BaseModel): - class Config: - orm_mode = True - validate_assignment = True +class NinjaJWTSettings(BaseSettings): + model_config = SettingsConfigDict( + validate_assignment=True, + extra="ignore", + ) ACCESS_TOKEN_LIFETIME: timedelta = Field(timedelta(minutes=5)) REFRESH_TOKEN_LIFETIME: timedelta = Field(timedelta(days=1)) @@ -82,20 +84,21 @@ class Config: ) TOKEN_VERIFY_INPUT_SCHEMA: Any = Field("ninja_jwt.schema.TokenVerifyInputSchema") - @root_validator - def validate_ninja_jwt_settings(cls, values): - for item in NinjaJWT_SETTINGS_DEFAULTS.keys(): - if isinstance(values[item], (tuple, list)) and isinstance( - values[item][0], str - ): - values[item] = [LazyStrImport(str(klass)) for klass in values[item]] - if isinstance(values[item], str): - values[item] = LazyStrImport(values[item]) - return values + def __getattribute__(self, item): + # Get the actual value using object.__getattribute__ to avoid recursion + value = object.__getattribute__(self, item) + + if item in NinjaJWT_SETTINGS_DEFAULTS: + if isinstance(value, (list, tuple)) and value and isinstance(value[0], str): + return [LazyStrImport(str(klass)) for klass in value] + elif isinstance(value, str): + return LazyStrImport(value) + + return value # convert to lazy object -api_settings = NinjaJWTSettings.from_orm(USER_SETTINGS) +api_settings = NinjaJWTSettings.model_validate(USER_SETTINGS.__dict__) def reload_api_settings(*args: Any, **kwargs: Any) -> None: @@ -104,9 +107,7 @@ def reload_api_settings(*args: Any, **kwargs: Any) -> None: setting, value = kwargs["setting"], kwargs["value"] if setting in ["SIMPLE_JWT", "NINJA_JWT"]: - api_settings = NinjaJWTSettings.from_orm( - NinjaJWTUserDefinedSettingsMapper(value) - ) + api_settings = NinjaJWTSettings.model_validate(value) setting_changed.connect(reload_api_settings) diff --git a/pyproject.toml b/pyproject.toml index 4d7ad2187..c7cc1c05f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,6 +51,7 @@ dependencies = [ "pyjwt>=1.7.1,<3", "pyjwt[crypto]", "django-ninja-extra >= 0.22.9", + "pydantic-settings>=2.0.0", ]