Files
dylan b9e4ac31eb Add environment variable management and fix Pydantic validation error (#15)
* Use env to manage important configurations and distinguish environments

* fix Pydantic validation error caused by None value in links field of Page class

* Production environment no longer exposes API docs

* Extract TOKEN_URL to conf
2023-04-21 20:10:07 +08:00

69 lines
2.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from __future__ import annotations
import math
from typing import TypeVar, Generic, Sequence, Dict, Union
from fastapi import Query
from fastapi_pagination.bases import AbstractPage, AbstractParams, RawParams
from fastapi_pagination.links.bases import create_links
from pydantic import BaseModel
T = TypeVar("T")
"""
重写分页库fastapi-pagination
使用方法example link: https://github.com/uriyyo/fastapi-pagination/tree/main/examples
"""
class Params(BaseModel, AbstractParams):
page: int = Query(1, ge=1, description="Page number")
size: int = Query(20, gt=0, le=100, description="Page size") # 默认 20 条记录
def to_raw_params(self) -> RawParams:
return RawParams(
limit=self.size,
offset=self.size * (self.page - 1),
)
class Page(AbstractPage[T], Generic[T]):
data: Sequence[T] # 数据
total: int # 总数据数
page: int # 第n页
size: int # 每页数量
total_pages: int # 总页数
links: Dict[str, Union[str, None]] # 跳转链接
__params_type__ = Params # 使用自定义的Params
@classmethod
def create(
cls,
data: Sequence[T],
total: int,
params: Params,
) -> Page[T]:
page = params.page
size = params.size
total_pages = math.ceil(total / params.size)
links = create_links(
**{
"first": {"page": 1, "size": f"{size}"},
"last": {"page": f"{math.ceil(total / params.size)}", "size": f"{size}"} if total > 0 else None,
"next": {"page": f"{page + 1}", "size": f"{size}"} if (page + 1) <= total_pages else None,
"prev": {"page": f"{page - 1}", "size": f"{size}"} if (page - 1) >= 1 else None
}
).dict()
return cls(
data=data,
total=total,
page=params.page,
size=params.size,
total_pages=total_pages,
links=links
)