toms-fast 0.2.1__py3-none-any.whl

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.
Files changed (60) hide show
  1. toms_fast-0.2.1.dist-info/METADATA +467 -0
  2. toms_fast-0.2.1.dist-info/RECORD +60 -0
  3. toms_fast-0.2.1.dist-info/WHEEL +4 -0
  4. toms_fast-0.2.1.dist-info/entry_points.txt +2 -0
  5. tomskit/__init__.py +0 -0
  6. tomskit/celery/README.md +693 -0
  7. tomskit/celery/__init__.py +4 -0
  8. tomskit/celery/celery.py +306 -0
  9. tomskit/celery/config.py +377 -0
  10. tomskit/cli/__init__.py +207 -0
  11. tomskit/cli/__main__.py +8 -0
  12. tomskit/cli/scaffold.py +123 -0
  13. tomskit/cli/templates/__init__.py +42 -0
  14. tomskit/cli/templates/base.py +348 -0
  15. tomskit/cli/templates/celery.py +101 -0
  16. tomskit/cli/templates/extensions.py +213 -0
  17. tomskit/cli/templates/fastapi.py +400 -0
  18. tomskit/cli/templates/migrations.py +281 -0
  19. tomskit/cli/templates_config.py +122 -0
  20. tomskit/logger/README.md +466 -0
  21. tomskit/logger/__init__.py +4 -0
  22. tomskit/logger/config.py +106 -0
  23. tomskit/logger/logger.py +290 -0
  24. tomskit/py.typed +0 -0
  25. tomskit/redis/README.md +462 -0
  26. tomskit/redis/__init__.py +6 -0
  27. tomskit/redis/config.py +85 -0
  28. tomskit/redis/redis_pool.py +87 -0
  29. tomskit/redis/redis_sync.py +66 -0
  30. tomskit/server/__init__.py +47 -0
  31. tomskit/server/config.py +117 -0
  32. tomskit/server/exceptions.py +412 -0
  33. tomskit/server/middleware.py +371 -0
  34. tomskit/server/parser.py +312 -0
  35. tomskit/server/resource.py +464 -0
  36. tomskit/server/server.py +276 -0
  37. tomskit/server/type.py +263 -0
  38. tomskit/sqlalchemy/README.md +590 -0
  39. tomskit/sqlalchemy/__init__.py +20 -0
  40. tomskit/sqlalchemy/config.py +125 -0
  41. tomskit/sqlalchemy/database.py +125 -0
  42. tomskit/sqlalchemy/pagination.py +359 -0
  43. tomskit/sqlalchemy/property.py +19 -0
  44. tomskit/sqlalchemy/sqlalchemy.py +131 -0
  45. tomskit/sqlalchemy/types.py +32 -0
  46. tomskit/task/README.md +67 -0
  47. tomskit/task/__init__.py +4 -0
  48. tomskit/task/task_manager.py +124 -0
  49. tomskit/tools/README.md +63 -0
  50. tomskit/tools/__init__.py +18 -0
  51. tomskit/tools/config.py +70 -0
  52. tomskit/tools/warnings.py +37 -0
  53. tomskit/tools/woker.py +81 -0
  54. tomskit/utils/README.md +666 -0
  55. tomskit/utils/README_SERIALIZER.md +644 -0
  56. tomskit/utils/__init__.py +35 -0
  57. tomskit/utils/fields.py +434 -0
  58. tomskit/utils/marshal_utils.py +137 -0
  59. tomskit/utils/response_utils.py +13 -0
  60. tomskit/utils/serializers.py +447 -0
@@ -0,0 +1,644 @@
1
+ # AsyncSerializer 使用指南
2
+
3
+ ## 概述
4
+
5
+ `AsyncSerializer` 是一个通用的异步序列化器,专为 Pydantic V2 设计,能够将 ORM 对象、字典或混合数据源转换为 Pydantic 模型。它支持异步属性、函数调用、嵌套模型、并发处理等高级特性。
6
+
7
+ **Import Path:**
8
+ ```python
9
+ from tomskit.utils.serializers import AsyncSerializer
10
+ ```
11
+
12
+ ## 核心特性
13
+
14
+ ### ✨ 主要功能
15
+
16
+ 1. **多数据源支持**
17
+ - ORM 对象(如 SQLAlchemy 模型)
18
+ - 字典数据
19
+ - 混合数据源(对象 + 字典)
20
+
21
+ 2. **异步属性自动处理**
22
+ - 自动识别并 `await` 异步属性(`@property async def`)
23
+ - 自动调用函数/异步函数
24
+ - 支持协程对象
25
+
26
+ 3. **智能类型处理**
27
+ - 自动处理嵌套 Pydantic 模型
28
+ - 支持 `List`、`Dict`、`Set`、`Tuple` 等集合类型
29
+ - 智能处理 `Union` 和 `Optional` 类型
30
+
31
+ 4. **并发处理**
32
+ - 列表序列化自动并发处理
33
+ - 大列表自动分批处理(每批 100 项)
34
+ - 嵌套列表/字典/集合也支持并发处理
35
+
36
+ 5. **Pydantic V2 兼容**
37
+ - 正确处理 `validation_alias`(支持字符串)
38
+ - 支持字段默认值和 `default_factory`
39
+ - 智能处理字段别名
40
+
41
+ 6. **性能优化**
42
+ - 字段元数据缓存,避免重复计算
43
+ - 大列表分批处理,避免资源耗尽
44
+ - 已实例化的模型直接返回,避免重复序列化
45
+
46
+ ## 快速开始
47
+
48
+ ### 基础用法
49
+
50
+ ```python
51
+ from pydantic import BaseModel
52
+ from tomskit.utils.serializers import AsyncSerializer
53
+
54
+ # 定义 Pydantic 模型
55
+ class UserModel(BaseModel):
56
+ id: int
57
+ name: str
58
+ email: str
59
+ age: int = 0
60
+
61
+ # 从字典序列化
62
+ data = {"id": 1, "name": "张三", "email": "zhangsan@example.com", "age": 25}
63
+ user = await AsyncSerializer.serialize(UserModel, data)
64
+ print(user.name) # 输出: 张三
65
+
66
+ # 从 ORM 对象序列化
67
+ class UserORM:
68
+ def __init__(self):
69
+ self.id = 1
70
+ self.name = "李四"
71
+ self.email = "lisi@example.com"
72
+ self.age = 30
73
+
74
+ orm_user = UserORM()
75
+ user = await AsyncSerializer.serialize(UserModel, orm_user)
76
+ print(user.name) # 输出: 李四
77
+ ```
78
+
79
+ ## API 文档
80
+
81
+ ### serialize
82
+
83
+ 单对象序列化入口。
84
+
85
+ ```python
86
+ @classmethod
87
+ async def serialize(
88
+ cls,
89
+ model_cls: Type[T],
90
+ source_data: Any
91
+ ) -> T | None
92
+ ```
93
+
94
+ **参数:**
95
+ - `model_cls`: Pydantic 模型类
96
+ - `source_data`: 数据源(ORM 对象 / 字典 / 混合体)
97
+
98
+ **返回:**
99
+ - 序列化后的 Pydantic 模型实例
100
+ - 如果 `source_data` 为 `None`,返回 `None`
101
+ - 如果 `source_data` 已经是该模型的实例,直接返回(避免重复序列化)
102
+
103
+ **示例:**
104
+ ```python
105
+ # 字典数据
106
+ data = {"id": 1, "name": "张三"}
107
+ user = await AsyncSerializer.serialize(UserModel, data)
108
+
109
+ # ORM 对象
110
+ orm_user = UserORM(id=1, name="张三")
111
+ user = await AsyncSerializer.serialize(UserModel, orm_user)
112
+
113
+ # None 值
114
+ result = await AsyncSerializer.serialize(UserModel, None)
115
+ assert result is None
116
+ ```
117
+
118
+ ### serialize_list
119
+
120
+ 列表序列化入口(并发处理)。
121
+
122
+ ```python
123
+ @classmethod
124
+ async def serialize_list(
125
+ cls,
126
+ model_cls: Type[T],
127
+ items: Sequence[Any] | Iterable[Any]
128
+ ) -> list[T]
129
+ ```
130
+
131
+ **参数:**
132
+ - `model_cls`: Pydantic 模型类
133
+ - `items`: 待序列化的对象列表(支持任何可迭代对象)
134
+
135
+ **返回:**
136
+ - 序列化后的模型列表(自动过滤掉 `None` 值)
137
+
138
+ **特性:**
139
+ - 自动并发处理,提升性能
140
+ - 小列表(≤100 项)直接并发处理
141
+ - 大列表(>100 项)自动分批处理,每批 100 项
142
+
143
+ **示例:**
144
+ ```python
145
+ items = [
146
+ {"id": 1, "name": "张三"},
147
+ {"id": 2, "name": "李四"},
148
+ None, # None 值会被自动过滤
149
+ {"id": 3, "name": "王五"}
150
+ ]
151
+
152
+ users = await AsyncSerializer.serialize_list(UserModel, items)
153
+ # 返回: [UserModel(id=1, name="张三"), UserModel(id=2, name="李四"), UserModel(id=3, name="王五")]
154
+ ```
155
+
156
+ ### serialize_pagination
157
+
158
+ 分页对象序列化入口。
159
+
160
+ ```python
161
+ @classmethod
162
+ async def serialize_pagination(
163
+ cls,
164
+ pagination_obj: Any,
165
+ model_cls: Type[T]
166
+ ) -> dict[str, Any]
167
+ ```
168
+
169
+ **参数:**
170
+ - `pagination_obj`: 分页对象,需要具有以下属性之一:
171
+ - `items`: 数据项列表
172
+ - `page`: 当前页码
173
+ - `per_page` 或 `limit`: 每页数量
174
+ - `total`: 总记录数
175
+ - `model_cls`: 数据项的 Pydantic 模型类
176
+
177
+ **返回:**
178
+ 包含以下字段的字典:
179
+ - `page`: 当前页码
180
+ - `limit`: 每页数量
181
+ - `total`: 总记录数
182
+ - `has_more`: 是否还有更多数据
183
+ - `data`: 序列化后的数据列表
184
+
185
+ **示例:**
186
+ ```python
187
+ class MockPagination:
188
+ def __init__(self):
189
+ self.page = 1
190
+ self.per_page = 10
191
+ self.total = 25
192
+ self.items = [
193
+ {"id": i, "name": f"用户{i}"}
194
+ for i in range(1, 11)
195
+ ]
196
+
197
+ pagination = MockPagination()
198
+ result = await AsyncSerializer.serialize_pagination(pagination, UserModel)
199
+
200
+ # 返回:
201
+ # {
202
+ # "page": 1,
203
+ # "limit": 10,
204
+ # "total": 25,
205
+ # "has_more": True,
206
+ # "data": [UserModel(...), ...]
207
+ # }
208
+ ```
209
+
210
+ ## 高级功能
211
+
212
+ ### 1. 异步属性支持
213
+
214
+ 自动识别并 `await` 异步属性。
215
+
216
+ ```python
217
+ class UserORM:
218
+ def __init__(self, name: str):
219
+ self.name = name
220
+
221
+ @property
222
+ async def full_name(self):
223
+ await asyncio.sleep(0.01) # 模拟异步操作
224
+ return f"{self.name} (Full)"
225
+
226
+ class UserModel(BaseModel):
227
+ name: str
228
+ full_name: str | None = None
229
+
230
+ orm_user = UserORM("张三")
231
+ user = await AsyncSerializer.serialize(UserModel, orm_user)
232
+ print(user.full_name) # 输出: 张三 (Full)
233
+ ```
234
+
235
+ ### 2. 函数自动调用
236
+
237
+ 自动调用字典中的函数或对象属性中的函数。
238
+
239
+ ```python
240
+ # 字典中的函数
241
+ data = {
242
+ "name": "张三",
243
+ "display_name": lambda: "员工-张三" # 自动调用
244
+ }
245
+
246
+ # 字典中的异步函数(直接传递函数对象)
247
+ async def get_async_name():
248
+ await asyncio.sleep(0.01)
249
+ return "异步名称"
250
+
251
+ data = {
252
+ "name": "张三",
253
+ "display_name": get_async_name # 传递函数对象,会自动调用并 await
254
+ }
255
+
256
+ user = await AsyncSerializer.serialize(UserModel, data)
257
+ ```
258
+
259
+ ### 3. 嵌套模型序列化
260
+
261
+ 支持多层嵌套的 Pydantic 模型。
262
+
263
+ ```python
264
+ class AddressModel(BaseModel):
265
+ city: str
266
+ street: str
267
+
268
+ class UserModel(BaseModel):
269
+ name: str
270
+ address: AddressModel # 嵌套模型
271
+
272
+ data = {
273
+ "name": "张三",
274
+ "address": {
275
+ "city": "北京",
276
+ "street": "中关村大街"
277
+ }
278
+ }
279
+
280
+ user = await AsyncSerializer.serialize(UserModel, data)
281
+ print(user.address.city) # 输出: 北京
282
+ ```
283
+
284
+ ### 4. 列表嵌套序列化
285
+
286
+ 支持列表中的嵌套模型,自动并发处理。
287
+
288
+ ```python
289
+ class UserModel(BaseModel):
290
+ name: str
291
+
292
+ class DepartmentModel(BaseModel):
293
+ name: str
294
+ users: list[UserModel] # 列表嵌套
295
+
296
+ data = {
297
+ "name": "技术部",
298
+ "users": [
299
+ {"name": "张三"},
300
+ {"name": "李四"}
301
+ ]
302
+ }
303
+
304
+ dept = await AsyncSerializer.serialize(DepartmentModel, data)
305
+ # users 列表会自动并发序列化
306
+ ```
307
+
308
+ ### 5. validation_alias 支持
309
+
310
+ 正确处理 Pydantic V2 的字段别名。
311
+
312
+ ```python
313
+ from pydantic import Field, BaseModel
314
+
315
+ class UserModel(BaseModel):
316
+ user_id: int = Field(validation_alias="userId")
317
+ user_name: str = Field(validation_alias="userName")
318
+
319
+ # 使用别名
320
+ data = {
321
+ "userId": 1,
322
+ "userName": "张三"
323
+ }
324
+
325
+ user = await AsyncSerializer.serialize(UserModel, data)
326
+ print(user.user_id) # 输出: 1
327
+ print(user.user_name) # 输出: 张三
328
+
329
+ # 也支持回退到字段名
330
+ data = {
331
+ "user_id": 1, # 使用字段名也可以
332
+ "userName": "张三"
333
+ }
334
+
335
+ user = await AsyncSerializer.serialize(UserModel, data)
336
+ ```
337
+
338
+ ### 6. 默认值处理
339
+
340
+ 智能处理字段默认值。
341
+
342
+ ```python
343
+ class UserModel(BaseModel):
344
+ name: str
345
+ profile: dict = Field(default_factory=dict) # 有默认值
346
+ age: int | None = None # 默认值是 None
347
+
348
+ # 如果字段有默认值且值为 None,会跳过让 Pydantic 使用默认值
349
+ data = {"name": "张三"} # profile 会使用默认值 {}
350
+ user = await AsyncSerializer.serialize(UserModel, data)
351
+ print(user.profile) # 输出: {}
352
+
353
+ # 如果默认值本身就是 None,会传递 None
354
+ data = {"name": "张三", "age": None}
355
+ user = await AsyncSerializer.serialize(UserModel, data)
356
+ print(user.age) # 输出: None
357
+ ```
358
+
359
+ ### 7. 混合数据源
360
+
361
+ 支持在同一数据源中混合使用对象和字典。
362
+
363
+ ```python
364
+ class UserORM:
365
+ def __init__(self):
366
+ self.id = 1
367
+ self.name = "张三"
368
+
369
+ # 字典中包含 ORM 对象
370
+ data = {
371
+ "id": 1,
372
+ "name": "张三",
373
+ "profile": {"age": 25} # 字典数据
374
+ }
375
+
376
+ # 或者对象中包含字典
377
+ orm_user = UserORM()
378
+ orm_user.profile = {"age": 25}
379
+
380
+ user = await AsyncSerializer.serialize(UserModel, data)
381
+ ```
382
+
383
+ ## 完整示例
384
+
385
+ ### 3层嵌套示例
386
+
387
+ ```python
388
+ from typing import List, Optional, Dict, Any
389
+ from pydantic import BaseModel, Field
390
+ from tomskit.utils.serializers import AsyncSerializer
391
+
392
+ # 第3层:员工
393
+ class EmployeeModel(BaseModel):
394
+ id: int
395
+ name: str
396
+ email: str
397
+ salary: float
398
+ profile: Dict[str, Any] = Field(default_factory=dict)
399
+ full_name: Optional[str] = None
400
+
401
+ # 第2层:部门
402
+ class DepartmentModel(BaseModel):
403
+ id: int
404
+ name: str
405
+ budget: Optional[float] = None
406
+ config: Dict[str, Any] = Field(default_factory=dict)
407
+ employees: List[EmployeeModel] = Field(default_factory=list)
408
+
409
+ # 第1层:公司
410
+ class CompanyModel(BaseModel):
411
+ id: int
412
+ name: str
413
+ total_employees: Optional[int] = None
414
+ metadata: Dict[str, Any] = Field(default_factory=dict)
415
+ departments: List[DepartmentModel] = Field(default_factory=list)
416
+
417
+ # ORM 对象(带异步属性)
418
+ class EmployeeORM:
419
+ def __init__(self, id: int, name: str, email: str, salary: float):
420
+ self.id = id
421
+ self.name = name
422
+ self.email = email
423
+ self.salary = salary
424
+
425
+ @property
426
+ async def full_name(self):
427
+ await asyncio.sleep(0.01)
428
+ return f"{self.name} (ID: {self.id})"
429
+
430
+ class DepartmentORM:
431
+ def __init__(self, id: int, name: str, employees: list):
432
+ self.id = id
433
+ self.name = name
434
+ self._employees = employees
435
+
436
+ @property
437
+ async def budget(self):
438
+ await asyncio.sleep(0.01)
439
+ return 100000.0 + (self.id * 10000)
440
+
441
+ @property
442
+ def employees(self):
443
+ return self._employees
444
+
445
+ class CompanyORM:
446
+ def __init__(self, id: int, name: str, departments: list):
447
+ self.id = id
448
+ self.name = name
449
+ self._departments = departments
450
+
451
+ @property
452
+ async def total_employees(self):
453
+ await asyncio.sleep(0.01)
454
+ count = 0
455
+ for dept in self._departments:
456
+ count += len(getattr(dept, 'employees', []))
457
+ return count
458
+
459
+ @property
460
+ def departments(self):
461
+ return self._departments
462
+
463
+ # 使用
464
+ employees = [
465
+ EmployeeORM(id=1, name="张三", email="zhangsan@example.com", salary=5000.0),
466
+ EmployeeORM(id=2, name="李四", email="lisi@example.com", salary=6000.0)
467
+ ]
468
+
469
+ dept = DepartmentORM(
470
+ id=1,
471
+ name="技术部",
472
+ employees=employees
473
+ )
474
+
475
+ company = CompanyORM(
476
+ id=1,
477
+ name="测试公司",
478
+ departments=[dept]
479
+ )
480
+
481
+ # 序列化(自动处理所有异步属性)
482
+ result = await AsyncSerializer.serialize(CompanyModel, company)
483
+
484
+ # 验证结果
485
+ assert result.id == 1
486
+ assert result.name == "测试公司"
487
+ assert result.total_employees == 2 # 异步属性已 await
488
+ assert len(result.departments) == 1
489
+ assert result.departments[0].budget == 110000.0 # 异步属性已 await
490
+ assert len(result.departments[0].employees) == 2
491
+ assert result.departments[0].employees[0].full_name == "张三 (ID: 1)" # 异步属性已 await
492
+ ```
493
+
494
+ ## 性能特性
495
+
496
+ ### 并发处理
497
+
498
+ - **列表序列化**:自动使用 `asyncio.gather` 并发处理
499
+ - **嵌套列表**:嵌套列表中的模型也会并发序列化
500
+ - **大列表优化**:超过 100 项的列表自动分批处理,避免资源耗尽
501
+
502
+ ### 缓存机制
503
+
504
+ - **字段键名缓存**:字段的 `validation_alias` 解析结果会被缓存
505
+ - **Pydantic 键名缓存**:传递给 Pydantic 的键名会被缓存
506
+ - **避免重复序列化**:如果源数据已经是目标模型的实例,直接返回
507
+
508
+ ### 分批处理
509
+
510
+ 对于大列表、大字典、大集合,自动分批处理:
511
+ - 列表:每批 100 项
512
+ - 字典:每批 100 个键
513
+ - 集合:每批 100 项
514
+
515
+ ## 注意事项
516
+
517
+ ### 1. 异步函数处理
518
+
519
+ 序列化器**会自动调用**异步函数对象。应该直接传递函数对象,而不是协程:
520
+
521
+ ```python
522
+ # ✅ 正确:传递函数对象(推荐)
523
+ data = {"name": async_func} # 会自动调用并 await
524
+
525
+ # ❌ 不推荐:传递协程
526
+ data = {"name": async_func()} # 虽然也能工作,但不推荐
527
+ ```
528
+
529
+ **注意**:虽然传递协程也能工作(会被自动 await),但推荐传递函数对象,这样更一致且更清晰。
530
+
531
+ ### 2. None 值处理
532
+
533
+ - 对于字典:如果键存在但值为 `None`,会返回 `None`(`None` 可能是有效值)
534
+ - 对于对象:如果属性存在但值为 `None`,会返回 `None`
535
+ - 对于字段默认值:如果字段有默认值且值为 `None`,会跳过让 Pydantic 使用默认值(除非默认值本身就是 `None`)
536
+
537
+ ### 3. 大列表性能
538
+
539
+ 对于非常大的列表(>10000 项),建议:
540
+ - 使用分批处理(已自动实现)
541
+ - 考虑使用生成器或流式处理
542
+ - 监控内存使用情况
543
+
544
+ ### 4. 类型注解
545
+
546
+ 虽然类型注解是可选的,但提供类型注解可以获得更好的类型推断和性能:
547
+ - 嵌套模型需要类型注解才能正确序列化
548
+ - Union 类型需要类型注解才能智能匹配
549
+
550
+ ## 最佳实践
551
+
552
+ ### 1. 定义清晰的 Pydantic 模型
553
+
554
+ ```python
555
+ class UserModel(BaseModel):
556
+ id: int
557
+ name: str
558
+ email: str
559
+ profile: dict = Field(default_factory=dict) # 使用 default_factory
560
+ created_at: datetime | None = None # Optional 类型
561
+ ```
562
+
563
+ ### 2. 使用类型注解
564
+
565
+ ```python
566
+ class DepartmentModel(BaseModel):
567
+ name: str
568
+ users: list[UserModel] # 明确指定嵌套类型
569
+ ```
570
+
571
+ ### 3. 处理异步属性
572
+
573
+ ```python
574
+ class UserORM:
575
+ @property
576
+ async def full_name(self):
577
+ # 异步属性会自动 await
578
+ return await get_full_name(self.id)
579
+ ```
580
+
581
+ ### 4. 利用并发处理
582
+
583
+ ```python
584
+ # 列表会自动并发处理,无需手动优化
585
+ users = await AsyncSerializer.serialize_list(UserModel, user_list)
586
+ ```
587
+
588
+ ## 常见问题
589
+
590
+ ### Q: 如何处理字段别名?
591
+
592
+ A: 使用 Pydantic 的 `Field(validation_alias="...")`,序列化器会自动处理。
593
+
594
+ ### Q: 大列表会内存溢出吗?
595
+
596
+ A: 不会。序列化器会自动分批处理大列表(每批 100 项),避免资源耗尽。
597
+
598
+ ### Q: 支持哪些数据源?
599
+
600
+ A: 支持字典、ORM 对象、以及它们的混合体。只要数据可以通过字典键或对象属性访问即可。
601
+
602
+ ### Q: 如何处理嵌套的异步属性?
603
+
604
+ A: 序列化器会自动递归处理嵌套模型,并自动 await 所有异步属性。
605
+
606
+ ### Q: 性能如何?
607
+
608
+ A:
609
+ - 小列表(≤100 项):并发处理,性能优秀
610
+ - 大列表(>100 项):分批并发处理,避免资源问题
611
+ - 字段元数据缓存:避免重复计算
612
+ - 已实例化模型:直接返回,零开销
613
+
614
+ ## 技术细节
615
+
616
+ ### 支持的集合类型
617
+
618
+ - `List[T]` / `list[T]`
619
+ - `Tuple[T, ...]` / `tuple[T, ...]`
620
+ - `Dict[str, T]` / `dict[str, T]`
621
+ - `Set[T]` / `set[T]`
622
+ - `Sequence[T]` / `Iterable[T]`
623
+
624
+ ### 支持的 Union 类型
625
+
626
+ - `Union[A, B]`
627
+ - `Optional[T]` (等价于 `Union[T, None]`)
628
+ - 智能类型匹配:根据实际值类型选择最匹配的 Union 成员
629
+
630
+ ### validation_alias 支持
631
+
632
+ - 字符串别名:`Field(validation_alias="userId")`
633
+ - AliasChoices:`Field(validation_alias=AliasChoices("userId", "user_id"))`
634
+ - AliasPath:`Field(validation_alias=AliasPath("user", "id"))`
635
+
636
+ ## 版本要求
637
+
638
+ - Python >= 3.11
639
+ - Pydantic >= 2.0
640
+
641
+ ## 相关文档
642
+
643
+ - [Pydantic V2 文档](https://docs.pydantic.dev/)
644
+ - [测试用例](../tests/test_serializers/test_async_serializer.py)
@@ -0,0 +1,35 @@
1
+ from tomskit.utils.marshal_utils import marshal, marshal_with, marshal_with_field
2
+ from tomskit.utils.fields import (
3
+ String,
4
+ DateTime,
5
+ Float,
6
+ Integer,
7
+ Nested,
8
+ List,
9
+ Raw,
10
+ Boolean,
11
+ FormattedString,
12
+ Arbitrary,
13
+ Fixed,
14
+ Price,
15
+ MarshallingException,
16
+ )
17
+
18
+ __all__ = [
19
+ 'marshal',
20
+ 'marshal_with',
21
+ 'marshal_with_field',
22
+ 'String',
23
+ 'DateTime',
24
+ 'Float',
25
+ 'Integer',
26
+ 'Nested',
27
+ 'List',
28
+ 'Raw',
29
+ 'Boolean',
30
+ 'FormattedString',
31
+ 'Arbitrary',
32
+ 'Fixed',
33
+ 'Price',
34
+ 'MarshallingException',
35
+ ]