fastapi-rest-toolkit 0.0.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,135 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ pip-wheel-metadata/
24
+ share/python-wheels/
25
+ *.egg-info/
26
+ .installed.cfg
27
+ *.egg
28
+ MANIFEST
29
+
30
+ # PyInstaller
31
+ *.manifest
32
+ *.spec
33
+
34
+ # Installer logs
35
+ pip-log.txt
36
+ pip-delete-this-directory.txt
37
+
38
+ # Unit test / coverage reports
39
+ htmlcov/
40
+ .tox/
41
+ .nox/
42
+ .coverage
43
+ .coverage.*
44
+ .cache
45
+ nosetests.xml
46
+ coverage.xml
47
+ *.cover
48
+ *.py,cover
49
+ .hypothesis/
50
+ .pytest_cache/
51
+
52
+ # Translations
53
+ *.mo
54
+ *.pot
55
+
56
+ # Django stuff:
57
+ *.log
58
+ local_settings.py
59
+ db.sqlite3
60
+ db.sqlite3-journal
61
+
62
+ # Flask stuff:
63
+ instance/
64
+ .webassets-cache
65
+
66
+ # Scrapy stuff:
67
+ .scrapy
68
+
69
+ # Sphinx documentation
70
+ docs/_build/
71
+
72
+ # PyBuilder
73
+ target/
74
+
75
+ # Jupyter Notebook
76
+ .ipynb_checkpoints
77
+
78
+ # IPython
79
+ profile_default/
80
+ ipython_config.py
81
+
82
+ # pyenv
83
+ .python-version
84
+
85
+ # Pipenv
86
+ Pipfile.lock
87
+
88
+ # PEP 582
89
+ __pypackages__/
90
+
91
+ # Celery stuff
92
+ celerybeat-schedule
93
+ celerybeat.pid
94
+
95
+ # SageMath parsed files
96
+ *.sage.py
97
+
98
+ # Environments
99
+ .env
100
+ .venv
101
+ env/
102
+ venv/
103
+ ENV/
104
+ env.bak/
105
+ venv.bak/
106
+
107
+ # Spyder project settings
108
+ .spyderproject
109
+ .spyproject
110
+
111
+ # Rope project settings
112
+ .ropeproject
113
+
114
+ # mkdocs documentation
115
+ /site
116
+
117
+ # mypy
118
+ .mypy_cache/
119
+ .dmypy.json
120
+ dmypy.json
121
+
122
+ # Pyre type checker
123
+ .pyre/
124
+
125
+ # IDE
126
+ .vscode/
127
+ .idea/
128
+ *.swp
129
+ *.swo
130
+ *~
131
+ .DS_Store
132
+ .cursor/
133
+
134
+
135
+ # demo
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,277 @@
1
+ Metadata-Version: 2.4
2
+ Name: fastapi-rest-toolkit
3
+ Version: 0.0.3
4
+ Summary: 类DRF风格的FastAPI工具包
5
+ Project-URL: Homepage, https://github.com/pppigrui/fastapi-rest-toolkit
6
+ Project-URL: Documentation, https://github.com/pppigrui/fastapi-rest-toolkit#readme
7
+ Project-URL: Repository, https://github.com/pppigrui/fastapi-rest-toolkit
8
+ Project-URL: Bug Tracker, https://github.com/pppigrui/fastapi-rest-toolkit/issues
9
+ Author-email: xiaorui <pppigrui@gmail.com>
10
+ License: MIT
11
+ License-File: LICENSE
12
+ Keywords: api,drf,fastapi,rest,toolkit
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Framework :: FastAPI
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
+ Requires-Python: >=3.12
21
+ Requires-Dist: fastapi>=0.128.0
22
+ Requires-Dist: pydantic>=2.12.0
23
+ Requires-Dist: redis>=7.1.0
24
+ Requires-Dist: sqlalchemy-crud-plus>=1.13.0
25
+ Requires-Dist: sqlalchemy>=2.0.46
26
+ Provides-Extra: all
27
+ Requires-Dist: redis>=5.0.0; extra == 'all'
28
+ Provides-Extra: redis
29
+ Requires-Dist: redis>=5.0.0; extra == 'redis'
30
+ Description-Content-Type: text/markdown
31
+
32
+ # FastAPI REST Toolkit
33
+
34
+ 类 Django REST Framework 风格的 FastAPI 工具包,提供简洁优雅的方式来构建 RESTful API。
35
+
36
+ ## 特性
37
+
38
+ - **ViewSet**: 类似 DRF 的 ViewSet,支持 CRUD 操作
39
+ - **Router**: 自动路由注册,简化路由配置
40
+ - **权限系统**: 灵活的权限控制(AllowAny、IsAuthenticated、IsAdmin)
41
+ - **过滤器**: 支持搜索、排序、CRUD Plus 过滤
42
+ - **节流**: 内置限流机制,支持 Redis 存储
43
+ - **Schema 工具**: 从 SQLAlchemy 模型自动生成 Pydantic Schema
44
+
45
+ ## 安装
46
+
47
+ ```bash
48
+ pip install fastapi-rest-toolkit
49
+ ```
50
+
51
+ ## 快速开始
52
+
53
+ ### 完整示例
54
+
55
+ ```python
56
+ from fastapi import FastAPI
57
+ from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine, async_sessionmaker
58
+ from sqlalchemy.orm import Mapped, mapped_column
59
+ from sqlalchemy import String, DateTime, func
60
+
61
+ from fastapi_rest_toolkit import DefaultRouter, ViewSet, CRUDService
62
+ from fastapi_rest_toolkit.permissions import IsAuthenticated, AllowAny
63
+ from fastapi_rest_toolkit.throttle import AsyncRedisSimpleRateThrottle
64
+ from sqlalchemy_crud_plus import CRUDPlus
65
+ from app.db.redis import redis_client
66
+
67
+ # 1. 定义 SQLAlchemy 模型
68
+ class User(Base):
69
+ __tablename__ = 'users'
70
+
71
+ id: Mapped[int] = mapped_column(primary_key=True)
72
+ name: Mapped[str] = mapped_column(String(50))
73
+ email: Mapped[str] = mapped_column(String(100), unique=True)
74
+ created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now())
75
+
76
+ # 2. 定义 Schema(手动或自动生成)
77
+ from pydantic import BaseModel
78
+
79
+ class UserRead(BaseModel):
80
+ id: int
81
+ email: str
82
+ name: str
83
+
84
+ class UserCreate(BaseModel):
85
+ email: str
86
+ name: str
87
+
88
+ class UserUpdate(BaseModel):
89
+ email: str | None = None
90
+ name: str | None = None
91
+
92
+ # 3. 定义 ViewSet
93
+ class UserViewSet(ViewSet):
94
+ read_schema = UserRead
95
+ create_schema = UserCreate
96
+ update_schema = UserUpdate
97
+
98
+ # 权限配置
99
+ permission_classes = (AllowAny, IsAuthenticated)
100
+
101
+ # 搜索和排序
102
+ search_fields = ("email", "name")
103
+ ordering_fields = ("id", "email", "name", "created_at")
104
+
105
+ # 节流配置
106
+ throttle_classes = (AsyncRedisSimpleRateThrottle(redis=redis_client),)
107
+
108
+ def __init__(self):
109
+ user_crud = CRUDPlus(User)
110
+ self.service = CRUDService(crud=user_crud, model=User)
111
+
112
+ # 4. 创建数据库会话
113
+ DATABASE_URL = "sqlite+aiosqlite:///./app.db"
114
+ engine = create_async_engine(DATABASE_URL, echo=False)
115
+ async_session = async_sessionmaker(bind=engine, class_=AsyncSession, expire_on_commit=False)
116
+
117
+ async def get_session():
118
+ async with async_session() as session:
119
+ yield session
120
+
121
+ # 5. 注册路由
122
+ app = FastAPI()
123
+ router = DefaultRouter()
124
+
125
+ router.register(
126
+ "users",
127
+ UserViewSet,
128
+ get_session=get_session,
129
+ get_user=get_current_user, # 可选的认证依赖
130
+ tags=["users"],
131
+ pk_type=int,
132
+ )
133
+
134
+ app.include_router(router.router, prefix="/api")
135
+ ```
136
+
137
+ ### 自动生成 Schema
138
+
139
+ 使用工具函数从 SQLAlchemy 模型自动生成 Pydantic Schema:
140
+
141
+ ```python
142
+ from fastapi_rest_toolkit.utils import sqlalchemy_model_to_pydantic
143
+ from app.models.user import User
144
+
145
+ # 自动生成 Schema
146
+ UserRead = sqlalchemy_model_to_pydantic(User, name="UserRead")
147
+ UserCreate = sqlalchemy_model_to_pydantic(User, name="UserCreate", exclude={"id"})
148
+ UserUpdate = sqlalchemy_model_to_pydantic(User, name="UserUpdate", optional=True)
149
+ ```
150
+
151
+ ### 关联数据加载
152
+
153
+ 支持加载关联数据(使用 selectinload):
154
+
155
+ ```python
156
+ class UserViewSet(ViewSet):
157
+ load_strategies = ("posts",) # 自动加载 posts 关联
158
+ ```
159
+
160
+ ### 权限控制
161
+
162
+ ```python
163
+ from fastapi_rest_toolkit.permissions import AllowAny, IsAuthenticated, IsAdmin
164
+
165
+ class ProtectedViewSet(ViewSet):
166
+ permission_classes = (IsAuthenticated,) # 需要登录
167
+
168
+ class AdminViewSet(ViewSet):
169
+ permission_classes = (IsAdmin,) # 需要管理员权限
170
+ ```
171
+
172
+ ### 搜索和排序
173
+
174
+ ```python
175
+ class UserViewSet(ViewSet):
176
+ # 支持搜索的字段
177
+ search_fields = ("name", "email")
178
+
179
+ # 支持排序的字段
180
+ ordering_fields = ("id", "name", "created_at")
181
+ ```
182
+
183
+ **API 使用示例:**
184
+
185
+ ```bash
186
+ # 搜索
187
+ GET /api/users?search=john
188
+
189
+ # 排序
190
+ GET /api/users?ordering=-created_at
191
+
192
+ # 组合使用
193
+ GET /api/users?search=john&ordering=name
194
+ ```
195
+
196
+ ### 节流配置
197
+
198
+ ```python
199
+ from fastapi_rest_toolkit.throttle import AsyncRedisSimpleRateThrottle
200
+ from app.db.redis import redis_client
201
+
202
+ class UserViewSet(ViewSet):
203
+ throttle_classes = (AsyncRedisSimpleRateThrottle(
204
+ redis=redis_client,
205
+ rate="100/hour" # 可选,默认 100/hour
206
+ ),)
207
+ ```
208
+
209
+ ### 异常处理
210
+
211
+ ```python
212
+ from fastapi import Request
213
+ from fastapi.responses import JSONResponse
214
+ from sqlalchemy.exc import IntegrityError
215
+
216
+ async def integrity_error_handler(request: Request, exc: IntegrityError) -> JSONResponse:
217
+ """处理数据库完整性约束错误"""
218
+ error_message = str(exc.orig)
219
+
220
+ if "UNIQUE constraint failed" in error_message:
221
+ parts = error_message.split(":")
222
+ if len(parts) > 1:
223
+ constraint_info = parts[1].strip()
224
+ field = constraint_info.split(".")[-1] if "." in constraint_info else constraint_info
225
+ detail = f"{field} 已存在"
226
+ else:
227
+ detail = error_message
228
+
229
+ return JSONResponse(
230
+ status_code=400,
231
+ content={"detail": detail, "error_type": "integrity_error"}
232
+ )
233
+
234
+ # 注册异常处理器
235
+ app.add_exception_handler(IntegrityError, integrity_error_handler)
236
+ ```
237
+
238
+ ## 组件说明
239
+
240
+ ### ViewSet
241
+
242
+ 提供标准的 CRUD 操作接口:
243
+
244
+ | 方法 | 路由 | 说明 |
245
+ |------|------|------|
246
+ | `list()` | `GET /api/users` | 获取列表(支持搜索、排序、分页) |
247
+ | `retrieve()` | `GET /api/users/{id}` | 获取单个对象 |
248
+ | `create()` | `POST /api/users` | 创建对象 |
249
+ | `update()` | `PUT/PATCH /api/users/{id}` | 更新对象 |
250
+ | `destroy()` | `DELETE /api/users/{id}` | 删除对象 |
251
+
252
+ ### 权限类
253
+
254
+ - `AllowAny` - 允许所有访问
255
+ - `IsAuthenticated` - 需要认证
256
+ - `IsAdmin` - 需要管理员权限
257
+ - `BasePermission` - 自定义权限基类
258
+
259
+ ### 过滤器
260
+
261
+ - `SearchFilterBackend` - 搜索过滤(使用 `search` 查询参数)
262
+ - `OrderingFilterBackend` - 排序(使用 `ordering` 查询参数)
263
+ - `CRUDPlusFilterBackend` - CRUD Plus 过滤
264
+
265
+ ### 节流类
266
+
267
+ - `SimpleRateThrottle` - 简单限流(内存存储)
268
+ - `AnonRateThrottle` - 匿名用户限流
269
+ - `AsyncRedisSimpleRateThrottle` - 基于 Redis 的异步限流
270
+
271
+ ### 工具函数
272
+
273
+ - `sqlalchemy_model_to_pydantic()` - 从 SQLAlchemy 模型生成 Pydantic Schema
274
+
275
+ ## License
276
+
277
+ MIT License
@@ -0,0 +1,246 @@
1
+ # FastAPI REST Toolkit
2
+
3
+ 类 Django REST Framework 风格的 FastAPI 工具包,提供简洁优雅的方式来构建 RESTful API。
4
+
5
+ ## 特性
6
+
7
+ - **ViewSet**: 类似 DRF 的 ViewSet,支持 CRUD 操作
8
+ - **Router**: 自动路由注册,简化路由配置
9
+ - **权限系统**: 灵活的权限控制(AllowAny、IsAuthenticated、IsAdmin)
10
+ - **过滤器**: 支持搜索、排序、CRUD Plus 过滤
11
+ - **节流**: 内置限流机制,支持 Redis 存储
12
+ - **Schema 工具**: 从 SQLAlchemy 模型自动生成 Pydantic Schema
13
+
14
+ ## 安装
15
+
16
+ ```bash
17
+ pip install fastapi-rest-toolkit
18
+ ```
19
+
20
+ ## 快速开始
21
+
22
+ ### 完整示例
23
+
24
+ ```python
25
+ from fastapi import FastAPI
26
+ from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine, async_sessionmaker
27
+ from sqlalchemy.orm import Mapped, mapped_column
28
+ from sqlalchemy import String, DateTime, func
29
+
30
+ from fastapi_rest_toolkit import DefaultRouter, ViewSet, CRUDService
31
+ from fastapi_rest_toolkit.permissions import IsAuthenticated, AllowAny
32
+ from fastapi_rest_toolkit.throttle import AsyncRedisSimpleRateThrottle
33
+ from sqlalchemy_crud_plus import CRUDPlus
34
+ from app.db.redis import redis_client
35
+
36
+ # 1. 定义 SQLAlchemy 模型
37
+ class User(Base):
38
+ __tablename__ = 'users'
39
+
40
+ id: Mapped[int] = mapped_column(primary_key=True)
41
+ name: Mapped[str] = mapped_column(String(50))
42
+ email: Mapped[str] = mapped_column(String(100), unique=True)
43
+ created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now())
44
+
45
+ # 2. 定义 Schema(手动或自动生成)
46
+ from pydantic import BaseModel
47
+
48
+ class UserRead(BaseModel):
49
+ id: int
50
+ email: str
51
+ name: str
52
+
53
+ class UserCreate(BaseModel):
54
+ email: str
55
+ name: str
56
+
57
+ class UserUpdate(BaseModel):
58
+ email: str | None = None
59
+ name: str | None = None
60
+
61
+ # 3. 定义 ViewSet
62
+ class UserViewSet(ViewSet):
63
+ read_schema = UserRead
64
+ create_schema = UserCreate
65
+ update_schema = UserUpdate
66
+
67
+ # 权限配置
68
+ permission_classes = (AllowAny, IsAuthenticated)
69
+
70
+ # 搜索和排序
71
+ search_fields = ("email", "name")
72
+ ordering_fields = ("id", "email", "name", "created_at")
73
+
74
+ # 节流配置
75
+ throttle_classes = (AsyncRedisSimpleRateThrottle(redis=redis_client),)
76
+
77
+ def __init__(self):
78
+ user_crud = CRUDPlus(User)
79
+ self.service = CRUDService(crud=user_crud, model=User)
80
+
81
+ # 4. 创建数据库会话
82
+ DATABASE_URL = "sqlite+aiosqlite:///./app.db"
83
+ engine = create_async_engine(DATABASE_URL, echo=False)
84
+ async_session = async_sessionmaker(bind=engine, class_=AsyncSession, expire_on_commit=False)
85
+
86
+ async def get_session():
87
+ async with async_session() as session:
88
+ yield session
89
+
90
+ # 5. 注册路由
91
+ app = FastAPI()
92
+ router = DefaultRouter()
93
+
94
+ router.register(
95
+ "users",
96
+ UserViewSet,
97
+ get_session=get_session,
98
+ get_user=get_current_user, # 可选的认证依赖
99
+ tags=["users"],
100
+ pk_type=int,
101
+ )
102
+
103
+ app.include_router(router.router, prefix="/api")
104
+ ```
105
+
106
+ ### 自动生成 Schema
107
+
108
+ 使用工具函数从 SQLAlchemy 模型自动生成 Pydantic Schema:
109
+
110
+ ```python
111
+ from fastapi_rest_toolkit.utils import sqlalchemy_model_to_pydantic
112
+ from app.models.user import User
113
+
114
+ # 自动生成 Schema
115
+ UserRead = sqlalchemy_model_to_pydantic(User, name="UserRead")
116
+ UserCreate = sqlalchemy_model_to_pydantic(User, name="UserCreate", exclude={"id"})
117
+ UserUpdate = sqlalchemy_model_to_pydantic(User, name="UserUpdate", optional=True)
118
+ ```
119
+
120
+ ### 关联数据加载
121
+
122
+ 支持加载关联数据(使用 selectinload):
123
+
124
+ ```python
125
+ class UserViewSet(ViewSet):
126
+ load_strategies = ("posts",) # 自动加载 posts 关联
127
+ ```
128
+
129
+ ### 权限控制
130
+
131
+ ```python
132
+ from fastapi_rest_toolkit.permissions import AllowAny, IsAuthenticated, IsAdmin
133
+
134
+ class ProtectedViewSet(ViewSet):
135
+ permission_classes = (IsAuthenticated,) # 需要登录
136
+
137
+ class AdminViewSet(ViewSet):
138
+ permission_classes = (IsAdmin,) # 需要管理员权限
139
+ ```
140
+
141
+ ### 搜索和排序
142
+
143
+ ```python
144
+ class UserViewSet(ViewSet):
145
+ # 支持搜索的字段
146
+ search_fields = ("name", "email")
147
+
148
+ # 支持排序的字段
149
+ ordering_fields = ("id", "name", "created_at")
150
+ ```
151
+
152
+ **API 使用示例:**
153
+
154
+ ```bash
155
+ # 搜索
156
+ GET /api/users?search=john
157
+
158
+ # 排序
159
+ GET /api/users?ordering=-created_at
160
+
161
+ # 组合使用
162
+ GET /api/users?search=john&ordering=name
163
+ ```
164
+
165
+ ### 节流配置
166
+
167
+ ```python
168
+ from fastapi_rest_toolkit.throttle import AsyncRedisSimpleRateThrottle
169
+ from app.db.redis import redis_client
170
+
171
+ class UserViewSet(ViewSet):
172
+ throttle_classes = (AsyncRedisSimpleRateThrottle(
173
+ redis=redis_client,
174
+ rate="100/hour" # 可选,默认 100/hour
175
+ ),)
176
+ ```
177
+
178
+ ### 异常处理
179
+
180
+ ```python
181
+ from fastapi import Request
182
+ from fastapi.responses import JSONResponse
183
+ from sqlalchemy.exc import IntegrityError
184
+
185
+ async def integrity_error_handler(request: Request, exc: IntegrityError) -> JSONResponse:
186
+ """处理数据库完整性约束错误"""
187
+ error_message = str(exc.orig)
188
+
189
+ if "UNIQUE constraint failed" in error_message:
190
+ parts = error_message.split(":")
191
+ if len(parts) > 1:
192
+ constraint_info = parts[1].strip()
193
+ field = constraint_info.split(".")[-1] if "." in constraint_info else constraint_info
194
+ detail = f"{field} 已存在"
195
+ else:
196
+ detail = error_message
197
+
198
+ return JSONResponse(
199
+ status_code=400,
200
+ content={"detail": detail, "error_type": "integrity_error"}
201
+ )
202
+
203
+ # 注册异常处理器
204
+ app.add_exception_handler(IntegrityError, integrity_error_handler)
205
+ ```
206
+
207
+ ## 组件说明
208
+
209
+ ### ViewSet
210
+
211
+ 提供标准的 CRUD 操作接口:
212
+
213
+ | 方法 | 路由 | 说明 |
214
+ |------|------|------|
215
+ | `list()` | `GET /api/users` | 获取列表(支持搜索、排序、分页) |
216
+ | `retrieve()` | `GET /api/users/{id}` | 获取单个对象 |
217
+ | `create()` | `POST /api/users` | 创建对象 |
218
+ | `update()` | `PUT/PATCH /api/users/{id}` | 更新对象 |
219
+ | `destroy()` | `DELETE /api/users/{id}` | 删除对象 |
220
+
221
+ ### 权限类
222
+
223
+ - `AllowAny` - 允许所有访问
224
+ - `IsAuthenticated` - 需要认证
225
+ - `IsAdmin` - 需要管理员权限
226
+ - `BasePermission` - 自定义权限基类
227
+
228
+ ### 过滤器
229
+
230
+ - `SearchFilterBackend` - 搜索过滤(使用 `search` 查询参数)
231
+ - `OrderingFilterBackend` - 排序(使用 `ordering` 查询参数)
232
+ - `CRUDPlusFilterBackend` - CRUD Plus 过滤
233
+
234
+ ### 节流类
235
+
236
+ - `SimpleRateThrottle` - 简单限流(内存存储)
237
+ - `AnonRateThrottle` - 匿名用户限流
238
+ - `AsyncRedisSimpleRateThrottle` - 基于 Redis 的异步限流
239
+
240
+ ### 工具函数
241
+
242
+ - `sqlalchemy_model_to_pydantic()` - 从 SQLAlchemy 模型生成 Pydantic Schema
243
+
244
+ ## License
245
+
246
+ MIT License