Skip to content

GSP Pydantic API Reference

The GSP Pydantic module provides serialization and deserialization capabilities using Pydantic models, enabling data validation and JSON schema generation for GSP objects.

Overview

gsp_pydantic

GSP Pydantic package initialization.

Serializer Module

The serializer module contains the serialization and parsing utilities for converting GSP objects to and from Pydantic models.

gsp_pydantic.serializer

Pydantic serializer and parser for GSP data structures.

Pydantic Serializer

gsp_pydantic.serializer.pydantic_serializer

Pydantic serializer for GSP data structures.

PydanticSerializer

Bases: gsp.types.serializer_base.SerializerBase

Serializer that converts GSP data structures into Pydantic models.

Source code in src/gsp_pydantic/serializer/pydantic_serializer.py
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
class PydanticSerializer(SerializerBase):
    """Serializer that converts GSP data structures into Pydantic models."""

    def __init__(self, canvas: Canvas):
        """Initialize the PydanticSerializer with a canvas.

        Args:
            canvas (Canvas): The canvas to be used in the serialization.
        """
        self._canvas = canvas

    def serialize(
        self,
        viewports: Sequence[Viewport],
        visuals: Sequence[VisualBase],
        model_matrices: Sequence[TransBuf],
        cameras: Sequence[Camera],
    ) -> PydanticDict:
        """Serialize the provided GSP data structures into a PydanticDict.

        Args:
            viewports (Sequence[Viewport]): The list of viewports to serialize.
            visuals (Sequence[VisualBase]): The list of visual elements to serialize.
            model_matrices (Sequence[TransBuf]): The list of model transformation matrices to serialize.
            cameras (Sequence[Camera]): The list of cameras to serialize.

        Returns:
            PydanticDict: The serialized data as a PydanticDict.
        """
        # =============================================================================
        #
        # =============================================================================

        pydanticCanvas = PydanticCanvas(
            uuid=self._canvas.get_uuid(),
            width=self._canvas.get_width(),
            height=self._canvas.get_height(),
            dpi=self._canvas.get_dpi(),
        )

        pydanticViewports = [
            PydanticViewport(
                uuid=viewport.get_uuid(),
                x=viewport.get_x(),
                y=viewport.get_y(),
                width=viewport.get_width(),
                height=viewport.get_height(),
            )
            for viewport in viewports
        ]

        pydantic_visuals = PydanticSerializer._visuals_to_pydantic(visuals)

        pydantic_model_matrices = [PydanticModelMatrix(model_matrix=PydanticSerializer._transbuf_to_pydantic(model_matrix)) for model_matrix in model_matrices]

        pydantic_cameras = [
            PydanticCamera(
                uuid=camera.get_uuid(),
                view_matrix=PydanticSerializer._transbuf_to_pydantic(camera.get_view_matrix()),
                projection_matrix=PydanticSerializer._transbuf_to_pydantic(camera.get_projection_matrix()),
            )
            for camera in cameras
        ]

        # =============================================================================
        #
        # =============================================================================

        pydantic_scene = PydanticScene(
            canvas=pydanticCanvas,
            viewports=pydanticViewports,
            visuals=pydantic_visuals,
            model_matrices=pydantic_model_matrices,
            cameras=pydantic_cameras,
        )

        pydantic_scene_dict: PydanticDict = pydantic_scene.model_dump()

        return pydantic_scene_dict  # Placeholder for JSON byte output

    # =============================================================================
    # Static methods
    # =============================================================================

    @staticmethod
    def _visuals_to_pydantic(visuals: Sequence[VisualBase]) -> list[PydanticVisual]:
        pydantic_visuals: list[PydanticVisual] = []
        for visual in visuals:
            if isinstance(visual, Markers):
                markers = typing.cast(Markers, visual)
                pydantic_visual = PydanticVisual(
                    type="markers",
                    visual=PydanticMarkers(
                        uuid=markers.get_uuid(),
                        marker_shape=markers.get_marker_shape().name,
                        positions=PydanticSerializer._transbuf_to_pydantic(markers.get_positions()),
                        sizes=PydanticSerializer._transbuf_to_pydantic(markers.get_sizes()),
                        face_colors=PydanticSerializer._transbuf_to_pydantic(markers.get_face_colors()),
                        edge_colors=PydanticSerializer._transbuf_to_pydantic(markers.get_edge_colors()),
                        edge_widths=PydanticSerializer._transbuf_to_pydantic(markers.get_edge_widths()),
                    ),
                )
                pydantic_visuals.append(pydantic_visual)
            elif isinstance(visual, Paths):
                paths = typing.cast(Paths, visual)
                pydantic_visual = PydanticVisual(
                    type="paths",
                    visual=PydanticPaths(
                        uuid=paths.get_uuid(),
                        positions=PydanticSerializer._transbuf_to_pydantic(paths.get_positions()),
                        path_sizes=PydanticSerializer._transbuf_to_pydantic(paths.get_path_sizes()),
                        colors=PydanticSerializer._transbuf_to_pydantic(paths.get_colors()),
                        line_widths=PydanticSerializer._transbuf_to_pydantic(paths.get_line_widths()),
                        cap_style=paths.get_cap_style().name,
                        join_style=paths.get_join_style().name,
                    ),
                )
                pydantic_visuals.append(pydantic_visual)
            elif isinstance(visual, Pixels):
                pixels = typing.cast(Pixels, visual)
                pydantic_visual = PydanticVisual(
                    type="pixels",
                    visual=PydanticPixels(
                        uuid=pixels.get_uuid(),
                        positions=PydanticSerializer._transbuf_to_pydantic(pixels.get_positions()),
                        colors=PydanticSerializer._transbuf_to_pydantic(pixels.get_colors()),
                        groups=pixels.get_groups(),
                    ),
                )
                pydantic_visuals.append(pydantic_visual)
            elif isinstance(visual, Points):
                points = typing.cast(Points, visual)
                pydantic_visual = PydanticVisual(
                    type="points",
                    visual=PydanticPoints(
                        uuid=points.get_uuid(),
                        positions=PydanticSerializer._transbuf_to_pydantic(points.get_positions()),
                        sizes=PydanticSerializer._transbuf_to_pydantic(points.get_sizes()),
                        face_colors=PydanticSerializer._transbuf_to_pydantic(points.get_face_colors()),
                        edge_colors=PydanticSerializer._transbuf_to_pydantic(points.get_edge_colors()),
                        edge_widths=PydanticSerializer._transbuf_to_pydantic(points.get_edge_widths()),
                    ),
                )
                pydantic_visuals.append(pydantic_visual)
            elif isinstance(visual, Segments):
                segments = typing.cast(Segments, visual)
                pydantic_visual = PydanticVisual(
                    type="segments",
                    visual=PydanticSegments(
                        uuid=segments.get_uuid(),
                        positions=PydanticSerializer._transbuf_to_pydantic(segments.get_positions()),
                        line_widths=PydanticSerializer._transbuf_to_pydantic(segments.get_line_widths()),
                        cap_style=segments.get_cap_style().name,
                        colors=PydanticSerializer._transbuf_to_pydantic(segments.get_colors()),
                    ),
                )
                pydantic_visuals.append(pydantic_visual)
            elif isinstance(visual, Texts):
                texts = typing.cast(Texts, visual)
                pydantic_visual = PydanticVisual(
                    type="texts",
                    visual=PydanticTexts(
                        uuid=texts.get_uuid(),
                        positions=PydanticSerializer._transbuf_to_pydantic(texts.get_positions()),
                        texts=texts.get_strings(),
                        colors=PydanticSerializer._transbuf_to_pydantic(texts.get_colors()),
                        font_sizes=PydanticSerializer._transbuf_to_pydantic(texts.get_font_sizes()),
                        anchors=PydanticSerializer._transbuf_to_pydantic(texts.get_anchors()),
                        angles=PydanticSerializer._transbuf_to_pydantic(texts.get_angles()),
                        font_name=texts.get_font_name(),
                    ),
                )
                pydantic_visuals.append(pydantic_visual)
            else:
                raise NotImplementedError(f"Serialization for this Visual type {type(visual)} is not implemented yet")

        # return the list of pydantic visuals
        return pydantic_visuals

    @staticmethod
    def _transbuf_to_pydantic(transbuf: TransBuf) -> PydanticTransBuf:
        if isinstance(transbuf, Buffer):
            buffer = typing.cast(Buffer, transbuf)
            pydantic_transbuf = PydanticTransBuf(
                type="buffer",
                transBuf=PydanticBuffer(
                    count=buffer.get_count(),
                    buffer_type=buffer.get_type().name,
                    data_base64=base64.b64encode(buffer.to_bytearray()).decode("utf-8"),
                ),
            )
            return pydantic_transbuf
        elif isinstance(transbuf, TransformChain):
            transform_chain = typing.cast(TransformChain, transbuf)
            pydantic_transbuf = PydanticTransBuf(
                type="transform_chain",
                transBuf=PydanticTransformChain(
                    transform_chain=transform_chain.serialize(),
                ),
            )
            return pydantic_transbuf
        else:
            raise ValueError("Unknown TransBuf type")

__init__(canvas: Canvas)

Initialize the PydanticSerializer with a canvas.

Parameters:

Name Type Description Default
canvas gsp.core.canvas.Canvas

The canvas to be used in the serialization.

required
Source code in src/gsp_pydantic/serializer/pydantic_serializer.py
46
47
48
49
50
51
52
def __init__(self, canvas: Canvas):
    """Initialize the PydanticSerializer with a canvas.

    Args:
        canvas (Canvas): The canvas to be used in the serialization.
    """
    self._canvas = canvas

serialize(viewports: Sequence[Viewport], visuals: Sequence[VisualBase], model_matrices: Sequence[TransBuf], cameras: Sequence[Camera]) -> PydanticDict

Serialize the provided GSP data structures into a PydanticDict.

Parameters:

Name Type Description Default
viewports typing.Sequence[gsp.core.viewport.Viewport]

The list of viewports to serialize.

required
visuals typing.Sequence[gsp.types.visual_base.VisualBase]

The list of visual elements to serialize.

required
model_matrices typing.Sequence[gsp.types.transbuf.TransBuf]

The list of model transformation matrices to serialize.

required
cameras typing.Sequence[gsp.core.camera.Camera]

The list of cameras to serialize.

required

Returns:

Name Type Description
PydanticDict gsp_pydantic.types.pydantic_dict.PydanticDict

The serialized data as a PydanticDict.

Source code in src/gsp_pydantic/serializer/pydantic_serializer.py
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
def serialize(
    self,
    viewports: Sequence[Viewport],
    visuals: Sequence[VisualBase],
    model_matrices: Sequence[TransBuf],
    cameras: Sequence[Camera],
) -> PydanticDict:
    """Serialize the provided GSP data structures into a PydanticDict.

    Args:
        viewports (Sequence[Viewport]): The list of viewports to serialize.
        visuals (Sequence[VisualBase]): The list of visual elements to serialize.
        model_matrices (Sequence[TransBuf]): The list of model transformation matrices to serialize.
        cameras (Sequence[Camera]): The list of cameras to serialize.

    Returns:
        PydanticDict: The serialized data as a PydanticDict.
    """
    # =============================================================================
    #
    # =============================================================================

    pydanticCanvas = PydanticCanvas(
        uuid=self._canvas.get_uuid(),
        width=self._canvas.get_width(),
        height=self._canvas.get_height(),
        dpi=self._canvas.get_dpi(),
    )

    pydanticViewports = [
        PydanticViewport(
            uuid=viewport.get_uuid(),
            x=viewport.get_x(),
            y=viewport.get_y(),
            width=viewport.get_width(),
            height=viewport.get_height(),
        )
        for viewport in viewports
    ]

    pydantic_visuals = PydanticSerializer._visuals_to_pydantic(visuals)

    pydantic_model_matrices = [PydanticModelMatrix(model_matrix=PydanticSerializer._transbuf_to_pydantic(model_matrix)) for model_matrix in model_matrices]

    pydantic_cameras = [
        PydanticCamera(
            uuid=camera.get_uuid(),
            view_matrix=PydanticSerializer._transbuf_to_pydantic(camera.get_view_matrix()),
            projection_matrix=PydanticSerializer._transbuf_to_pydantic(camera.get_projection_matrix()),
        )
        for camera in cameras
    ]

    # =============================================================================
    #
    # =============================================================================

    pydantic_scene = PydanticScene(
        canvas=pydanticCanvas,
        viewports=pydanticViewports,
        visuals=pydantic_visuals,
        model_matrices=pydantic_model_matrices,
        cameras=pydantic_cameras,
    )

    pydantic_scene_dict: PydanticDict = pydantic_scene.model_dump()

    return pydantic_scene_dict  # Placeholder for JSON byte output

Pydantic Parser

gsp_pydantic.serializer.pydantic_parser

Pydantic parser for GSP data structures.

PydanticParser

Parser that converts Pydantic models into GSP data structures.

Source code in src/gsp_pydantic/serializer/pydantic_parser.py
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
class PydanticParser:
    """Parser that converts Pydantic models into GSP data structures."""
    def __init__(self):
        """Initialize the PydanticParser."""
        pass

    def parse(self, json_dict: PydanticDict) -> tuple[
        Canvas,
        list[Viewport],
        list[VisualBase],
        list[TransBuf],
        list[Camera],
    ]:
        """Parse a Pydantic JSON dictionary into GSP data structures.

        Args:
            json_dict (PydanticDict): The Pydantic JSON dictionary representing the scene.

        Returns:
            tuple[
                Canvas,
                list[Viewport],
                list[VisualBase],
                list[TransBuf],
                list[Camera],
            ]: The parsed GSP data structures.
        """
        json_str = json.dumps(json_dict, indent=4)
        pydantic_scene = PydanticScene.model_validate(pydantic_core.from_json(json_str, allow_partial=True))

        # =============================================================================
        # Parse Pydantic Canvas
        # =============================================================================
        pydantic_canvas = pydantic_scene.canvas
        canvas = Canvas(pydantic_canvas.width, pydantic_canvas.height, pydantic_canvas.dpi)
        canvas._uuid = pydantic_canvas.uuid

        # =============================================================================
        # Parse Pydantic Viewports
        # =============================================================================
        viewports: list[Viewport] = []  # Placeholder implementation
        for pydantic_viewport in pydantic_scene.viewports:
            viewport = Viewport(
                pydantic_viewport.x,
                pydantic_viewport.y,
                pydantic_viewport.width,
                pydantic_viewport.height,
            )
            viewport._uuid = pydantic_viewport.uuid
            viewports.append(viewport)

        # =============================================================================
        # Parse Pydantic Visuals
        # =============================================================================
        visuals: list[VisualBase] = []  # Placeholder implementation
        for pydantic_visual in pydantic_scene.visuals:
            visual = PydanticParser._pydantic_to_visual(pydantic_visual)
            visuals.append(visual)

        # =============================================================================
        # Parse Pydantic Model Matrices
        # =============================================================================
        model_matrices: list[TransBuf] = []  # Placeholder implementation
        for pydantic_model_matrix in pydantic_scene.model_matrices:
            model_matrix = PydanticParser._pydantic_to_transbuf(pydantic_model_matrix.model_matrix)
            model_matrices.append(model_matrix)

        # =============================================================================
        # Parse Pydanticy Cameras
        # =============================================================================
        cameras: list[Camera] = []
        for pydantic_camera in pydantic_scene.cameras:
            view_matrix = PydanticParser._pydantic_to_transbuf(pydantic_camera.view_matrix)
            projection_matrix = PydanticParser._pydantic_to_transbuf(pydantic_camera.projection_matrix)
            camera = Camera(view_matrix, projection_matrix)
            camera._uuid = pydantic_camera.uuid
            cameras.append(camera)

        # =============================================================================
        # Return the renderer arguments
        # =============================================================================
        return canvas, viewports, visuals, model_matrices, cameras

    @staticmethod
    def _pydantic_to_visual(pydantic_visual: PydanticVisual) -> VisualBase:
        if pydantic_visual.type == "markers":
            pydantic_markers = typing.cast(PydanticMarkers, pydantic_visual.visual)
            marker_shape = MarkerShape[pydantic_markers.marker_shape]
            positions = PydanticParser._pydantic_to_transbuf(pydantic_markers.positions)
            sizes = PydanticParser._pydantic_to_transbuf(pydantic_markers.sizes)
            face_colors = PydanticParser._pydantic_to_transbuf(pydantic_markers.face_colors)
            edge_colors = PydanticParser._pydantic_to_transbuf(pydantic_markers.edge_colors)
            edge_widths = PydanticParser._pydantic_to_transbuf(pydantic_markers.edge_widths)
            markers = Markers(marker_shape, positions, sizes, face_colors, edge_colors, edge_widths)
            markers._uuid = pydantic_markers.uuid
            return markers
        elif pydantic_visual.type == "paths":
            pydantic_paths = typing.cast(PydanticPaths, pydantic_visual.visual)
            positions = PydanticParser._pydantic_to_transbuf(pydantic_paths.positions)
            path_sizes = PydanticParser._pydantic_to_transbuf(pydantic_paths.path_sizes)
            colors = PydanticParser._pydantic_to_transbuf(pydantic_paths.colors)
            line_widths = PydanticParser._pydantic_to_transbuf(pydantic_paths.line_widths)
            cap_style = CapStyle[pydantic_paths.cap_style]
            join_style = JoinStyle[pydantic_paths.join_style]
            paths = Paths(positions, path_sizes, colors, line_widths, cap_style, join_style)
            paths._uuid = pydantic_paths.uuid
            return paths
        elif pydantic_visual.type == "pixels":
            pydantic_pixels = typing.cast(PydanticPixels, pydantic_visual.visual)
            positions = PydanticParser._pydantic_to_transbuf(pydantic_pixels.positions)
            colors = PydanticParser._pydantic_to_transbuf(pydantic_pixels.colors)
            groups = pydantic_pixels.groups
            pixels = Pixels(positions, colors, groups)
            pixels._uuid = pydantic_pixels.uuid
            return pixels
        elif pydantic_visual.type == "points":
            pydantic_points = typing.cast(PydanticPoints, pydantic_visual.visual)
            positions = PydanticParser._pydantic_to_transbuf(pydantic_points.positions)
            sizes = PydanticParser._pydantic_to_transbuf(pydantic_points.sizes)
            face_colors = PydanticParser._pydantic_to_transbuf(pydantic_points.face_colors)
            edge_colors = PydanticParser._pydantic_to_transbuf(pydantic_points.edge_colors)
            edge_widths = PydanticParser._pydantic_to_transbuf(pydantic_points.edge_widths)
            points = Points(positions, sizes, face_colors, edge_colors, edge_widths)
            points._uuid = pydantic_points.uuid
            return points
        elif pydantic_visual.type == "segments":
            pydantic_segments = typing.cast(PydanticSegments, pydantic_visual.visual)
            positions = PydanticParser._pydantic_to_transbuf(pydantic_segments.positions)
            line_widths = PydanticParser._pydantic_to_transbuf(pydantic_segments.line_widths)
            cap_style = CapStyle[pydantic_segments.cap_style]
            colors = PydanticParser._pydantic_to_transbuf(pydantic_segments.colors)
            segments = Segments(positions, line_widths, cap_style, colors)
            segments._uuid = pydantic_segments.uuid
            return segments
        elif pydantic_visual.type == "texts":
            pydantic_texts = typing.cast(PydanticTexts, pydantic_visual.visual)
            positions = PydanticParser._pydantic_to_transbuf(pydantic_texts.positions)
            texts_list = pydantic_texts.texts
            colors = PydanticParser._pydantic_to_transbuf(pydantic_texts.colors)
            font_sizes = PydanticParser._pydantic_to_transbuf(pydantic_texts.font_sizes)
            anchors = PydanticParser._pydantic_to_transbuf(pydantic_texts.anchors)
            angles = PydanticParser._pydantic_to_transbuf(pydantic_texts.angles)
            font_name = pydantic_texts.font_name
            texts = Texts(positions, texts_list, colors, font_sizes, anchors, angles, font_name)
            texts._uuid = pydantic_texts.uuid
            return texts
        else:
            raise ValueError(f"Unknown PydanticVisual type: {pydantic_visual.type}")

    @staticmethod
    def _pydantic_to_transbuf(pydantic_transbuf: PydanticTransBuf) -> TransBuf:
        if pydantic_transbuf.type == "buffer":
            pydantic_buffer = typing.cast(PydanticBuffer, pydantic_transbuf.transBuf)
            count = pydantic_buffer.count
            buffer_type = BufferType[pydantic_buffer.buffer_type]
            buffer_data = bytearray(base64.b64decode(pydantic_buffer.data_base64))
            buffer = Buffer.from_bytearray(buffer_data, buffer_type)
            assert buffer.get_count() == count, f"Buffer count mismatch: expected {count}, got {buffer.get_count()}"
            return buffer
        elif pydantic_transbuf.type == "transform_chain":
            pydantic_transform_chain = typing.cast(PydanticTransformChain, pydantic_transbuf.transBuf)
            deserialized_transform = TransformChain.deserialize(pydantic_transform_chain.transform_chain)
            buffer = deserialized_transform.run()
            return buffer
        else:
            raise ValueError(f"Unknown PydanticTransBuf type: {pydantic_transbuf.type}")

__init__()

Initialize the PydanticParser.

Source code in src/gsp_pydantic/serializer/pydantic_parser.py
39
40
41
def __init__(self):
    """Initialize the PydanticParser."""
    pass

parse(json_dict: PydanticDict) -> tuple[Canvas, list[Viewport], list[VisualBase], list[TransBuf], list[Camera]]

Parse a Pydantic JSON dictionary into GSP data structures.

Parameters:

Name Type Description Default
json_dict gsp_pydantic.types.pydantic_dict.PydanticDict

The Pydantic JSON dictionary representing the scene.

required

Returns:

Type Description
gsp.core.canvas.Canvas

tuple[ Canvas, list[Viewport], list[VisualBase], list[TransBuf], list[Camera],

list[gsp.core.viewport.Viewport]

]: The parsed GSP data structures.

Source code in src/gsp_pydantic/serializer/pydantic_parser.py
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
def parse(self, json_dict: PydanticDict) -> tuple[
    Canvas,
    list[Viewport],
    list[VisualBase],
    list[TransBuf],
    list[Camera],
]:
    """Parse a Pydantic JSON dictionary into GSP data structures.

    Args:
        json_dict (PydanticDict): The Pydantic JSON dictionary representing the scene.

    Returns:
        tuple[
            Canvas,
            list[Viewport],
            list[VisualBase],
            list[TransBuf],
            list[Camera],
        ]: The parsed GSP data structures.
    """
    json_str = json.dumps(json_dict, indent=4)
    pydantic_scene = PydanticScene.model_validate(pydantic_core.from_json(json_str, allow_partial=True))

    # =============================================================================
    # Parse Pydantic Canvas
    # =============================================================================
    pydantic_canvas = pydantic_scene.canvas
    canvas = Canvas(pydantic_canvas.width, pydantic_canvas.height, pydantic_canvas.dpi)
    canvas._uuid = pydantic_canvas.uuid

    # =============================================================================
    # Parse Pydantic Viewports
    # =============================================================================
    viewports: list[Viewport] = []  # Placeholder implementation
    for pydantic_viewport in pydantic_scene.viewports:
        viewport = Viewport(
            pydantic_viewport.x,
            pydantic_viewport.y,
            pydantic_viewport.width,
            pydantic_viewport.height,
        )
        viewport._uuid = pydantic_viewport.uuid
        viewports.append(viewport)

    # =============================================================================
    # Parse Pydantic Visuals
    # =============================================================================
    visuals: list[VisualBase] = []  # Placeholder implementation
    for pydantic_visual in pydantic_scene.visuals:
        visual = PydanticParser._pydantic_to_visual(pydantic_visual)
        visuals.append(visual)

    # =============================================================================
    # Parse Pydantic Model Matrices
    # =============================================================================
    model_matrices: list[TransBuf] = []  # Placeholder implementation
    for pydantic_model_matrix in pydantic_scene.model_matrices:
        model_matrix = PydanticParser._pydantic_to_transbuf(pydantic_model_matrix.model_matrix)
        model_matrices.append(model_matrix)

    # =============================================================================
    # Parse Pydanticy Cameras
    # =============================================================================
    cameras: list[Camera] = []
    for pydantic_camera in pydantic_scene.cameras:
        view_matrix = PydanticParser._pydantic_to_transbuf(pydantic_camera.view_matrix)
        projection_matrix = PydanticParser._pydantic_to_transbuf(pydantic_camera.projection_matrix)
        camera = Camera(view_matrix, projection_matrix)
        camera._uuid = pydantic_camera.uuid
        cameras.append(camera)

    # =============================================================================
    # Return the renderer arguments
    # =============================================================================
    return canvas, viewports, visuals, model_matrices, cameras

Types Module

The types module defines Pydantic models for GSP data structures, providing validation and schema generation.

gsp_pydantic.types

Pydantic types for GSP data structures.

Pydantic Dict

gsp_pydantic.types.pydantic_dict

Pydantic type for a dictionary with string keys and any values.

PydanticDict = Dict[str, Any] module-attribute

Type alias for a dictionary with string keys and any values.

Pydantic Types

gsp_pydantic.types.pydantic_types

"Pydantic models for GSP data types.

PydanticGroups = Union[int, list[int], list[list[int]]] module-attribute

Type alias for groups which can be an int, a list of ints, or a list of list of ints.

PydanticBuffer

Bases: pydantic.BaseModel

Pydantic model representing a buffer with encoded data.

This class stores buffer data in a serializable format using base64 encoding.

Source code in src/gsp_pydantic/types/pydantic_types.py
14
15
16
17
18
19
20
21
22
23
24
25
class PydanticBuffer(BaseModel):
    """Pydantic model representing a buffer with encoded data.

    This class stores buffer data in a serializable format using base64 encoding.
    """

    count: int
    """number of elements in the buffer"""
    buffer_type: str
    """type of the buffer elements, corresponds to BufferType enum value"""
    data_base64: str
    """data encoded in base64 format"""

buffer_type: str instance-attribute

type of the buffer elements, corresponds to BufferType enum value

count: int instance-attribute

number of elements in the buffer

data_base64: str instance-attribute

data encoded in base64 format

PydanticCamera

Bases: pydantic.BaseModel

Pydantic model representing a camera.

Defines the camera's view and projection transformations for rendering the scene.

Source code in src/gsp_pydantic/types/pydantic_types.py
196
197
198
199
200
201
202
203
204
class PydanticCamera(BaseModel):
    """Pydantic model representing a camera.

    Defines the camera's view and projection transformations for rendering the scene.
    """

    uuid: str
    view_matrix: PydanticTransBuf
    projection_matrix: PydanticTransBuf

PydanticCanvas

Bases: pydantic.BaseModel

Pydantic model representing a canvas for rendering.

Defines the rendering surface with dimensions and resolution.

Source code in src/gsp_pydantic/types/pydantic_types.py
162
163
164
165
166
167
168
169
170
171
class PydanticCanvas(BaseModel):
    """Pydantic model representing a canvas for rendering.

    Defines the rendering surface with dimensions and resolution.
    """

    uuid: str
    width: int
    height: int
    dpi: float

PydanticMarkers

Bases: pydantic.BaseModel

Pydantic model representing marker visual elements.

Markers are geometric shapes (circles, squares, etc.) positioned in space with configurable appearance properties.

Source code in src/gsp_pydantic/types/pydantic_types.py
59
60
61
62
63
64
65
66
67
68
69
70
71
72
class PydanticMarkers(BaseModel):
    """Pydantic model representing marker visual elements.

    Markers are geometric shapes (circles, squares, etc.) positioned in space
    with configurable appearance properties.
    """

    uuid: str
    marker_shape: str
    positions: PydanticTransBuf
    sizes: PydanticTransBuf
    face_colors: PydanticTransBuf
    edge_colors: PydanticTransBuf
    edge_widths: PydanticTransBuf

PydanticModelMatrix

Bases: pydantic.BaseModel

Pydantic model representing a model transformation matrix.

Contains the transformation matrix for positioning objects in the scene.

Source code in src/gsp_pydantic/types/pydantic_types.py
187
188
189
190
191
192
193
class PydanticModelMatrix(BaseModel):
    """Pydantic model representing a model transformation matrix.

    Contains the transformation matrix for positioning objects in the scene.
    """

    model_matrix: PydanticTransBuf

PydanticPaths

Bases: pydantic.BaseModel

Pydantic model representing path visual elements.

Paths are continuous lines or curves with configurable line styles and colors.

Source code in src/gsp_pydantic/types/pydantic_types.py
75
76
77
78
79
80
81
82
83
84
85
86
87
class PydanticPaths(BaseModel):
    """Pydantic model representing path visual elements.

    Paths are continuous lines or curves with configurable line styles and colors.
    """

    uuid: str
    positions: PydanticTransBuf
    path_sizes: PydanticTransBuf
    colors: PydanticTransBuf
    line_widths: PydanticTransBuf
    cap_style: str
    join_style: str

PydanticPixels

Bases: pydantic.BaseModel

Pydantic model representing pixel visual elements.

Pixels are individual colored points organized into groups.

Source code in src/gsp_pydantic/types/pydantic_types.py
90
91
92
93
94
95
96
97
98
99
class PydanticPixels(BaseModel):
    """Pydantic model representing pixel visual elements.

    Pixels are individual colored points organized into groups.
    """

    uuid: str
    positions: PydanticTransBuf
    colors: PydanticTransBuf
    groups: PydanticGroups

PydanticPoints

Bases: pydantic.BaseModel

Pydantic model representing point visual elements.

Points are circular elements with configurable size and appearance, including face color, edge color, and edge width.

Source code in src/gsp_pydantic/types/pydantic_types.py
102
103
104
105
106
107
108
109
110
111
112
113
114
class PydanticPoints(BaseModel):
    """Pydantic model representing point visual elements.

    Points are circular elements with configurable size and appearance,
    including face color, edge color, and edge width.
    """

    uuid: str
    positions: PydanticTransBuf
    sizes: PydanticTransBuf
    face_colors: PydanticTransBuf
    edge_colors: PydanticTransBuf
    edge_widths: PydanticTransBuf

PydanticScene

Bases: pydantic.BaseModel

Pydantic model representing a complete scene.

Aggregates all scene elements including canvas, viewports, visual elements, transformation matrices, and cameras.

Source code in src/gsp_pydantic/types/pydantic_types.py
207
208
209
210
211
212
213
214
215
216
217
218
class PydanticScene(BaseModel):
    """Pydantic model representing a complete scene.

    Aggregates all scene elements including canvas, viewports, visual elements,
    transformation matrices, and cameras.
    """

    canvas: PydanticCanvas
    viewports: list[PydanticViewport]
    visuals: list[PydanticVisual]
    model_matrices: list[PydanticModelMatrix]
    cameras: list[PydanticCamera]

PydanticSegments

Bases: pydantic.BaseModel

Pydantic model representing line segment visual elements.

Segments are individual line segments with configurable width, color, and cap style.

Source code in src/gsp_pydantic/types/pydantic_types.py
117
118
119
120
121
122
123
124
125
126
127
class PydanticSegments(BaseModel):
    """Pydantic model representing line segment visual elements.

    Segments are individual line segments with configurable width, color, and cap style.
    """

    uuid: str
    positions: PydanticTransBuf
    line_widths: PydanticTransBuf
    cap_style: str
    colors: PydanticTransBuf

PydanticTexts

Bases: pydantic.BaseModel

Pydantic model representing text visual elements.

Text elements with configurable position, font properties, colors, and orientation.

Source code in src/gsp_pydantic/types/pydantic_types.py
130
131
132
133
134
135
136
137
138
139
140
141
142
143
class PydanticTexts(BaseModel):
    """Pydantic model representing text visual elements.

    Text elements with configurable position, font properties, colors, and orientation.
    """

    uuid: str
    positions: PydanticTransBuf
    texts: list[str]
    colors: PydanticTransBuf
    font_sizes: PydanticTransBuf
    anchors: PydanticTransBuf
    angles: PydanticTransBuf
    font_name: str

PydanticTransBuf

Bases: pydantic.BaseModel

Pydantic model for a transform buffer union type.

Can represent either a buffer or a transform chain, discriminated by the type field.

Source code in src/gsp_pydantic/types/pydantic_types.py
37
38
39
40
41
42
43
44
class PydanticTransBuf(BaseModel):
    """Pydantic model for a transform buffer union type.

    Can represent either a buffer or a transform chain, discriminated by the type field.
    """

    type: Literal["buffer", "transform_chain"]
    transBuf: PydanticBuffer | PydanticTransformChain

PydanticTransformChain

Bases: pydantic.BaseModel

Pydantic model representing a chain of transformations.

Contains a dictionary representing the transformation chain configuration.

Source code in src/gsp_pydantic/types/pydantic_types.py
28
29
30
31
32
33
34
class PydanticTransformChain(BaseModel):
    """Pydantic model representing a chain of transformations.

    Contains a dictionary representing the transformation chain configuration.
    """

    transform_chain: dict[str, Any]

PydanticViewport

Bases: pydantic.BaseModel

Pydantic model representing a viewport region.

Defines a rectangular viewing area within the canvas.

Source code in src/gsp_pydantic/types/pydantic_types.py
174
175
176
177
178
179
180
181
182
183
184
class PydanticViewport(BaseModel):
    """Pydantic model representing a viewport region.

    Defines a rectangular viewing area within the canvas.
    """

    uuid: str
    x: int
    y: int
    width: int
    height: int

PydanticVisual

Bases: pydantic.BaseModel

Pydantic model for a visual element union type.

Discriminated union that can represent any of the visual element types, distinguished by the type field.

Source code in src/gsp_pydantic/types/pydantic_types.py
146
147
148
149
150
151
152
153
154
class PydanticVisual(BaseModel):
    """Pydantic model for a visual element union type.

    Discriminated union that can represent any of the visual element types,
    distinguished by the type field.
    """

    type: Literal["markers", "paths", "pixels", "points", "segments", "texts"]
    visual: PydanticMarkers | PydanticPaths | PydanticPixels | PydanticPoints | PydanticSegments | PydanticTexts