compas-pb 0.1.0__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.
compas_pb/__init__.py ADDED
@@ -0,0 +1,43 @@
1
+ from __future__ import print_function
2
+
3
+ import os
4
+
5
+ # please don't remove me! I trigger the registration of all the core serializers
6
+ import compas_pb.conversions # noqa: F401 #
7
+
8
+ from .api import pb_load
9
+ from .api import pb_dump
10
+ from .api import pb_dump_bts
11
+ from .api import pb_load_bts
12
+ from .api import pb_dump_json
13
+ from .api import pb_load_json
14
+
15
+
16
+ __author__ = ["Wei-Ting Chen", "Chen Kasirer"]
17
+ __copyright__ = "Gramazio Kohler Research"
18
+ __license__ = "MIT License"
19
+ __email__ = "kasirer@arch.ethz.ch"
20
+ __version__ = "0.1.0"
21
+
22
+
23
+ HERE = os.path.dirname(__file__)
24
+
25
+ HOME = os.path.abspath(os.path.join(HERE, "../../"))
26
+ DATA = os.path.abspath(os.path.join(HOME, "data"))
27
+ DOCS = os.path.abspath(os.path.join(HOME, "docs"))
28
+ TEMP = os.path.abspath(os.path.join(HOME, "temp"))
29
+ IDL = os.path.abspath(os.path.join(HOME, "IDL"))
30
+
31
+ __all__ = [
32
+ "HOME",
33
+ "DATA",
34
+ "DOCS",
35
+ "TEMP",
36
+ "IDL",
37
+ "pb_load",
38
+ "pb_dump",
39
+ "pb_dump_bts",
40
+ "pb_load_bts",
41
+ "pb_dump_json",
42
+ "pb_load_json",
43
+ ]
compas_pb/api.py ADDED
@@ -0,0 +1,155 @@
1
+ from typing import Dict
2
+ from typing import List
3
+
4
+ from compas.data import Data
5
+
6
+ from compas_pb.core import deserialize_message
7
+ from compas_pb.core import deserialize_message_from_json
8
+ from compas_pb.core import serialize_message_bts
9
+ from compas_pb.core import serialize_message_to_json
10
+
11
+
12
+ def pb_dump(data: Data | Dict[str, Data] | List[Data], filepath: str) -> None:
13
+ """Write a collection of COMPAS object to a binary file.
14
+
15
+ Parameters
16
+ ----------
17
+ data : Data | Dict | List
18
+ Any protobuffer serializable object.
19
+ This includes any (combination of) COMPAS object(s).
20
+ filepath : path string or file-like object
21
+ A writeable file-like object or the path to a file.
22
+
23
+ Returns:
24
+ -------
25
+ None
26
+
27
+ Example:
28
+ --------
29
+ pass
30
+
31
+ """
32
+ message_bts = serialize_message_bts(data)
33
+
34
+ with open(filepath, "wb") as f:
35
+ f.write(message_bts)
36
+
37
+
38
+ def pb_load(filepath: str) -> Data | Dict | List:
39
+ """Read a collection of COMPAS object from a binary file.
40
+
41
+ Parameters
42
+ ----------
43
+ filepath : path string or file-like object
44
+
45
+ A readable file-like object or the path to a file.
46
+
47
+ Returns:
48
+ -------
49
+ Data | Dict | List
50
+
51
+ The (COMPAS) object(s) contained in the file.
52
+
53
+ """
54
+
55
+ with open(filepath, "rb") as f:
56
+ message_bts = f.read()
57
+ message = deserialize_message(message_bts)
58
+ return message
59
+
60
+
61
+ def pb_dump_json(data: Data | Dict | List) -> str:
62
+ """Write a collection of COMPAS object to a JSON string.
63
+
64
+
65
+ Parameters
66
+ ----------
67
+ data : Data | Dict | List
68
+
69
+ Any protobuffer serializable object. This includes any (combination of) COMPAS object(s).
70
+
71
+
72
+ Returns:
73
+ -------
74
+ string
75
+
76
+ The JSON string representation of the data.
77
+
78
+ Example:
79
+ --------
80
+ pass
81
+
82
+ """
83
+ json_str = serialize_message_to_json(data)
84
+ return json_str
85
+
86
+
87
+ def pb_load_json(data: str) -> Data | Dict | List:
88
+ """Read a collection of COMPAS object from a JSON string.
89
+
90
+
91
+ Parameters
92
+ ----------
93
+ data : str
94
+
95
+ A JSON string representation of the data.
96
+
97
+
98
+ Returns:
99
+ -------
100
+ Data | Dict | List
101
+
102
+
103
+ The (COMPAS) object(s) contained in the JSON string.
104
+
105
+ Example:
106
+ --------
107
+ pass
108
+
109
+ """
110
+ message = deserialize_message_from_json(data)
111
+ return message
112
+
113
+
114
+ def pb_dump_bts(data: Data | Dict | list) -> bytes:
115
+ """Write a collection of COMPAS object to a btye string.
116
+
117
+
118
+ Parameters
119
+ ----------
120
+ data : Data | Dict | List
121
+
122
+ Any protobuffer serializable object.
123
+ This includes any (combination of) COMPAS object(s).
124
+
125
+ Returns:
126
+ -------
127
+ None
128
+
129
+ Example:
130
+ --------
131
+ pass
132
+
133
+ """
134
+ message_bts = serialize_message_bts(data)
135
+
136
+ return message_bts
137
+
138
+
139
+ def pb_load_bts(data: bytes) -> Data | Dict | List:
140
+ """Read a collection of COMPAS object from a binary file.
141
+
142
+ Parameters
143
+ ----------
144
+ filepath : path string or file-like object
145
+ A readable file-like object or the path to a file.
146
+
147
+
148
+ Returns:
149
+ -------
150
+ Data | Dict | List
151
+ The (COMPAS) object(s) contained in the file.
152
+
153
+ """
154
+ message_bts = deserialize_message(data)
155
+ return message_bts
@@ -0,0 +1,151 @@
1
+ from compas.datastructures import Mesh
2
+ from compas.geometry import Circle
3
+ from compas.geometry import Frame
4
+ from compas.geometry import Line
5
+ from compas.geometry import Point
6
+ from compas.geometry import Vector
7
+
8
+ from compas_pb.generated import circle_pb2
9
+ from compas_pb.generated import frame_pb2
10
+ from compas_pb.generated import line_pb2
11
+ from compas_pb.generated import mesh_pb2
12
+ from compas_pb.generated import point_pb2
13
+ from compas_pb.generated import vector_pb2
14
+
15
+ from .registry import pb_deserializer
16
+ from .registry import pb_serializer
17
+
18
+
19
+ @pb_serializer(Point)
20
+ def point_to_pb(obj: Point) -> point_pb2.PointData:
21
+ proto_data = point_pb2.PointData()
22
+ proto_data.guid = str(obj.guid)
23
+ proto_data.name = obj.name
24
+ proto_data.x = obj.x
25
+ proto_data.y = obj.y
26
+ proto_data.z = obj.z
27
+ return proto_data
28
+
29
+
30
+ @pb_deserializer(point_pb2.PointData)
31
+ def point_from_pb(proto_data: point_pb2.PointData) -> Point:
32
+ return Point(x=proto_data.x, y=proto_data.y, z=proto_data.z, name=proto_data.name)
33
+
34
+
35
+ @pb_serializer(Line)
36
+ def line_to_pb(line_obj: Line) -> line_pb2.LineData:
37
+ proto_data = line_pb2.LineData()
38
+ proto_data.guid = str(line_obj.guid)
39
+ proto_data.name = line_obj.name
40
+
41
+ start = point_to_pb(line_obj.start)
42
+ end = point_to_pb(line_obj.end)
43
+
44
+ proto_data.start.CopyFrom(start)
45
+ proto_data.end.CopyFrom(end)
46
+
47
+ return proto_data
48
+
49
+
50
+ @pb_deserializer(line_pb2.LineData)
51
+ def line_from_pb(proto_data: line_pb2.LineData) -> Line:
52
+ start = point_from_pb(proto_data.start)
53
+ end = point_from_pb(proto_data.end)
54
+
55
+ return Line(start=start, end=end, name=proto_data.name)
56
+
57
+
58
+ @pb_serializer(Vector)
59
+ def vector_to_pb(obj: Vector) -> vector_pb2.VectorData:
60
+ proto_data = vector_pb2.VectorData()
61
+ proto_data.name = obj.name
62
+ proto_data.x = obj.x
63
+ proto_data.y = obj.y
64
+ proto_data.z = obj.z
65
+ return proto_data
66
+
67
+
68
+ @pb_deserializer(vector_pb2.VectorData)
69
+ def vector_from_pb(proto_data: vector_pb2.VectorData) -> Vector:
70
+ return Vector(x=proto_data.x, y=proto_data.y, z=proto_data.z, name=proto_data.name)
71
+
72
+
73
+ @pb_serializer(Frame)
74
+ def frame_to_pb(frame_obj: Frame) -> frame_pb2.FrameData:
75
+ proto_data = frame_pb2.FrameData()
76
+ proto_data.guid = str(frame_obj.guid)
77
+ proto_data.name = frame_obj.name
78
+
79
+ origin = point_to_pb(frame_obj.point)
80
+ xaxis = vector_to_pb(frame_obj.xaxis)
81
+ yaxis = vector_to_pb(frame_obj.yaxis)
82
+
83
+ proto_data.point.CopyFrom(origin)
84
+ proto_data.xaxis.CopyFrom(xaxis)
85
+ proto_data.yaxis.CopyFrom(yaxis)
86
+
87
+ return proto_data
88
+
89
+
90
+ @pb_deserializer(frame_pb2.FrameData)
91
+ def frame_from_pb(proto_data: frame_pb2.FrameData) -> Frame:
92
+ origin = point_from_pb(proto_data.point)
93
+ xaxis = vector_from_pb(proto_data.xaxis)
94
+ yaxis = vector_from_pb(proto_data.yaxis)
95
+ return Frame(point=origin, xaxis=xaxis, yaxis=yaxis, name=proto_data.name)
96
+
97
+
98
+ @pb_serializer(Mesh)
99
+ def mesh_to_pb(mesh: Mesh) -> mesh_pb2.MeshData:
100
+ proto_data = mesh_pb2.MeshData()
101
+ proto_data.guid = str(mesh.guid)
102
+ proto_data.name = mesh.name or "Mesh"
103
+
104
+ index_map = {} # vertex_key → index
105
+ for index, (key, attr) in enumerate(mesh.vertices(data=True)):
106
+ point = Point(*mesh.vertex_coordinates(key))
107
+ proto_data.vertices.append(point_to_pb(point))
108
+ index_map[key] = index
109
+
110
+ for fkey in mesh.faces():
111
+ indices = [index_map[vkey] for vkey in mesh.face_vertices(fkey)]
112
+ face_msg = mesh_pb2.FaceList()
113
+ face_msg.indices.extend(indices)
114
+ proto_data.faces.append(face_msg)
115
+
116
+ return proto_data
117
+
118
+
119
+ @pb_deserializer(mesh_pb2.MeshData)
120
+ def mesh_from_pb(proto_data: mesh_pb2.MeshData) -> Mesh:
121
+ mesh = Mesh(guid=proto_data.guid, name=proto_data.name)
122
+ vertex_map = []
123
+
124
+ for pb_point in proto_data.vertices:
125
+ point = point_from_pb(pb_point)
126
+ key = mesh.add_vertex(x=point.x, y=point.y, z=point.z)
127
+ vertex_map.append(key)
128
+
129
+ for face in proto_data.faces:
130
+ indices = [vertex_map[i] for i in face.indices]
131
+ mesh.add_face(indices)
132
+
133
+ return mesh
134
+
135
+
136
+ @pb_serializer(Circle)
137
+ def circle_to_pb(circle: Circle) -> circle_pb2.CircleData:
138
+ result = circle_pb2.CircleData()
139
+ result.guid = str(circle.guid)
140
+ result.name = circle.name or "Circle"
141
+ result.radius = circle.radius
142
+ result.frame.CopyFrom(frame_to_pb(circle.frame))
143
+ return result
144
+
145
+
146
+ @pb_deserializer(circle_pb2.CircleData)
147
+ def circle_from_pb(proto_data: circle_pb2.CircleData) -> Circle:
148
+ frame = frame_from_pb(proto_data.frame)
149
+ result = Circle(radius=proto_data.radius, frame=frame, name=proto_data.name)
150
+ result._guid = proto_data.guid
151
+ return result
compas_pb/core.py ADDED
@@ -0,0 +1,364 @@
1
+ import compas
2
+ from compas.plugins import pluggable
3
+ from google.protobuf.json_format import MessageToJson
4
+ from google.protobuf.json_format import Parse
5
+
6
+ from compas_pb.generated import message_pb2
7
+
8
+ from .registry import SerialzerRegistry
9
+
10
+
11
+ @pluggable(category="factories", selector="collect_all")
12
+ def register_serializers() -> None:
13
+ """Collects all the plugins which register custom serializers with _ProtoBufferAny."""
14
+ pass
15
+
16
+
17
+ _DISCOVERY_DONE = False
18
+
19
+
20
+ def _discover_serializers() -> None:
21
+ global _DISCOVERY_DONE
22
+ if _DISCOVERY_DONE:
23
+ return
24
+
25
+ register_serializers()
26
+ _DISCOVERY_DONE = True
27
+
28
+
29
+ PY_TYPES_SERIALIZER = {
30
+ int: message_pb2.DataType.INT,
31
+ float: message_pb2.DataType.FLOAT,
32
+ bool: message_pb2.DataType.BOOL,
33
+ str: message_pb2.DataType.STR,
34
+ bytes: message_pb2.DataType.BYTES,
35
+ }
36
+
37
+ PY_TYPES_DESERIALIZER = {key.__name__.lower(): value for key, value in PY_TYPES_SERIALIZER.items()}
38
+
39
+
40
+ def primitive_to_pb(obj: int | float | bool | str | bytes) -> message_pb2.PrimitiveData:
41
+ """
42
+ Convert a python native type to a protobuf message.
43
+
44
+ Parameters
45
+ ----------
46
+ obj : :class: `int`, `float`, `bool`, `str`, `bytes`
47
+ The python native type to convert.
48
+
49
+ Returns
50
+ -------
51
+ :class: `compas_pb.generated.message_pb2.AnyData`
52
+ The protobuf message type of AnyData.
53
+ """
54
+ if obj is None:
55
+ obj = "None" # HACK: find proper way to handle None
56
+
57
+ data_offset = message_pb2.PrimitiveData()
58
+
59
+ type_ = type(obj)
60
+ if type_ is int:
61
+ data_offset.int = obj
62
+ elif type_ is float:
63
+ data_offset.float = obj
64
+ elif type_ is bool:
65
+ data_offset.bool = obj
66
+ elif type_ is str:
67
+ data_offset.str = obj
68
+ elif type_ is bytes:
69
+ data_offset.bytes = obj
70
+ else:
71
+ raise TypeError(f"Unsupported type: {type_}")
72
+
73
+ return data_offset
74
+
75
+
76
+ def primitive_from_pb(primitive: message_pb2.PrimitiveData) -> int | float | bool | str | bytes:
77
+ """Convert a protobuf message to a python native type.
78
+
79
+ Parameters
80
+ ----------
81
+ proto_data : :class: `compas_pb.generated.message_pb2.PrimitiveData`
82
+ The protobuf message type of PrimitiveData.
83
+
84
+ Returns
85
+ -------
86
+ data_offset : int | float | bool | str | bytes
87
+ The converted python native type.
88
+ """
89
+ type_ = primitive.WhichOneof("data")
90
+ if type_ == "int":
91
+ data_offset = primitive.int
92
+ elif type_ == "float":
93
+ data_offset = primitive.float
94
+ elif type_ == "bool":
95
+ data_offset = primitive.bool
96
+ elif type_ == "str":
97
+ data_offset = primitive.str
98
+ elif type_ == "bytes":
99
+ data_offset = primitive.bytes
100
+ else:
101
+ raise ValueError(f"Unsupported primitive type: {type_}")
102
+
103
+ return data_offset
104
+
105
+
106
+ def any_to_pb(obj: compas.data.Data | int | float | bool | str | bytes, fallback_serializer=None) -> message_pb2.AnyData:
107
+ """Convert any object to a protobuf any message.
108
+
109
+ Parameters
110
+ ----------
111
+ obj : compas.data.Data | list | dict | int | float | bool | str
112
+ The object to convert. Can be a COMPAS Data object, list, dict, or primitive type.
113
+
114
+ Returns
115
+ -------
116
+ :class: `compas_pb.generated.message_pb2.AnyData`
117
+ The protobuf message type of AnyData.
118
+ """
119
+ _discover_serializers()
120
+ proto_data = message_pb2.AnyData()
121
+
122
+ if obj is None:
123
+ obj = "None" # HACK: find proper way to handle None
124
+
125
+ try:
126
+ serializer = SerialzerRegistry.get_serializer(obj)
127
+ if serializer:
128
+ pb_obj = serializer(obj)
129
+ proto_data.data.Pack(pb_obj)
130
+ elif hasattr(obj, "__jsondump__"):
131
+ obj_dict = {obj.__class__.__name__: obj.__jsondump__()}
132
+ data_offset = fallback_serializer(obj_dict)
133
+ proto_data.data.Pack(data_offset)
134
+ else:
135
+ primitive = primitive_to_pb(obj)
136
+ proto_data.data.Pack(primitive)
137
+ return proto_data
138
+ except TypeError as e:
139
+ raise TypeError(f"Unsupported type: {type(obj)}: {e}")
140
+
141
+
142
+ def any_from_pb(proto_data: message_pb2.AnyData) -> compas.data.Data | int | float | bool | str | bytes:
143
+ """Convert a protobuf message to a supported object.
144
+
145
+ Parameters
146
+ ----------
147
+ proto_data : :class: `compas_pb.generated.message_pb2.AnyData`
148
+ The protobuf message type of AnyData.
149
+
150
+ Returns
151
+ -------
152
+ compas.data.Data | list | dict | int | float | bool | str
153
+ The converted object. Can be a COMPAS Data object, list, dict, or primitive type.
154
+ """
155
+ _discover_serializers()
156
+
157
+ # type.googleapis.com/<fully.qualified.message.name>
158
+ proto_type = proto_data.data.type_url.split("/")[-1]
159
+
160
+ if proto_type == message_pb2.PrimitiveData.DESCRIPTOR.full_name:
161
+ primitive_data = message_pb2.PrimitiveData()
162
+ is_unpacked = proto_data.data.Unpack(primitive_data)
163
+ if not is_unpacked:
164
+ raise TypeError(f"Unsupported proto type: {proto_type}")
165
+
166
+ return primitive_from_pb(primitive_data)
167
+
168
+ deserializer = SerialzerRegistry.get_deserializer(proto_type)
169
+ if not deserializer:
170
+ raise TypeError(f"Unsupported proto type: {proto_type}")
171
+
172
+ unpacked_instance = deserializer.__deserializer_type__()
173
+ _ = proto_data.data.Unpack(unpacked_instance)
174
+ return deserializer(unpacked_instance)
175
+
176
+
177
+ def serialize_message(data) -> message_pb2.MessageData:
178
+ """Serialize a top-level protobuf message.
179
+
180
+ Parameters:
181
+ ----------
182
+ data : object
183
+ The data to be serialized. This can be a COMPAS object, a list of objects, or a dictionary.
184
+
185
+ Returns:
186
+ -------
187
+ message : message_pb2.MessageData
188
+
189
+ """
190
+ if not data:
191
+ raise ValueError("No message data to convert.")
192
+
193
+ message_data = _serializer_any(data)
194
+ message = message_pb2.MessageData(data=message_data)
195
+ return message
196
+
197
+
198
+ def serialize_message_bts(data) -> bytes:
199
+ """Serialize a top-level protobuf message.
200
+
201
+ Parameters:
202
+ ----------
203
+ data : object
204
+ The data to be serialized. This can be a COMPAS object, a list of objects, or a dictionary.
205
+
206
+ Returns:
207
+ -------
208
+ message : bytes
209
+ The serialized protobuf message as bytes.
210
+
211
+ """
212
+ message = serialize_message(data)
213
+ message_bts = message.SerializeToString()
214
+ return message_bts
215
+
216
+
217
+ def serialize_message_to_json(data) -> dict:
218
+ """Serialize a top-level protobuf message.
219
+
220
+ Parameters:
221
+ ----------
222
+ data : object
223
+ The data to be serialized. This can be a COMPAS object, a list of objects, or a dictionary.
224
+
225
+ Returns:
226
+ -------
227
+ message : dict
228
+ The serialized protobuf message as a dictionary.
229
+
230
+ """
231
+ message = serialize_message(data)
232
+ message_json = MessageToJson(message)
233
+ return message_json
234
+
235
+
236
+ def _serializer_any(obj) -> message_pb2.AnyData:
237
+ """Serialize a COMPAS object to protobuf message."""
238
+ any_data = message_pb2.AnyData()
239
+
240
+ if isinstance(obj, (list, tuple)):
241
+ data_offset = _serialize_list(obj)
242
+ any_data.data.Pack(data_offset)
243
+ elif isinstance(obj, dict):
244
+ data_offset = _serialize_dict(obj)
245
+ any_data.data.Pack(data_offset)
246
+ else:
247
+ # check if it is COMPAS object or Python native type or fallback to dictionary.
248
+ any_data = any_to_pb(obj, fallback_serializer=_serialize_dict)
249
+ return any_data
250
+
251
+
252
+ def _serialize_list(data_list) -> message_pb2.ListData:
253
+ """Serialize a Python list containing mixed data type."""
254
+ list_data = message_pb2.ListData()
255
+ for item in data_list:
256
+ data_offset = _serializer_any(item)
257
+ list_data.data.append(data_offset)
258
+ return list_data
259
+
260
+
261
+ def _serialize_dict(data_dict) -> message_pb2.DictData:
262
+ """Serialize a Python dictionary containing mixed data types."""
263
+ dict_data = message_pb2.DictData()
264
+ for key, value in data_dict.items():
265
+ data_offset = _serializer_any(value)
266
+ dict_data.data[key].CopyFrom(data_offset)
267
+ return dict_data
268
+
269
+
270
+ def deserialize_message(binary_data) -> list | dict:
271
+ """Deserialize a top-level protobuf message.
272
+
273
+ Parameters:
274
+ ----------
275
+ binary_data : bytes
276
+ The binary data to be deserialized.
277
+
278
+ Returns:
279
+ -------
280
+ message : list | dict
281
+ The deserialized protobuf message.
282
+
283
+ """
284
+ message_data = deserialize_message_bts(binary_data)
285
+ return _deserialize_any(message_data)
286
+
287
+
288
+ def deserialize_message_bts(binary_data) -> message_pb2.MessageData:
289
+ """Deserialize a binary data into bytes string.
290
+
291
+ Parameters:
292
+ ----------
293
+ binary_data : bytes
294
+ The binary data to be deserialized.
295
+
296
+ Returns:
297
+ -------
298
+ message_data : message_pb2.MessageData
299
+ The protobuf message data.
300
+
301
+ """
302
+ if not binary_data:
303
+ raise ValueError("Binary data is empty.")
304
+
305
+ any_data = message_pb2.MessageData()
306
+ any_data.ParseFromString(binary_data)
307
+ return any_data.data
308
+
309
+
310
+ def deserialize_message_from_json(json_data: str) -> dict:
311
+ """Deserialize a top-level protobuf message into dictionary.
312
+
313
+ Parameters:
314
+ ----------
315
+ json_data : str
316
+ A JSON string representation of the data.
317
+
318
+ Returns:
319
+ -------
320
+ message : dict
321
+ The deserialized protobuf message as a dictionary.
322
+
323
+ """
324
+ if not json_data:
325
+ raise ValueError("No message data to convert.")
326
+
327
+ message = message_pb2.MessageData()
328
+ json_message = Parse(json_data, message)
329
+
330
+ any_data = message_pb2.MessageData()
331
+ any_data.CopyFrom(json_message)
332
+
333
+ return _deserialize_any(any_data.data)
334
+
335
+
336
+ def _deserialize_any(data: message_pb2.AnyData | message_pb2.ListData | message_pb2.DictData) -> list | dict:
337
+ """Deserialize a protobuf message to COMPAS object."""
338
+ if data.data.Is(message_pb2.ListData.DESCRIPTOR):
339
+ data_offset = _deserialize_list(data)
340
+ elif data.data.Is(message_pb2.DictData.DESCRIPTOR):
341
+ data_offset = _deserialize_dict(data)
342
+ else:
343
+ data_offset = any_from_pb(data)
344
+ return data_offset
345
+
346
+
347
+ def _deserialize_list(data_list: message_pb2.ListData) -> list:
348
+ """Deserialize a protobuf ListData message to Python list."""
349
+ data_offset = []
350
+ list_data = message_pb2.ListData()
351
+ data_list.data.Unpack(list_data)
352
+ for item in list_data.data:
353
+ data_offset.append(_deserialize_any(item))
354
+ return data_offset
355
+
356
+
357
+ def _deserialize_dict(data_dict: message_pb2.AnyData) -> dict:
358
+ """Deserialize a protobuf DictData message to Python dictionary."""
359
+ data_offset = {}
360
+ dict_data = message_pb2.DictData()
361
+ data_dict.data.Unpack(dict_data)
362
+ for key, value in dict_data.data.items():
363
+ data_offset[key] = _deserialize_any(value)
364
+ return data_offset
@@ -0,0 +1,37 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # NO CHECKED-IN PROTOBUF GENCODE
4
+ # source: compas_pb/generated/circle.proto
5
+ # Protobuf Python Version: 6.31.1
6
+ """Generated protocol buffer code."""
7
+ from google.protobuf import descriptor as _descriptor
8
+ from google.protobuf import descriptor_pool as _descriptor_pool
9
+ from google.protobuf import runtime_version as _runtime_version
10
+ from google.protobuf import symbol_database as _symbol_database
11
+ from google.protobuf.internal import builder as _builder
12
+ _runtime_version.ValidateProtobufRuntimeVersion(
13
+ _runtime_version.Domain.PUBLIC,
14
+ 6,
15
+ 31,
16
+ 1,
17
+ '',
18
+ 'compas_pb/generated/circle.proto'
19
+ )
20
+ # @@protoc_insertion_point(imports)
21
+
22
+ _sym_db = _symbol_database.Default()
23
+
24
+
25
+ from compas_pb.generated import frame_pb2 as compas__pb_dot_generated_dot_frame__pb2
26
+
27
+
28
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n compas_pb/generated/circle.proto\x12\x0e\x63ompas_pb.data\x1a\x1f\x63ompas_pb/generated/frame.proto\"b\n\nCircleData\x12\x0c\n\x04guid\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0e\n\x06radius\x18\x03 \x01(\x02\x12(\n\x05\x66rame\x18\x04 \x01(\x0b\x32\x19.compas_pb.data.FrameDatab\x06proto3')
29
+
30
+ _globals = globals()
31
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
32
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'compas_pb.generated.circle_pb2', _globals)
33
+ if not _descriptor._USE_C_DESCRIPTORS:
34
+ DESCRIPTOR._loaded_options = None
35
+ _globals['_CIRCLEDATA']._serialized_start=85
36
+ _globals['_CIRCLEDATA']._serialized_end=183
37
+ # @@protoc_insertion_point(module_scope)
@@ -0,0 +1,37 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # NO CHECKED-IN PROTOBUF GENCODE
4
+ # source: compas_pb/generated/element.proto
5
+ # Protobuf Python Version: 6.31.1
6
+ """Generated protocol buffer code."""
7
+ from google.protobuf import descriptor as _descriptor
8
+ from google.protobuf import descriptor_pool as _descriptor_pool
9
+ from google.protobuf import runtime_version as _runtime_version
10
+ from google.protobuf import symbol_database as _symbol_database
11
+ from google.protobuf.internal import builder as _builder
12
+ _runtime_version.ValidateProtobufRuntimeVersion(
13
+ _runtime_version.Domain.PUBLIC,
14
+ 6,
15
+ 31,
16
+ 1,
17
+ '',
18
+ 'compas_pb/generated/element.proto'
19
+ )
20
+ # @@protoc_insertion_point(imports)
21
+
22
+ _sym_db = _symbol_database.Default()
23
+
24
+
25
+ from compas_pb.generated import frame_pb2 as compas__pb_dot_generated_dot_frame__pb2
26
+
27
+
28
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n!compas_pb/generated/element.proto\x12\x0e\x63ompas_pb.data\x1a\x1f\x63ompas_pb/generated/frame.proto\"\x80\x01\n\x0b\x45lementData\x12\x0c\n\x04guid\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12(\n\x05\x66rame\x18\x03 \x01(\x0b\x32\x19.compas_pb.data.FrameData\x12\r\n\x05xsize\x18\x04 \x01(\x02\x12\r\n\x05ysize\x18\x05 \x01(\x02\x12\r\n\x05zsize\x18\x06 \x01(\x02\x62\x06proto3')
29
+
30
+ _globals = globals()
31
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
32
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'compas_pb.generated.element_pb2', _globals)
33
+ if not _descriptor._USE_C_DESCRIPTORS:
34
+ DESCRIPTOR._loaded_options = None
35
+ _globals['_ELEMENTDATA']._serialized_start=87
36
+ _globals['_ELEMENTDATA']._serialized_end=215
37
+ # @@protoc_insertion_point(module_scope)
@@ -0,0 +1,38 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # NO CHECKED-IN PROTOBUF GENCODE
4
+ # source: compas_pb/generated/frame.proto
5
+ # Protobuf Python Version: 6.31.1
6
+ """Generated protocol buffer code."""
7
+ from google.protobuf import descriptor as _descriptor
8
+ from google.protobuf import descriptor_pool as _descriptor_pool
9
+ from google.protobuf import runtime_version as _runtime_version
10
+ from google.protobuf import symbol_database as _symbol_database
11
+ from google.protobuf.internal import builder as _builder
12
+ _runtime_version.ValidateProtobufRuntimeVersion(
13
+ _runtime_version.Domain.PUBLIC,
14
+ 6,
15
+ 31,
16
+ 1,
17
+ '',
18
+ 'compas_pb/generated/frame.proto'
19
+ )
20
+ # @@protoc_insertion_point(imports)
21
+
22
+ _sym_db = _symbol_database.Default()
23
+
24
+
25
+ from compas_pb.generated import point_pb2 as compas__pb_dot_generated_dot_point__pb2
26
+ from compas_pb.generated import vector_pb2 as compas__pb_dot_generated_dot_vector__pb2
27
+
28
+
29
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1f\x63ompas_pb/generated/frame.proto\x12\x0e\x63ompas_pb.data\x1a\x1f\x63ompas_pb/generated/point.proto\x1a compas_pb/generated/vector.proto\"\xa7\x01\n\tFrameData\x12\x0c\n\x04guid\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12(\n\x05point\x18\x03 \x01(\x0b\x32\x19.compas_pb.data.PointData\x12)\n\x05xaxis\x18\x04 \x01(\x0b\x32\x1a.compas_pb.data.VectorData\x12)\n\x05yaxis\x18\x05 \x01(\x0b\x32\x1a.compas_pb.data.VectorDatab\x06proto3')
30
+
31
+ _globals = globals()
32
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
33
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'compas_pb.generated.frame_pb2', _globals)
34
+ if not _descriptor._USE_C_DESCRIPTORS:
35
+ DESCRIPTOR._loaded_options = None
36
+ _globals['_FRAMEDATA']._serialized_start=119
37
+ _globals['_FRAMEDATA']._serialized_end=286
38
+ # @@protoc_insertion_point(module_scope)
@@ -0,0 +1,37 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # NO CHECKED-IN PROTOBUF GENCODE
4
+ # source: compas_pb/generated/line.proto
5
+ # Protobuf Python Version: 6.31.1
6
+ """Generated protocol buffer code."""
7
+ from google.protobuf import descriptor as _descriptor
8
+ from google.protobuf import descriptor_pool as _descriptor_pool
9
+ from google.protobuf import runtime_version as _runtime_version
10
+ from google.protobuf import symbol_database as _symbol_database
11
+ from google.protobuf.internal import builder as _builder
12
+ _runtime_version.ValidateProtobufRuntimeVersion(
13
+ _runtime_version.Domain.PUBLIC,
14
+ 6,
15
+ 31,
16
+ 1,
17
+ '',
18
+ 'compas_pb/generated/line.proto'
19
+ )
20
+ # @@protoc_insertion_point(imports)
21
+
22
+ _sym_db = _symbol_database.Default()
23
+
24
+
25
+ from compas_pb.generated import point_pb2 as compas__pb_dot_generated_dot_point__pb2
26
+
27
+
28
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1e\x63ompas_pb/generated/line.proto\x12\x0e\x63ompas_pb.data\x1a\x1f\x63ompas_pb/generated/point.proto\"x\n\x08LineData\x12\x0c\n\x04guid\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12(\n\x05start\x18\x03 \x01(\x0b\x32\x19.compas_pb.data.PointData\x12&\n\x03\x65nd\x18\x04 \x01(\x0b\x32\x19.compas_pb.data.PointDatab\x06proto3')
29
+
30
+ _globals = globals()
31
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
32
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'compas_pb.generated.line_pb2', _globals)
33
+ if not _descriptor._USE_C_DESCRIPTORS:
34
+ DESCRIPTOR._loaded_options = None
35
+ _globals['_LINEDATA']._serialized_start=83
36
+ _globals['_LINEDATA']._serialized_end=203
37
+ # @@protoc_insertion_point(module_scope)
@@ -0,0 +1,39 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # NO CHECKED-IN PROTOBUF GENCODE
4
+ # source: compas_pb/generated/mesh.proto
5
+ # Protobuf Python Version: 6.31.1
6
+ """Generated protocol buffer code."""
7
+ from google.protobuf import descriptor as _descriptor
8
+ from google.protobuf import descriptor_pool as _descriptor_pool
9
+ from google.protobuf import runtime_version as _runtime_version
10
+ from google.protobuf import symbol_database as _symbol_database
11
+ from google.protobuf.internal import builder as _builder
12
+ _runtime_version.ValidateProtobufRuntimeVersion(
13
+ _runtime_version.Domain.PUBLIC,
14
+ 6,
15
+ 31,
16
+ 1,
17
+ '',
18
+ 'compas_pb/generated/mesh.proto'
19
+ )
20
+ # @@protoc_insertion_point(imports)
21
+
22
+ _sym_db = _symbol_database.Default()
23
+
24
+
25
+ from compas_pb.generated import point_pb2 as compas__pb_dot_generated_dot_point__pb2
26
+
27
+
28
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1e\x63ompas_pb/generated/mesh.proto\x12\x0e\x63ompas_pb.data\x1a\x1f\x63ompas_pb/generated/point.proto\"\x1b\n\x08\x46\x61\x63\x65List\x12\x0f\n\x07indices\x18\x01 \x03(\r\"\x98\x01\n\x08MeshData\x12\x11\n\x04guid\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x11\n\x04name\x18\x02 \x01(\tH\x01\x88\x01\x01\x12+\n\x08vertices\x18\x03 \x03(\x0b\x32\x19.compas_pb.data.PointData\x12\'\n\x05\x66\x61\x63\x65s\x18\x04 \x03(\x0b\x32\x18.compas_pb.data.FaceListB\x07\n\x05_guidB\x07\n\x05_nameb\x06proto3')
29
+
30
+ _globals = globals()
31
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
32
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'compas_pb.generated.mesh_pb2', _globals)
33
+ if not _descriptor._USE_C_DESCRIPTORS:
34
+ DESCRIPTOR._loaded_options = None
35
+ _globals['_FACELIST']._serialized_start=83
36
+ _globals['_FACELIST']._serialized_end=110
37
+ _globals['_MESHDATA']._serialized_start=113
38
+ _globals['_MESHDATA']._serialized_end=265
39
+ # @@protoc_insertion_point(module_scope)
@@ -0,0 +1,51 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # NO CHECKED-IN PROTOBUF GENCODE
4
+ # source: compas_pb/generated/message.proto
5
+ # Protobuf Python Version: 6.31.1
6
+ """Generated protocol buffer code."""
7
+ from google.protobuf import descriptor as _descriptor
8
+ from google.protobuf import descriptor_pool as _descriptor_pool
9
+ from google.protobuf import runtime_version as _runtime_version
10
+ from google.protobuf import symbol_database as _symbol_database
11
+ from google.protobuf.internal import builder as _builder
12
+ _runtime_version.ValidateProtobufRuntimeVersion(
13
+ _runtime_version.Domain.PUBLIC,
14
+ 6,
15
+ 31,
16
+ 1,
17
+ '',
18
+ 'compas_pb/generated/message.proto'
19
+ )
20
+ # @@protoc_insertion_point(imports)
21
+
22
+ _sym_db = _symbol_database.Default()
23
+
24
+
25
+ from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2
26
+
27
+
28
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n!compas_pb/generated/message.proto\x12\x0e\x63ompas_pb.data\x1a\x19google/protobuf/any.proto\"\x8f\x01\n\rPrimitiveData\x12&\n\x04type\x18\x01 \x01(\x0e\x32\x18.compas_pb.data.DataType\x12\r\n\x03int\x18\x02 \x01(\x05H\x00\x12\x0f\n\x05\x66loat\x18\x03 \x01(\x02H\x00\x12\x0e\n\x04\x62ool\x18\x04 \x01(\x08H\x00\x12\r\n\x03str\x18\x05 \x01(\tH\x00\x12\x0f\n\x05\x62ytes\x18\x06 \x01(\x0cH\x00\x42\x06\n\x04\x64\x61ta\"-\n\x07\x41nyData\x12\"\n\x04\x64\x61ta\x18\x01 \x01(\x0b\x32\x14.google.protobuf.Any\"1\n\x08ListData\x12%\n\x04\x64\x61ta\x18\x01 \x03(\x0b\x32\x17.compas_pb.data.AnyData\"\x82\x01\n\x08\x44ictData\x12\x30\n\x04\x64\x61ta\x18\x01 \x03(\x0b\x32\".compas_pb.data.DictData.DataEntry\x1a\x44\n\tDataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.compas_pb.data.AnyData:\x02\x38\x01\"4\n\x0bMessageData\x12%\n\x04\x64\x61ta\x18\x01 \x01(\x0b\x32\x17.compas_pb.data.AnyData*I\n\x08\x44\x61taType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x07\n\x03INT\x10\x01\x12\t\n\x05\x46LOAT\x10\x02\x12\x08\n\x04\x42OOL\x10\x03\x12\x07\n\x03STR\x10\x04\x12\t\n\x05\x42YTES\x10\x05\x62\x06proto3')
29
+
30
+ _globals = globals()
31
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
32
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'compas_pb.generated.message_pb2', _globals)
33
+ if not _descriptor._USE_C_DESCRIPTORS:
34
+ DESCRIPTOR._loaded_options = None
35
+ _globals['_DICTDATA_DATAENTRY']._loaded_options = None
36
+ _globals['_DICTDATA_DATAENTRY']._serialized_options = b'8\001'
37
+ _globals['_DATATYPE']._serialized_start=511
38
+ _globals['_DATATYPE']._serialized_end=584
39
+ _globals['_PRIMITIVEDATA']._serialized_start=81
40
+ _globals['_PRIMITIVEDATA']._serialized_end=224
41
+ _globals['_ANYDATA']._serialized_start=226
42
+ _globals['_ANYDATA']._serialized_end=271
43
+ _globals['_LISTDATA']._serialized_start=273
44
+ _globals['_LISTDATA']._serialized_end=322
45
+ _globals['_DICTDATA']._serialized_start=325
46
+ _globals['_DICTDATA']._serialized_end=455
47
+ _globals['_DICTDATA_DATAENTRY']._serialized_start=387
48
+ _globals['_DICTDATA_DATAENTRY']._serialized_end=455
49
+ _globals['_MESSAGEDATA']._serialized_start=457
50
+ _globals['_MESSAGEDATA']._serialized_end=509
51
+ # @@protoc_insertion_point(module_scope)
@@ -0,0 +1,36 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # NO CHECKED-IN PROTOBUF GENCODE
4
+ # source: compas_pb/generated/point.proto
5
+ # Protobuf Python Version: 6.31.1
6
+ """Generated protocol buffer code."""
7
+ from google.protobuf import descriptor as _descriptor
8
+ from google.protobuf import descriptor_pool as _descriptor_pool
9
+ from google.protobuf import runtime_version as _runtime_version
10
+ from google.protobuf import symbol_database as _symbol_database
11
+ from google.protobuf.internal import builder as _builder
12
+ _runtime_version.ValidateProtobufRuntimeVersion(
13
+ _runtime_version.Domain.PUBLIC,
14
+ 6,
15
+ 31,
16
+ 1,
17
+ '',
18
+ 'compas_pb/generated/point.proto'
19
+ )
20
+ # @@protoc_insertion_point(imports)
21
+
22
+ _sym_db = _symbol_database.Default()
23
+
24
+
25
+
26
+
27
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1f\x63ompas_pb/generated/point.proto\x12\x0e\x63ompas_pb.data\"H\n\tPointData\x12\x0c\n\x04guid\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\t\n\x01x\x18\x03 \x01(\x02\x12\t\n\x01y\x18\x04 \x01(\x02\x12\t\n\x01z\x18\x05 \x01(\x02\x62\x06proto3')
28
+
29
+ _globals = globals()
30
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
31
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'compas_pb.generated.point_pb2', _globals)
32
+ if not _descriptor._USE_C_DESCRIPTORS:
33
+ DESCRIPTOR._loaded_options = None
34
+ _globals['_POINTDATA']._serialized_start=51
35
+ _globals['_POINTDATA']._serialized_end=123
36
+ # @@protoc_insertion_point(module_scope)
@@ -0,0 +1,36 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # NO CHECKED-IN PROTOBUF GENCODE
4
+ # source: compas_pb/generated/vector.proto
5
+ # Protobuf Python Version: 6.31.1
6
+ """Generated protocol buffer code."""
7
+ from google.protobuf import descriptor as _descriptor
8
+ from google.protobuf import descriptor_pool as _descriptor_pool
9
+ from google.protobuf import runtime_version as _runtime_version
10
+ from google.protobuf import symbol_database as _symbol_database
11
+ from google.protobuf.internal import builder as _builder
12
+ _runtime_version.ValidateProtobufRuntimeVersion(
13
+ _runtime_version.Domain.PUBLIC,
14
+ 6,
15
+ 31,
16
+ 1,
17
+ '',
18
+ 'compas_pb/generated/vector.proto'
19
+ )
20
+ # @@protoc_insertion_point(imports)
21
+
22
+ _sym_db = _symbol_database.Default()
23
+
24
+
25
+
26
+
27
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n compas_pb/generated/vector.proto\x12\x0e\x63ompas_pb.data\"I\n\nVectorData\x12\x0c\n\x04guid\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\t\n\x01x\x18\x03 \x01(\x02\x12\t\n\x01y\x18\x04 \x01(\x02\x12\t\n\x01z\x18\x05 \x01(\x02\x62\x06proto3')
28
+
29
+ _globals = globals()
30
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
31
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'compas_pb.generated.vector_pb2', _globals)
32
+ if not _descriptor._USE_C_DESCRIPTORS:
33
+ DESCRIPTOR._loaded_options = None
34
+ _globals['_VECTORDATA']._serialized_start=52
35
+ _globals['_VECTORDATA']._serialized_end=125
36
+ # @@protoc_insertion_point(module_scope)
compas_pb/registry.py ADDED
@@ -0,0 +1,57 @@
1
+ from typing import Any
2
+ from typing import Callable
3
+ from typing import Dict
4
+ from typing import Type
5
+
6
+
7
+ class PbSerializerRegistrationError(Exception):
8
+ """Custom exception for errors in Protocol Buffer serializer registration."""
9
+
10
+ pass
11
+
12
+
13
+ _SERIALIZERS: Dict[Type, Callable] = {}
14
+ _DESERIALIZERS: Dict[str, Callable] = {}
15
+
16
+
17
+ def pb_serializer(obj_type: Type):
18
+ """Decorator which registers a serializer for ``obj_type`` to its protobuf."""
19
+
20
+ def wrapper(func):
21
+ print(f"Registering serializer for {obj_type.__name__}")
22
+ _SERIALIZERS[obj_type] = func
23
+ return func
24
+
25
+ return wrapper
26
+
27
+
28
+ def pb_deserializer(pb_type: Type):
29
+ """Decorator which registers a deserializer for the protobuf module."""
30
+
31
+ def wrapper(func):
32
+ type_url = pb_type.DESCRIPTOR.full_name
33
+ try:
34
+ _DESERIALIZERS[type_url] = func
35
+ except AttributeError:
36
+ raise PbSerializerRegistrationError(f"Unable to register deserializer for {pb_type}. Sure it's a protobuf type?")
37
+ else:
38
+ # used for unpacking Any
39
+ func.__deserializer_type__ = pb_type
40
+ return func
41
+
42
+ return wrapper
43
+
44
+
45
+ class SerialzerRegistry:
46
+ @staticmethod
47
+ def get_serializer(data: Any) -> Callable:
48
+ result = None
49
+ for cls in type(data).mro():
50
+ result = _SERIALIZERS.get(cls)
51
+ if result:
52
+ break
53
+ return result
54
+
55
+ @staticmethod
56
+ def get_deserializer(pb_typename) -> Callable:
57
+ return _DESERIALIZERS.get(pb_typename)
@@ -0,0 +1,139 @@
1
+ Metadata-Version: 2.4
2
+ Name: compas_pb
3
+ Version: 0.1.0
4
+ Summary: Protobuf extension for COMPAS Data
5
+ Author-email: Wei-Ting Chen <chenwei@arch.ethz.ch>, Chen Kasirer <kasirer@arch.ethz.ch>
6
+ License: MIT License
7
+
8
+ Gramazio Kohler Research
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://gramaziokohler.github.io/compas_pb
29
+ Project-URL: Documentation, https://gramaziokohler.github.io/compas_pb
30
+ Project-URL: Repository, https://github.com/gramaziokohler/compas_pb
31
+ Project-URL: Changelog, https://github.com/gramaziokohler/compas_pb/blob/main/CHANGELOG.md
32
+ Project-URL: Issues, https://github.com/gramaziokohler/compas_pb/issues
33
+ Project-URL: Forum, https://forum.compas-framework.org/
34
+ Classifier: Development Status :: 4 - Beta
35
+ Classifier: Topic :: Scientific/Engineering
36
+ Classifier: Operating System :: Unix
37
+ Classifier: Operating System :: POSIX
38
+ Classifier: Operating System :: Microsoft :: Windows
39
+ Classifier: Programming Language :: Python
40
+ Classifier: Programming Language :: Python :: 3
41
+ Classifier: Programming Language :: Python :: 3.10
42
+ Classifier: Programming Language :: Python :: 3.11
43
+ Classifier: Programming Language :: Python :: 3.12
44
+ Requires-Python: >=3.9
45
+ Description-Content-Type: text/markdown
46
+ License-File: LICENSE
47
+ Requires-Dist: compas>=2
48
+ Requires-Dist: protobuf>=6.31.1
49
+ Provides-Extra: dev
50
+ Requires-Dist: attrs>=17.4; extra == "dev"
51
+ Requires-Dist: black>=22.12.0; extra == "dev"
52
+ Requires-Dist: bump-my-version; extra == "dev"
53
+ Requires-Dist: compas_invocations2; extra == "dev"
54
+ Requires-Dist: invoke>=0.14; extra == "dev"
55
+ Requires-Dist: ruff; extra == "dev"
56
+ Requires-Dist: sphinx_compas2_theme; extra == "dev"
57
+ Requires-Dist: twine; extra == "dev"
58
+ Requires-Dist: wheel; extra == "dev"
59
+ Requires-Dist: pytest-mock; extra == "dev"
60
+ Requires-Dist: build; extra == "dev"
61
+ Dynamic: license-file
62
+
63
+ # compas_pb
64
+
65
+ A COMPAS extension which lets you serialize and deserialize COMPAS `Data` types using protobuf.
66
+
67
+ ## Installation
68
+
69
+ Stable releases can be installed from PyPI.
70
+
71
+ ```bash
72
+ pip install compas_pb
73
+ ```
74
+
75
+ ## Basic Usage
76
+
77
+ ### Serialize to file
78
+
79
+ ```python
80
+ from compas.geometry import Vector
81
+ from compas_pb import pb_dump
82
+ from compas_pb import pb_load
83
+
84
+ PATH = "vector.data"
85
+
86
+ vector = Vector(1.0, 2.0, 3.0)
87
+
88
+ pb_dump(vector, PATH)
89
+
90
+ loaded_vector = pb_load(PATH)
91
+
92
+ ```
93
+
94
+ ### (De)serialize to bytes
95
+
96
+ ```python
97
+ from compas.geometry import Vector
98
+ from compas_pb import pb_dump_bts
99
+ from compas_pb import pb_load_bts
100
+
101
+ vector = Vector(1.0, 2.0, 3.0)
102
+
103
+ bytes_vector = pb_dump_bts(vector)
104
+
105
+ loaded_vector = pb_load_bts(bytes_vector)
106
+
107
+ ```
108
+
109
+ ### Serialization of arbitrarily nested data structures
110
+
111
+ ```python
112
+ from compas.geometry import Vector
113
+ from compas.geometry import Polyline
114
+ from compas_pb import pb_dump_bts
115
+ from compas_pb import pb_load_bts
116
+
117
+ data = {
118
+ "direction": Vector(1.0, 2.0, 3.0),
119
+ "outlines":
120
+ [
121
+ Polyline([0, 0, 0], [1, 1, 1], [2, 2, 2]),
122
+ Polyline([3, 3, 3], [4, 4, 4], [5, 5, 5])
123
+ ],
124
+ }
125
+
126
+ pb_data = pb_dump_bts(data)
127
+
128
+ loaded_data = pb_load_bts(pb_data)
129
+
130
+ ```
131
+
132
+ ## Documentation
133
+
134
+ For further "getting started" instructions, a tutorial, examples, and an API reference,
135
+ please check out the online documentation here: [compas_pb docs](https://gramaziokohler.github.io/compas_pb)
136
+
137
+ ## Issue Tracker
138
+
139
+ If you find a bug or if you have a problem with running the code, please file an issue on the [Issue Tracker](https://github.com/gramaziokohler/compas_pb/issues).
@@ -0,0 +1,18 @@
1
+ compas_pb/__init__.py,sha256=YL2KB6xEh5ZFVwwduNd9xV7O6ISrqGMlCpEu6aVKQtY,996
2
+ compas_pb/api.py,sha256=W1orxacUubadENdQA9aT_QHDPjfYuCSxXOlmA2MztXQ,3188
3
+ compas_pb/conversions.py,sha256=PvCNy22uJa3qTxtPiOzLsR_pbNyVU5L-HeXZ9luuL8c,4594
4
+ compas_pb/core.py,sha256=1Rrbs1s320mv7Nw_65SIftExyflvxwRNB63sqgY5cqM,10601
5
+ compas_pb/registry.py,sha256=wGGutFwRgN8Kz3qBcmo221esUS1b_65ZzmVNoJop1nM,1529
6
+ compas_pb/generated/circle_pb2.py,sha256=5q40m5qcrSIo364ZvAw7_RXLU7XMSNBgz9svRZje3B4,1611
7
+ compas_pb/generated/element_pb2.py,sha256=i3UBa9MUpARRdNYzMMMsh7YaFbFSX9yiFhdoM7LhJ1Y,1700
8
+ compas_pb/generated/frame_pb2.py,sha256=7DaeRr3eVf_CkjSVinZeuLgAG9p7YS1SbnwdPlGYaCk,1837
9
+ compas_pb/generated/line_pb2.py,sha256=gMHowN6UJdB2h33nqb9o5aQcmBpLcdc408VxzBkmLds,1632
10
+ compas_pb/generated/mesh_pb2.py,sha256=wdJ93r7w5Jf1YZHHaXyF6GlRk_58dgAcYG2KUz_9YMM,1878
11
+ compas_pb/generated/message_pb2.py,sha256=ur7Ar-MaPs5r5RUrIAW8AVYWCJA_459olvPQYCfBbTc,3110
12
+ compas_pb/generated/point_pb2.py,sha256=m-Z42Aj5dgEQBJ2XJnVs5_pFt1ghxf64EVc1sCzUBdM,1471
13
+ compas_pb/generated/vector_pb2.py,sha256=hc7ieQKZpait3XL3z3ysXxOMjwcvkoZwmgJo2o3BpwM,1472
14
+ compas_pb-0.1.0.dist-info/licenses/LICENSE,sha256=DWh2gvP-duhkl_NQe381E-kB6t1JYmfQoj2-cRiyfH8,1062
15
+ compas_pb-0.1.0.dist-info/METADATA,sha256=AI8PmI4B2PJL5iKOQBGbGYw_KaTOCgG31RAlagSLZ6s,4565
16
+ compas_pb-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
17
+ compas_pb-0.1.0.dist-info/top_level.txt,sha256=yhfpfzBf4DONPZzjZ52rUWso_YpiEQA249heZCamI1k,10
18
+ compas_pb-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Gramazio Kohler Research
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 @@
1
+ compas_pb