visualli-bindings 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- visualli_bindings-0.1.1/PKG-INFO +9 -0
- visualli_bindings-0.1.1/README.md +49 -0
- visualli_bindings-0.1.1/setup.cfg +4 -0
- visualli_bindings-0.1.1/setup.py +12 -0
- visualli_bindings-0.1.1/visualli.py +161 -0
- visualli_bindings-0.1.1/visualli_bindings.egg-info/PKG-INFO +9 -0
- visualli_bindings-0.1.1/visualli_bindings.egg-info/SOURCES.txt +8 -0
- visualli_bindings-0.1.1/visualli_bindings.egg-info/dependency_links.txt +1 -0
- visualli_bindings-0.1.1/visualli_bindings.egg-info/requires.txt +1 -0
- visualli_bindings-0.1.1/visualli_bindings.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Visualli Python Bindings
|
|
2
|
+
|
|
3
|
+
Official [Pydantic](https://docs.pydantic.dev/) models for the Visualli specification. These bindings provide a strict, type-safe implementation of the [JSON Schema](../../visualli.schema.json).
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
### From PyPI (Recommended)
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install visualli-bindings
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### From Source
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pip install .
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
These models are purely for data validation and structure definition. They do not include file parsing logic.
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
from visualli import Layer, Node
|
|
25
|
+
|
|
26
|
+
# Create valid objects
|
|
27
|
+
layer = Layer(
|
|
28
|
+
id="layer-123",
|
|
29
|
+
level=0,
|
|
30
|
+
nodes=[
|
|
31
|
+
Node(
|
|
32
|
+
id="node-1",
|
|
33
|
+
position={"x": 0, "y": 0},
|
|
34
|
+
data={"label": "Central Idea"}
|
|
35
|
+
)
|
|
36
|
+
]
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
print(layer.model_dump_json(indent=2))
|
|
40
|
+
|
|
41
|
+
# Validate raw data
|
|
42
|
+
raw_data = {
|
|
43
|
+
"type": "meta",
|
|
44
|
+
"version": "0.1",
|
|
45
|
+
"title": "My Map"
|
|
46
|
+
}
|
|
47
|
+
from visualli import Meta
|
|
48
|
+
meta = Meta(**raw_data) # Raises ValidationError if invalid
|
|
49
|
+
```
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
setup(
|
|
4
|
+
name="visualli-bindings",
|
|
5
|
+
version="0.1.1",
|
|
6
|
+
description="Official Visualli Pydantic Models",
|
|
7
|
+
py_modules=["visualli"],
|
|
8
|
+
install_requires=[
|
|
9
|
+
"pydantic>=2.0.0",
|
|
10
|
+
],
|
|
11
|
+
python_requires=">=3.11.0",
|
|
12
|
+
)
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from enum import Enum
|
|
5
|
+
from typing import Annotated, Any, Literal
|
|
6
|
+
|
|
7
|
+
from pydantic import AwareDatetime, BaseModel, ConfigDict, Field, RootModel
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Meta(BaseModel):
|
|
11
|
+
model_config = ConfigDict(
|
|
12
|
+
extra="forbid",
|
|
13
|
+
)
|
|
14
|
+
type: Literal["meta"]
|
|
15
|
+
version: Annotated[str, Field(description="Visualli spec version (e.g. '0.1')")]
|
|
16
|
+
title: str
|
|
17
|
+
created: AwareDatetime | None = None
|
|
18
|
+
lastModified: AwareDatetime | None = None
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class Extension(BaseModel):
|
|
22
|
+
type: Literal["extension"]
|
|
23
|
+
id: Annotated[
|
|
24
|
+
str,
|
|
25
|
+
Field(
|
|
26
|
+
description="Unique identifier for the extension (e.g., 'semantic-anchors')"
|
|
27
|
+
),
|
|
28
|
+
]
|
|
29
|
+
data: Annotated[
|
|
30
|
+
list[Any] | None, Field(description="Data payload for the extension")
|
|
31
|
+
] = None
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class Layout(Enum):
|
|
35
|
+
"""
|
|
36
|
+
Spatial arrangement of the layer's nodes on the canvas. 'radial' arranges nodes in a circle around the parent node, 'linear-horizontal' arranges them along a horizontal axis, 'linear-vertical' arranges them along a vertical axis.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
radial = "radial"
|
|
40
|
+
linear_horizontal = "linear-horizontal"
|
|
41
|
+
linear_vertical = "linear-vertical"
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class Position(BaseModel):
|
|
45
|
+
x: float
|
|
46
|
+
y: float
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class Data(BaseModel):
|
|
50
|
+
model_config = ConfigDict(
|
|
51
|
+
extra="forbid",
|
|
52
|
+
)
|
|
53
|
+
label: Annotated[str, Field(description="Label text for the node")]
|
|
54
|
+
summary: Annotated[
|
|
55
|
+
str, Field(description="A short description or summary of the node content")
|
|
56
|
+
]
|
|
57
|
+
color: str | None = None
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class Node(BaseModel):
|
|
61
|
+
id: str
|
|
62
|
+
position: Position
|
|
63
|
+
data: Data
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class Style(Enum):
|
|
67
|
+
dashed = "dashed"
|
|
68
|
+
solid = "solid"
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class Data1(BaseModel):
|
|
72
|
+
model_config = ConfigDict(
|
|
73
|
+
extra="forbid",
|
|
74
|
+
)
|
|
75
|
+
label: str
|
|
76
|
+
style: Style | None = "solid"
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class Connection(BaseModel):
|
|
80
|
+
id: str
|
|
81
|
+
from_: Annotated[str, Field(alias="from", description="Source Node ID")]
|
|
82
|
+
to: Annotated[str, Field(description="Target Node ID")]
|
|
83
|
+
data: Data1
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class Formation(Enum):
|
|
87
|
+
"""
|
|
88
|
+
Visual arrangement of nodes within the container. Uses the same vocabulary as Layer.layout: 'radial' arranges nodes in a circle, 'linear-horizontal' along a horizontal axis, 'linear-vertical' along a vertical axis.
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
radial = "radial"
|
|
92
|
+
linear_horizontal = "linear-horizontal"
|
|
93
|
+
linear_vertical = "linear-vertical"
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class Style1(Enum):
|
|
97
|
+
"""
|
|
98
|
+
Visual style of the container border
|
|
99
|
+
"""
|
|
100
|
+
|
|
101
|
+
dashed = "dashed"
|
|
102
|
+
none = "none"
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class Data2(BaseModel):
|
|
106
|
+
model_config = ConfigDict(
|
|
107
|
+
extra="forbid",
|
|
108
|
+
)
|
|
109
|
+
label: Annotated[str, Field(description="Container Label")]
|
|
110
|
+
formation: Annotated[
|
|
111
|
+
Formation | None,
|
|
112
|
+
Field(
|
|
113
|
+
description="Visual arrangement of nodes within the container. Uses the same vocabulary as Layer.layout: 'radial' arranges nodes in a circle, 'linear-horizontal' along a horizontal axis, 'linear-vertical' along a vertical axis."
|
|
114
|
+
),
|
|
115
|
+
] = None
|
|
116
|
+
style: Annotated[
|
|
117
|
+
Style1 | None, Field(description="Visual style of the container border")
|
|
118
|
+
] = None
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
class Container(BaseModel):
|
|
122
|
+
id: str
|
|
123
|
+
nodes: Annotated[
|
|
124
|
+
list[str], Field(description="List of Node IDs contained in this group")
|
|
125
|
+
]
|
|
126
|
+
data: Data2
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class Layer(BaseModel):
|
|
130
|
+
type: Literal["layer"]
|
|
131
|
+
id: Annotated[str, Field(description="UUID of the layer")]
|
|
132
|
+
level: Annotated[int, Field(description="Hierarchy level (0 is root)", ge=0)]
|
|
133
|
+
parentLayerId: Annotated[
|
|
134
|
+
str | None, Field(description="UUID of the parent layer")
|
|
135
|
+
] = None
|
|
136
|
+
parentNodeId: Annotated[
|
|
137
|
+
str | None,
|
|
138
|
+
Field(
|
|
139
|
+
description="UUID of the specific node in the parent layer this layer attaches to"
|
|
140
|
+
),
|
|
141
|
+
] = None
|
|
142
|
+
layout: Annotated[
|
|
143
|
+
Layout | None,
|
|
144
|
+
Field(
|
|
145
|
+
description="Spatial arrangement of the layer's nodes on the canvas. 'radial' arranges nodes in a circle around the parent node, 'linear-horizontal' arranges them along a horizontal axis, 'linear-vertical' arranges them along a vertical axis."
|
|
146
|
+
),
|
|
147
|
+
] = None
|
|
148
|
+
nodes: Annotated[list[Node] | None, Field(validate_default=True)] = []
|
|
149
|
+
connections: list[Connection] | None = None
|
|
150
|
+
containers: Annotated[list[Container] | None, Field(validate_default=True)] = []
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
class VisualliSpec011(RootModel[Meta | Extension | Layer]):
|
|
154
|
+
root: Annotated[
|
|
155
|
+
Meta | Extension | Layer,
|
|
156
|
+
Field(
|
|
157
|
+
description="Schema for a single line in a .visualli (JSONL) file. Each line must be one of: Meta, Extension, or Layer.",
|
|
158
|
+
discriminator="type",
|
|
159
|
+
title="Visualli Spec 0.1.1",
|
|
160
|
+
),
|
|
161
|
+
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pydantic>=2.0.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
visualli
|