mirror of
https://github.com/fastapi-users/fastapi-users.git
synced 2025-10-26 02:16:07 +08:00
Drop Pydantic v1 support
This commit is contained in:
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@ -41,7 +41,7 @@ jobs:
|
||||
pip install hatch
|
||||
- name: Test
|
||||
run: |
|
||||
hatch run test:test-cov-xml
|
||||
hatch run test-cov-xml
|
||||
- uses: codecov/codecov-action@v5
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
@ -214,7 +214,7 @@ We use [Hatch](https://hatch.pypa.io/latest/install/) to manage the development
|
||||
You can run all the tests with:
|
||||
|
||||
```bash
|
||||
hatch run test:test
|
||||
hatch run test
|
||||
```
|
||||
|
||||
### Format the code
|
||||
|
||||
@ -8,7 +8,6 @@ from fastapi_users.authentication.transport.base import (
|
||||
TransportLogoutNotSupportedError,
|
||||
)
|
||||
from fastapi_users.openapi import OpenAPIResponseType
|
||||
from fastapi_users.schemas import model_dump
|
||||
|
||||
|
||||
class BearerResponse(BaseModel):
|
||||
@ -24,7 +23,7 @@ class BearerTransport(Transport):
|
||||
|
||||
async def get_login_response(self, token: str) -> Response:
|
||||
bearer_response = BearerResponse(access_token=token, token_type="bearer")
|
||||
return JSONResponse(model_dump(bearer_response))
|
||||
return JSONResponse(bearer_response.model_dump())
|
||||
|
||||
async def get_logout_response(self) -> Response:
|
||||
raise TransportLogoutNotSupportedError()
|
||||
|
||||
@ -265,6 +265,6 @@ def get_oauth_associate_router(
|
||||
request,
|
||||
)
|
||||
|
||||
return schemas.model_validate(user_schema, user)
|
||||
return user_schema.model_validate(user)
|
||||
|
||||
return router
|
||||
|
||||
@ -69,6 +69,6 @@ def get_register_router(
|
||||
},
|
||||
)
|
||||
|
||||
return schemas.model_validate(user_schema, created_user)
|
||||
return user_schema.model_validate(created_user)
|
||||
|
||||
return router
|
||||
|
||||
@ -46,7 +46,7 @@ def get_users_router(
|
||||
async def me(
|
||||
user: models.UP = Depends(get_current_active_user),
|
||||
):
|
||||
return schemas.model_validate(user_schema, user)
|
||||
return user_schema.model_validate(user)
|
||||
|
||||
@router.patch(
|
||||
"/me",
|
||||
@ -94,7 +94,7 @@ def get_users_router(
|
||||
user = await user_manager.update(
|
||||
user_update, user, safe=True, request=request
|
||||
)
|
||||
return schemas.model_validate(user_schema, user)
|
||||
return user_schema.model_validate(user)
|
||||
except exceptions.InvalidPasswordException as e:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
@ -127,7 +127,7 @@ def get_users_router(
|
||||
},
|
||||
)
|
||||
async def get_user(user=Depends(get_user_or_404)):
|
||||
return schemas.model_validate(user_schema, user)
|
||||
return user_schema.model_validate(user)
|
||||
|
||||
@router.patch(
|
||||
"/{id}",
|
||||
@ -181,7 +181,7 @@ def get_users_router(
|
||||
user = await user_manager.update(
|
||||
user_update, user, safe=False, request=request
|
||||
)
|
||||
return schemas.model_validate(user_schema, user)
|
||||
return user_schema.model_validate(user)
|
||||
except exceptions.InvalidPasswordException as e:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
|
||||
@ -68,7 +68,7 @@ def get_verify_router(
|
||||
):
|
||||
try:
|
||||
user = await user_manager.verify(token, request)
|
||||
return schemas.model_validate(user_schema, user)
|
||||
return user_schema.model_validate(user)
|
||||
except (exceptions.InvalidVerifyToken, exceptions.UserNotExists):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
|
||||
@ -1,35 +1,15 @@
|
||||
from typing import Any, Generic, TypeVar
|
||||
from typing import Generic, TypeVar
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, EmailStr
|
||||
from pydantic.version import VERSION as PYDANTIC_VERSION
|
||||
|
||||
from fastapi_users import models
|
||||
|
||||
PYDANTIC_V2 = PYDANTIC_VERSION.startswith("2.")
|
||||
|
||||
SCHEMA = TypeVar("SCHEMA", bound=BaseModel)
|
||||
|
||||
if PYDANTIC_V2: # pragma: no cover
|
||||
|
||||
def model_dump(model: BaseModel, *args, **kwargs) -> dict[str, Any]:
|
||||
return model.model_dump(*args, **kwargs) # type: ignore
|
||||
|
||||
def model_validate(schema: type[SCHEMA], obj: Any, *args, **kwargs) -> SCHEMA:
|
||||
return schema.model_validate(obj, *args, **kwargs) # type: ignore
|
||||
|
||||
else: # pragma: no cover # type: ignore
|
||||
|
||||
def model_dump(model: BaseModel, *args, **kwargs) -> dict[str, Any]:
|
||||
return model.dict(*args, **kwargs) # type: ignore
|
||||
|
||||
def model_validate(schema: type[SCHEMA], obj: Any, *args, **kwargs) -> SCHEMA:
|
||||
return schema.from_orm(obj) # type: ignore
|
||||
|
||||
|
||||
class CreateUpdateDictModel(BaseModel):
|
||||
def create_update_dict(self):
|
||||
return model_dump(
|
||||
self,
|
||||
return self.model_dump(
|
||||
exclude_unset=True,
|
||||
exclude={
|
||||
"id",
|
||||
@ -41,7 +21,7 @@ class CreateUpdateDictModel(BaseModel):
|
||||
)
|
||||
|
||||
def create_update_dict_superuser(self):
|
||||
return model_dump(self, exclude_unset=True, exclude={"id"})
|
||||
return self.model_dump(exclude_unset=True, exclude={"id"})
|
||||
|
||||
|
||||
class BaseUser(CreateUpdateDictModel, Generic[models.ID]):
|
||||
@ -53,12 +33,7 @@ class BaseUser(CreateUpdateDictModel, Generic[models.ID]):
|
||||
is_superuser: bool = False
|
||||
is_verified: bool = False
|
||||
|
||||
if PYDANTIC_V2: # pragma: no cover
|
||||
model_config = ConfigDict(from_attributes=True) # type: ignore
|
||||
else: # pragma: no cover
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class BaseUserCreate(CreateUpdateDictModel):
|
||||
@ -93,12 +68,7 @@ class BaseOAuthAccount(BaseModel, Generic[models.ID]):
|
||||
account_id: str
|
||||
account_email: str
|
||||
|
||||
if PYDANTIC_V2: # pragma: no cover
|
||||
model_config = ConfigDict(from_attributes=True) # type: ignore
|
||||
else: # pragma: no cover
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class BaseOAuthAccountMixin(BaseModel):
|
||||
|
||||
@ -96,22 +96,9 @@ lint-check = [
|
||||
"mypy fastapi_users/",
|
||||
]
|
||||
docs = "mkdocs serve"
|
||||
|
||||
[tool.hatch.envs.test]
|
||||
|
||||
[tool.hatch.envs.test.scripts]
|
||||
test = "pytest --cov=fastapi_users/ --cov-report=term-missing --cov-fail-under=100"
|
||||
test-cov-xml = "pytest --cov=fastapi_users/ --cov-report=xml --cov-fail-under=100"
|
||||
|
||||
[[tool.hatch.envs.test.matrix]]
|
||||
pydantic = ["v1", "v2"]
|
||||
|
||||
[tool.hatch.envs.test.overrides]
|
||||
matrix.pydantic.extra-dependencies = [
|
||||
{value = "pydantic<2.0", if = ["v1"]},
|
||||
{value = "pydantic>=2.0", if = ["v2"]},
|
||||
]
|
||||
|
||||
[tool.hatch.build.targets.sdist]
|
||||
support-legacy = true # Create setup.py
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ import pytest
|
||||
import pytest_asyncio
|
||||
from fastapi import Depends, FastAPI, status
|
||||
|
||||
from fastapi_users import FastAPIUsers, schemas
|
||||
from fastapi_users import FastAPIUsers
|
||||
from tests.conftest import IDType, User, UserCreate, UserModel, UserUpdate
|
||||
|
||||
|
||||
@ -77,7 +77,7 @@ async def test_app_client(
|
||||
def optional_current_user(
|
||||
user: UserModel | None = Depends(fastapi_users.current_user(optional=True)),
|
||||
):
|
||||
return schemas.model_validate(User, user) if user else None
|
||||
return User.model_validate(user) if user else None
|
||||
|
||||
@app.get("/optional-current-active-user")
|
||||
def optional_current_active_user(
|
||||
@ -85,7 +85,7 @@ async def test_app_client(
|
||||
fastapi_users.current_user(optional=True, active=True)
|
||||
),
|
||||
):
|
||||
return schemas.model_validate(User, user) if user else None
|
||||
return User.model_validate(user) if user else None
|
||||
|
||||
@app.get("/optional-current-verified-user")
|
||||
def optional_current_verified_user(
|
||||
@ -93,7 +93,7 @@ async def test_app_client(
|
||||
fastapi_users.current_user(optional=True, verified=True)
|
||||
),
|
||||
):
|
||||
return schemas.model_validate(User, user) if user else None
|
||||
return User.model_validate(user) if user else None
|
||||
|
||||
@app.get("/optional-current-superuser")
|
||||
def optional_current_superuser(
|
||||
@ -101,7 +101,7 @@ async def test_app_client(
|
||||
fastapi_users.current_user(optional=True, active=True, superuser=True)
|
||||
),
|
||||
):
|
||||
return schemas.model_validate(User, user) if user else None
|
||||
return User.model_validate(user) if user else None
|
||||
|
||||
@app.get("/optional-current-verified-superuser")
|
||||
def optional_current_verified_superuser(
|
||||
@ -111,7 +111,7 @@ async def test_app_client(
|
||||
)
|
||||
),
|
||||
):
|
||||
return schemas.model_validate(User, user) if user else None
|
||||
return User.model_validate(user) if user else None
|
||||
|
||||
async for client in get_test_client(app):
|
||||
yield client
|
||||
|
||||
Reference in New Issue
Block a user