当前位置: 首页 > news >正文

autogen_core中的DataclassJsonMessageSerializer类

源代码

import json
from dataclasses import asdict, dataclass, fields
from typing import Any, ClassVar, Dict, List, Protocol, Sequence, TypeVar, cast, get_args, get_origin, runtime_checkable, Union
from pydantic import BaseModelfrom types import NoneType, UnionTypedef _type_name(cls: type[Any] | Any) -> str:if isinstance(cls, type):return cls.__name__else:return cast(str, cls.__class__.__name__)def is_union(t: object) -> bool:origin = get_origin(t)return origin is Union or origin is UnionTypeT = TypeVar("T")class MessageSerializer(Protocol[T]):@propertydef data_content_type(self) -> str: ...@propertydef type_name(self) -> str: ...def deserialize(self, payload: bytes) -> T: ...def serialize(self, message: T) -> bytes: ...@runtime_checkable
class IsDataclass(Protocol):# as already noted in comments, checking for this attribute is currently# the most reliable way to ascertain that something is a dataclass__dataclass_fields__: ClassVar[Dict[str, Any]]def is_dataclass(cls: type[Any]) -> bool:return hasattr(cls, "__dataclass_fields__")def has_nested_dataclass(cls: type[IsDataclass]) -> bool:# iterate fields and check if any of them are dataclassesreturn any(is_dataclass(f.type) for f in cls.__dataclass_fields__.values())def contains_a_union(cls: type[IsDataclass]) -> bool:return any(is_union(f.type) for f in cls.__dataclass_fields__.values())def has_nested_base_model(cls: type[IsDataclass]) -> bool:for f in fields(cls):field_type = f.type# Resolve forward references and other annotationsorigin = get_origin(field_type)args = get_args(field_type)# If the field type is directly a subclass of BaseModelif isinstance(field_type, type) and issubclass(field_type, BaseModel):return True# If the field type is a generic type like List[BaseModel], Tuple[BaseModel, ...], etc.if origin is not None and args:for arg in args:# Recursively check the argument typesif isinstance(arg, type) and issubclass(arg, BaseModel):return Trueelif get_origin(arg) is not None:# Handle nested generics like List[List[BaseModel]]if has_nested_base_model_in_type(arg):return True# Handle Union typeselif args:for arg in args:if isinstance(arg, type) and issubclass(arg, BaseModel):return Trueelif get_origin(arg) is not None:if has_nested_base_model_in_type(arg):return Truereturn Falsedef has_nested_base_model_in_type(tp: Any) -> bool:"""Helper function to check if a type or its arguments is a BaseModel subclass."""origin = get_origin(tp)args = get_args(tp)if isinstance(tp, type) and issubclass(tp, BaseModel):return Trueif origin is not None and args:for arg in args:if has_nested_base_model_in_type(arg):return Truereturn FalseDataclassT = TypeVar("DataclassT", bound=IsDataclass)JSON_DATA_CONTENT_TYPE = "application/json"
"""JSON data content type"""# TODO: what's the correct content type? There seems to be some disagreement over what it should be
PROTOBUF_DATA_CONTENT_TYPE = "application/x-protobuf"
"""Protobuf data content type"""class DataclassJsonMessageSerializer(MessageSerializer[DataclassT]):def __init__(self, cls: type[DataclassT]) -> None:if contains_a_union(cls):raise ValueError("Dataclass has a union type, which is not supported. To use a union, use a Pydantic model")if has_nested_dataclass(cls) or has_nested_base_model(cls):raise ValueError("Dataclass has nested dataclasses or base models, which are not supported. To use nested types, use a Pydantic model")self.cls = cls@propertydef data_content_type(self) -> str:return JSON_DATA_CONTENT_TYPE@propertydef type_name(self) -> str:return _type_name(self.cls)def deserialize(self, payload: bytes) -> DataclassT:message_str = payload.decode("utf-8")return self.cls(**json.loads(message_str))def serialize(self, message: DataclassT) -> bytes:return json.dumps(asdict(message)).encode("utf-8")

代码解释

这段代码定义了一个用于序列化和反序列化数据类(dataclass)和 Pydantic 模型的序列化器,特别是针对 JSON 格式。它的目标是提供一种结构化的方式来序列化和反序列化消息,并检查不支持的特性,例如嵌套的数据类、嵌套的 Pydantic 模型以及数据类中联合类型(union type)。

1. 导入

import json
from dataclasses import asdict, dataclass, fields
from typing import Any, ClassVar, Dict, List, Protocol, Sequence, TypeVar, cast, get_args, get_origin, runtime_checkable, Union
from pydantic import BaseModelfrom types import NoneType, UnionType

这部分导入了必要的模块:

  • json: 用于 JSON 序列化/反序列化。
  • dataclasses: 用于处理数据类 (asdict, dataclass, fields)。
  • typing: 用于类型提示和处理泛型 (Any, ClassVar, Dict, List, Protocol, Sequence, TypeVar, cast, get_args, get_origin, runtime_checkable, Union)。
  • pydantic: 用于处理 Pydantic 模型 (BaseModel)。
  • types: 用于处理类型提示,包括 NoneTypeUnionType

2. 辅助函数

  • _type_name(cls): 返回类或对象的名称。
  • is_union(t): 检查类型 t 是否为 UnionUnionType
  • is_dataclass(cls): 检查类 cls 是否为数据类。
  • has_nested_dataclass(cls): 检查数据类 cls 是否包含任何嵌套的数据类作为字段。
  • contains_a_union(cls): 检查数据类 cls 是否包含任何 Union 类型作为字段类型。
  • has_nested_base_model(cls): 检查数据类 cls 是否包含任何嵌套的 Pydantic BaseModel 子类作为字段,包括处理 List[BaseModel] 等泛型和嵌套泛型。
  • has_nested_base_model_in_type(tp): has_nested_base_model 使用的辅助函数,用于递归检查类型或其参数是否为 BaseModel 子类。

3. 类型变量和常量

  • T: 一个泛型类型变量。
  • DataclassT: 绑定到 IsDataclass 的类型变量。
  • JSON_DATA_CONTENT_TYPE: JSON 内容类型的常量。
  • PROTOBUF_DATA_CONTENT_TYPE: Protobuf 内容类型的常量(虽然在 JSON 序列化器中未使用)。

4. MessageSerializer 协议

class MessageSerializer(Protocol[T]):@propertydef data_content_type(self) -> str: ...@propertydef type_name(self) -> str: ...def deserialize(self, payload: bytes) -> T: ...def serialize(self, message: T) -> bytes: ...

定义了消息序列化器的协议(接口)。任何实现此协议的类都必须定义指定的属性和方法:

  • data_content_type: 序列化数据的 MIME 类型。
  • type_name: 被序列化类型的名称。
  • deserialize(payload): 将字节负载反序列化为 T 类型的对象。
  • serialize(message): 将 T 类型的对象序列化为字节负载。

5. IsDataclass 协议

@runtime_checkable
class IsDataclass(Protocol):__dataclass_fields__: ClassVar[Dict[str, Any]]

一个运行时可检查的协议,用于确定类是否为数据类。它检查 __dataclass_fields__ 属性是否存在。

6. DataclassJsonMessageSerializer

class DataclassJsonMessageSerializer(MessageSerializer[DataclassT]):# ...

此类实现了 MessageSerializer 协议,用于数据类的 JSON 序列化。

  • __init__(self, cls): 构造函数,它接受数据类类型 cls 作为参数。它执行关键检查:
    • 如果数据类包含 Union 类型,则引发 ValueError(使用 Pydantic 处理联合类型)。
    • 如果数据类包含嵌套的数据类或 Pydantic 模型,则引发 ValueError(使用 Pydantic 处理嵌套类型)。
  • data_content_type 属性:返回 JSON_DATA_CONTENT_TYPE
  • type_name 属性:返回数据类的名称。
  • deserialize(payload): 将 JSON 负载反序列化为数据类的实例。
  • serialize(message): 将数据类实例序列化为 JSON 负载。

总结

这段代码提供了一个专门用于简单数据类(没有联合或嵌套的数据类/模型)的 JSON 序列化器。它强调使用 Pydantic 来处理更复杂的场景,从而实现了清晰的关注点分离,并使序列化过程更具可预测性。这是一种很好的方法,可以避免直接在数据类中泛型序列化嵌套结构和联合类型的复杂性。

几个例子

@dataclass
class Point:x: inty: intserializer = DataclassJsonMessageSerializer(Point)point = Point(x=10, y=20)
serialized_data = serializer.serialize(point)
print(f"Serialized data: {serialized_data}")  # Output: b'{"x": 10, "y": 20}'deserialized_point = serializer.deserialize(serialized_data)
print(f"Deserialized point: {deserialized_point}")  # Output: Point(x=10, y=20)print(isinstance(deserialized_point, Point)) # Output: True
Serialized data: b'{"x": 10, "y": 20}'
Deserialized point: Point(x=10, y=20)
True
@dataclass
class Line:points: list[Point]line = Line(points=[Point(x=1, y=2), Point(x=3, y=4)])
serializer_line = DataclassJsonMessageSerializer(Line)serialized_line = serializer_line.serialize(line)
print(f"Serialized line: {serialized_line}") # Output: b'{"points": [{"x": 1, "y": 2}, {"x": 3, "y": 4}]}'deserialized_line = serializer_line.deserialize(serialized_line)
print(f"Deserialized line: {deserialized_line}") # Output: Line(points=[Point(x=1, y=2), Point(x=3, y=4)])print(isinstance(deserialized_line, Line)) # Output: True
Serialized line: b'{"points": [{"x": 1, "y": 2}, {"x": 3, "y": 4}]}'
Deserialized line: Line(points=[{'x': 1, 'y': 2}, {'x': 3, 'y': 4}])
True
@dataclass
class Rectangle:top_left: Pointbottom_right: Point# 这会抛出 ValueError,因为 Rectangle 包含嵌套的数据类 Point
try:serializer_rectangle = DataclassJsonMessageSerializer(Rectangle)
except ValueError as e:print(f"Error: {e}")  # Output: Error: Dataclass has nested dataclasses or base models, which are not supported. To use nested types, use a Pydantic model
Error: Dataclass has nested dataclasses or base models, which are not supported. To use nested types, use a Pydantic model
from typing import Union@dataclass
class Shape:shape_type: Union[str, int]try:serializer_shape = DataclassJsonMessageSerializer(Shape)
except ValueError as e:print(f"Error: {e}") # Output: Error: Dataclass has a union type, which is not supported. To use a union, use a Pydantic model
Error: Dataclass has a union type, which is not supported. To use a union, use a Pydantic model

相关文章:

autogen_core中的DataclassJsonMessageSerializer类

源代码 import json from dataclasses import asdict, dataclass, fields from typing import Any, ClassVar, Dict, List, Protocol, Sequence, TypeVar, cast, get_args, get_origin, runtime_checkable, Union from pydantic import BaseModelfrom types import NoneType, …...

floodfill算法系列一>太平洋大西洋水流问题

目录 题目方法解析&#xff1a;代码设计&#xff1a;代码呈现&#xff1a; 题目方法解析&#xff1a; 代码设计&#xff1a; 代码呈现&#xff1a; class Solution {int m,n;int[] dx {0,0,-1,1};int[] dy {-1,1,0,0};public List<List<Integer>> pacificAtlant…...

DeepSeek 助力 Vue 开发:打造丝滑的无限滚动(Infinite Scroll)

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 Deep…...

JavaScript 内置对象-Math对象

在JavaScript中&#xff0c;Math 对象提供了一系列与数学相关的静态方法和属性&#xff0c;帮助开发者执行复杂的计算任务。无论是简单的算术运算还是高级的几何、统计计算&#xff0c;Math 对象都能提供强大的支持。本文将详细介绍 Math 对象的主要功能及其使用方法。 一、简…...

硕成C语言22【一些算法和数组的概念】

1.求水仙花数 #include <stdio.h>int main() {//求水仙花数&#xff1a;1.三位数 2.个位的立方十位的立方百位的立方该数int unit, tens, hundreds;for (int i 100; i < 1000; i)//i表示该水仙花数{unit i / 1 % 10;tens i / 10 % 10;hundreds i / 100 % 10;if (…...

Halcon相机标定

1&#xff0c;前言。 相机的成像过程实质上是坐标系的转换。首先空间中的点由“世界坐标系”转换到“相机坐标系”&#xff0c;然后再将其投影到成像平面&#xff08;图像物理坐标系&#xff09;&#xff0c;最后再将成像的平面上的数据转换为图像像素坐标系。但是由于透镜的制…...

部门管理(体验,最原始方法来做,Django+mysql)

本人初学&#xff0c;写完代码在此记录和复盘 在创建和注册完APP之后&#xff08;我的命名是employees&#xff09;&#xff0c;编写models.py文件创建表 手动插入了几条数据 1.部门查询 urls.py和views.py在编写之前&#xff0c;都要注意导入对应的库 urls.py&#xff1a;…...

clickhouse集群搭建

Clickhouse集群搭建 文章目录 Clickhouse集群搭建安装包下载clickhouse单机安装默认安装默认数据库目录更改默认数据目录 2分片-1副本-3节点集群搭建1. 配置hosts2. 修改每个主机的主机名3. 配置文件上传配置文件分布chnode1配置文件chnode2配置文件chnode3配置文件 4. 重启cli…...

250214-java类集框架

单列集合是list和set&#xff0c;list的实现类有ArrayList和LinkedList&#xff0c;前者是数组实现&#xff0c;后者是链表实现。list和set&#xff0c;前者有序、可重复&#xff0c;后者无序不可重复。 1.单列集合 1.1. list java.util.List接口继承自Collection接口&#…...

二叉树(C语言版)

文章目录 二叉树完全二叉树和满二叉树二叉搜索树基本操作实现代码运行结果 分析红黑树2-3-4树(理论模型)红黑树(实际实现) 二叉树 树是一种层次结构&#xff0c;它在现实生活中是广泛存在的&#xff0c;比如&#xff1a;族谱(family tree)&#xff0c;组织机构&#xff0c;目录…...

ASP.NET Core 面试宝典【刷题系列】

文章目录 引言1、什么是 dot net core 的 startup class?2、什么是中间件?3、application builder 的 use 和 run 方法有什么区别?4、dot net core 管道里面的map拓展有什么作用?5、dot net core 里面的路径是如何处理的?6、如何在 dot net core 中激活 session 功能?7、…...

案例-02.部门管理-查询

一.查询部门-需求 二.查询部门-思路 API接口文档 三.代码实现 1.controller层&#xff1a;负责与前端进行交互&#xff0c;接收前端所发来的请求 注&#xff1a;Slf4j用于记录日志使用&#xff0c;可以省略private static Logger log LoggerFactory.getLogger(DeptControlle…...

src和href区别

src和href区别 (1)请求资源类型不同(2)作用结果不同(3)解析方式不同 (1)请求资源类型不同 href 用来建立文档和元素之间的链接(是引用),常用的有a、linksrc 在请求src资源时候会将指向的资源下载并且应用到文档中(引入),常用的有script、iframe、image。 (2)作用结果不同 hr…...

Java每日精进·45天挑战·Day19

第一部分&#xff1a;移除数字以形成最小数的贪心算法实现 在编程的世界里&#xff0c;我们经常遇到需要对字符串表示的数字进行操作的问题。今天&#xff0c;我们要深入探讨一个具体的挑战&#xff1a;给定一个以字符串形式表示的非负整数 num 和一个整数 k&#xff0c;我们的…...

区块链的交易管理和共识机制

区块链的交易管理和共识机制是其核心功能&#xff0c;以下为你详细介绍它们的实现方式&#xff1a; 交易管理的实现 交易发起 • 用户使用钱包软件创建一笔交易&#xff0c;该交易包含发送方地址、接收方地址、转账金额等关键信息。同时&#xff0c;发送方会使用自己的私钥对…...

最新国内 ChatGPT Plus/Pro 获取教程

最后更新版本&#xff1a;20250202 教程介绍&#xff1a; 本文将详细介绍如何快速获取一张虚拟信用卡&#xff0c;并通过该卡来获取ChatGPT Plus和ChatGPT Pro。 # 教程全程约15分钟开通ChatGPT Plus会员帐号前准备工作 一个尚未升级的ChatGPT帐号&#xff01;一张虚拟信用卡…...

Apollo 9.0 速度动态规划决策算法 – path time heuristic optimizer

文章目录 1. 动态规划2. 采样3. 代价函数3.1 障碍物代价3.2 距离终点代价3.3 速度代价3.4 加速度代价3.5 jerk代价 4. 回溯 这一章将来讲解速度决策算法&#xff0c;也就是SPEED_HEURISTIC_OPTIMIZER task里面的内容。Apollo 9.0使用动态规划算法进行速度决策&#xff0c;从类名…...

Apache Iceberg 与 Apache Hudi:数据湖领域的双雄对决

在数据存储和处理不断发展的领域中&#xff0c;数据湖仓的概念已经崭露头角&#xff0c;成为了一种变革性的力量。数据湖仓结合了数据仓库和数据湖的最佳元素&#xff0c;提供了一个统一的平台&#xff0c;支持数据科学、商业智能、人工智能/机器学习以及临时报告等多种关键功能…...

【LeetCode Hot100 普通数组】最大子数组和、合并区间、旋转数组、除自身以外数组的乘积、缺失的第一个正整数

普通数组 1. 最大子数组和&#xff08;Maximum Subarray&#xff09;解题思路动态规划的优化解法&#xff08;Kadane 算法&#xff09;核心思想 代码解析 2. 合并区间&#xff08;Merge Intervals&#xff09;解题思路代码实现 3. 旋转数组&#xff08;Rotate Array&#xff09…...

共享存储-一步一步部署ceph分布式文件系统

一、Ceph 简介 Ceph 是一个开源的分布式文件系统。因为它还支持块存储、对象存储&#xff0c;所以很自 然的被用做云计算框架 openstack 或 cloudstack 整个存储后端。当然也可以单独作 为存储&#xff0c;例如部署一套集群作为对象存储、SAN 存储、NAS 存储等。 二、ceph 支…...

AI Agent可观测性框架:f/agentlytics深度解析与实战指南

1. 项目概述&#xff1a;一个面向Agent的深度分析框架 最近在折腾AI Agent开发的朋友&#xff0c;可能都遇到过类似的困惑&#xff1a;Agent跑起来了&#xff0c;但为什么是这个结果&#xff1f;它的“思考”过程到底发生了什么&#xff1f;哪个环节耗时最长&#xff0c;哪个工…...

香港品牌研究院发布:2026年GEO行业发展白皮书

2026年GEO行业发展白皮书 ——从粗放运营到AI品牌基建高质量发展 **文件编号&#xff1a;**HKIBR-2026-GEO-001 **版本编号&#xff1a;**V1.0 **发布时间&#xff1a;**2026年4月 **研究发布&#xff5c;学术监制&#xff1a;**香港品牌研究院HongKongBrandInstitute **…...

静态代码分析中SAT技术的应用与优化

1. 静态代码分析的演进与挑战静态代码分析技术自20世纪70年代诞生以来&#xff0c;已经历了三代技术演进。第一代以Lint工具为代表&#xff0c;主要通过模式匹配检测代码中的可疑构造&#xff0c;但由于其高达10:1的噪声比&#xff08;即每发现1个真实缺陷会产生10条无关警告&a…...

GitHub Copilot真能替代程序员吗?我让它和资深工程师结对编程了一周,结果有点意外

GitHub Copilot与资深工程师的七日对决&#xff1a;一场关于AI编程的深度实验 实验缘起&#xff1a;当AI助手遇上十年经验开发者 去年冬天&#xff0c;我决定做一个大胆的尝试——让我的十年Java开发经验与GitHub Copilot来一场为期七天的结对编程马拉松。这不是简单的工具评测…...

Royal TSX中文语言包:让专业远程连接管理更亲切

Royal TSX中文语言包&#xff1a;让专业远程连接管理更亲切 【免费下载链接】Royal_TSX_Chinese_Language_Pack Royal_TSX的简体中文汉化包 项目地址: https://gitcode.com/gh_mirrors/ro/Royal_TSX_Chinese_Language_Pack 你是否曾经面对功能强大的Royal TSX远程连接管…...

Anthropic新研究MSM:先教AI“为什么”,将智能体失准率大幅降低,改写对齐训练逻辑

先教「为什么」&#xff0c;再教「怎么做」MSM的具体方法是在预训练之后、对齐微调之前&#xff0c;加一个中间训练阶段。传统流程是两段&#xff1a;pre-training&#xff0c;然后alignment fine-tuning。MSM流程是三段&#xff1a;pre-training&#xff0c;然后MSM&#xff0…...

低成本超声波传感器智能化改造:基于PIC12F1840的I2C适配板设计

1. 项目概述&#xff1a;用3美元的传感器实现55美元的功能如果你正在捣鼓一个机器人项目&#xff0c;尤其是那种需要全方位感知周围环境的全向移动平台&#xff0c;那么超声波测距传感器多半在你的采购清单上。市面上最常见的选择无非两种&#xff1a;一种是像SRF04这样&#x…...

AlphaGo Zero强化学习范式:从零自演进AI如何重塑工业智能

1. 从AlphaGo Zero看人工智能范式的根本性转变2017年&#xff0c;当DeepMind宣布AlphaGo Zero以100:0的战绩击败其前代冠军版本时&#xff0c;整个科技圈&#xff0c;尤其是我们这些身处半导体、工业控制和嵌入式系统一线的工程师&#xff0c;感受到的震动远超一场棋类比赛的胜…...

云原生安全:零信任架构如何重塑远程办公时代的企业防护

1. 远程办公常态下的云安全挑战与核心思路疫情之后&#xff0c;混合办公从“应急方案”变成了“新常态”。我们面对的早已不是简单的“把办公室电脑搬回家”&#xff0c;而是一个由分布式混合云、多云环境、五花八门的设备&#xff08;公司配发的、员工个人的、移动端的&#x…...

Stable Diffusion WebUI 1.9更新后,采样器和调度器分家了?聊聊‘Automatic’选项背后的懒人哲学

Stable Diffusion WebUI 1.9更新解析&#xff1a;当采样器与调度器分道扬镳 打开最新版Stable Diffusion WebUI 1.9&#xff0c;不少用户会立刻注意到界面上的微妙变化——原本熟悉的采样器选择区域旁&#xff0c;突然多出了一个名为"Schedule type"的下拉菜单。这个…...