API reference
The distribution installs as vsdxkit but keeps the vsdx import
namespace.
VisioFile
- class vsdx.vsdxfile.VisioFile(filename: str, debug: bool = False, limits: PackageLimits | None = None, limits_path: str | None = None)
Represents a vsdx file
- Parameters:
filename (str) – filename the
VisioFilewas created frompages (list of
Page) – a list of pages in the VisioFilemaster_pages (list of
Page) – a list of master pages in the VisioFile
- __exit__(exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None) None
- __init__(filename: str, debug: bool = False, limits: PackageLimits | None = None, limits_path: str | None = None) None
VisioFile constructor
- Parameters:
filename (str) – the vsdx file to load and create the VisioFile object from
debug (bool, default to False) – enable/disable debugging
limits (PackageLimits, optional) – package expansion caps; the defaults suit untrusted documents
limits_path (str, optional) – JSON file with the same keys as the PackageLimits fields
- add_page(name: str | None = None) Page
Add a new page at the end of the VisioFile
- Parameters:
name (str, optional) – The name of the new page
- Returns:
Page object representing the new page
- add_page_at(index: int, name: str | None = None) Page
Add a new page at the specified index of the VisioFile
- Parameters:
index (int) – zero-based index where the new page will be placed
name (str, optional) – The name of the new page
- Returns:
Pageobject representing the new page
- copy_page(page: Page, *, index: int | PagePosition = PagePosition.AFTER, name: str | None = None) Page
Copy an existing page and insert in VisioFile
- Parameters:
page (Page) – the page to copy
index (int | PagePosition) – the specific int or relation PagePosition location for new page
name (str) – name of new page (note this may be altered if name already exists)
- Returns:
the newly created page
- create_shape(page: Page, palette_name: str, x: float, y: float, w: float | None = None, h: float | None = None, text: str | None = None) Shape
Create a new shape on a page from the extended shape palette.
Palette shapes are deliberately masterless, so creation needs no master-import and works on any document. Reuses copy_shape and the existing position/size setters (no second copy or id-rewrite path).
- Parameters:
page – destination page
palette_name – sentinel name, e.g. ‘PALETTE_PROCESS’, ‘PALETTE_DECISION’, ‘PALETTE_START_END’, ‘PALETTE_PARALLELOGRAM’, ‘PALETTE_DATABASE’
y (x,) – centre position of the new shape
h (w,) – optional width/height overrides
text – label text; the palette sentinel name is cleared when None
- Returns:
the new Shape
- get_page_by_name(name: str) Page | None
Get page from VisioFile with matching name
- Parameters:
name (str) – The name of the required page
- Returns:
Pageobject representing the page (or None if not found)
- jinja_render_vsdx(context: dict[str, object]) None
Transform a template VisioFile object using the Jinja language The method updates the VisioFile object loaded from the template file, so does not return any value Note: vsdx specific extensions are available such as {% for item in list %} statements with no {% endfor %}
- Parameters:
context (dict) – A dictionary containing values that can be accessed by the Jinja processor
- Returns:
None
- remove_page_by_index(index: int) None
Remove zero-based nth page from VisioFile object
- Parameters:
index (int) – Zero-based index of the page
- Returns:
None
- remove_page_by_name(page_name: str) None
Remove first page from VisioFile object that matches the page_name
- Parameters:
page_name (str) – page of page to delete
- Returns:
None
- save_vsdx(new_filename: str | None = None) None
save the VisioFile object as new vsdx file
- Parameters:
new_filename (str) – path to save vsdx file. A .vsdx or .vsdm extension must match the package’s own kind; any other name gets the matching extension appended. Omit it to save over the source file, which is checked the same way but never renamed.
- Raises:
ValueError – if the extension contradicts the package kind
Page and PagePosition
- class vsdx.pages.Page(xml: ET.ElementTree[ET.Element], filename: str, page_name: str, page_id: str, rel_id: str, vis: VisioFile)
Represents a page or a master page in a vsdx file
- Parameters:
vis (
VisioFile) – the VisioFile object the page belongs toname (str) – the name of the page
connects (List of
Connect) – a list of Connect objects in the page
- add_shape_to_lane(shape: Shape, lane: Shape) None
Move a shape so its centre lies within a CFF swimlane’s geometric band.
- add_swimlane(label: str | None = None) Shape
Add a swimlane to this page’s CFF Container by cloning its top lane.
- Returns:
the new lane Shape
- property child_shapes: list[Shape]
Return list of Shape objects at top level of VisioFile.Page
- Returns:
list of Shape objects
- Return type:
List[Shape]
- connect_shapes(from_shape: Shape, to_shape: Shape, route: str = 'dynamic', from_cp: int = 0, to_cp: int = 0) Shape
Create a Visio-faithful dynamic connector between two shapes on this page.
route: ‘dynamic’ (shape glue, default), ‘point’ (connection-point glue using from_cp/to_cp 0-based connection point indexes), optionally with routing behaviour ‘straight’, ‘rightangle’ or ‘curved’ - e.g. route=’straight’ or route=’point|curved’.
- Returns:
the new connector Shape
- Return type:
- delete_shape(shape: Shape) None
Delete a shape from this page, removing any incident connectors.
A group takes its children with it, so connectors glued to a child and records naming one are removed alongside the group’s own. Connectors are deleted first (including their Connect records), then the shape.
- Raises:
ValueError – if the shape is not on this page
Shape, Cell and DataProperty
- class vsdx.shapes.Shape(xml: Element, parent: Page | Shape, page: Page)
Represents a single shape, or a group shape containing other shapes
- property bounds: tuple[float, float, float, float]
- cell_value(name: str) str | None
- property center_x_y: tuple[float | None, float | None]
- property child_shapes: list[Shape]
Get child/sub shapes contained by a Shape
- Returns:
list of Shape objects
- Return type:
List[Shape]
- property connected_shapes: list[Shape]
Shapes at the far end of this shape’s connector records.
Connect records can reference a shape that is not on this page (for example a connector record left behind by a deleted shape), so lookups that resolve to nothing are skipped rather than held as None.
- property connects: list[Connect]
Connect items linking this shape to others.
The annotation quotes
Connectsotyping.get_type_hintsstays runtime-resolvable while avoiding an import cycle withvsdx.connectors(resolved lazily by the type checker).
- copy(page: Page | None = None) Shape
Copy this Shape to the specified destination Page, and return the copy.
If the destination page is not specified, the Shape is copied to its containing Page.
- Parameters:
page (
Page(Optional)) – The page where the new Shape will be placed. If not specified, the copy will be placed in the original shape’s page.- Returns:
Shapethe new copy of shape
- property data_properties: dict[str, DataProperty]
Get data properties of the shape - which labels, names, and values returns a dictionary of DataProperty objects indexed by property label
The result is cached against this shape’s own
Propertyrows, so adding, removing or replacing one is picked up on the next read. A row edited in place is not: the cache is keyed on row identity, so renaming a property’sLabelleaves the dictionary keyed under the old label until some row is added or removed. One limitation remains, over inherited properties:A property inherited from a master is resolved when this shape is first read. Editing the master afterwards is not reflected here: the cache key covers this shape’s own rows, not the master’s, and this shape holds the master it resolved for as long as it lives.
Setting
DataProperty.valueon an inherited property is safe: the property is marked inherited, so writing to it creates an override row on this shape and leaves the master alone.DataProperty.set_attribute()andDataProperty.remove_attribute()do not yet do this, and still write an inherited property’s cells in the master.- Returns:
Dict[str, DataProperty]
- property fill_color: str | None
- find_replace(old: str, new: str) None
- property geometry: Geometry | None
This shape’s Geometry section, merged with the master’s, or
None.Built on first read and then held for as long as this Shape object lives, so
shape.geometrytwice gives the same object and a row written through one read is seen by the next.Building it resolves the shape’s master, which is why it is deferred: walking a page for ids or text mints a Shape per element and touches no geometry at all.
Only the building is deferred. Which section it reads is decided when the Shape is built, as
cellsdecides which of that section’s rows it lists, so the two stay in step: a section added to or removed from the XML afterwards is seen by neither until the shape is read again.
- get_or_create_cell(name: str, v: str | None = None, f: str | None = None) Cell
Set or create a named cell on this shape.
Existing cells have their V/F attributes updated in place. New cells are inserted after the last direct Cell child so the shape keeps the schema ordering (cells ahead of Text/Sections).
- Parameters:
name – cell name (N attribute), e.g. ‘PinX’
v – value to set on the V attribute (optional)
f – formula to set on the F attribute (optional)
- Returns:
the Cell object
- property height: float | None
- property line_color: str | None
- property line_weight: float | None
- move(x_delta: float, y_delta: float) None
- remove() None
Remove this shape from its page or group.
Deprecated in favour of
Page.delete_shape(), which this now calls: it is the single path that also deletes the connectors glued to the shape and theirConnectrecords. Detaching the element alone left orphan connectors and dangling records behind, and Visio repairs such a package on open. It also raisedValueErrorfor a shape inside a group, whose XML is held by the group’sShapescontainer rather than by the group element the parent Shape wraps.
- shape_name: str | None
- property text: str
- property text_color: str | None
Get text color of shape - returns only first color attribute if there are many
- property width: float | None
- property x: float | None
- property y: float | None
- class vsdx.shapes.Cell(xml: Element, shape: Shape)
Represents a Cell element in a vsdx xml file
- property formula: str | None
- property func: str | None
- property name: str | None
- property value: str | None
- class vsdx.shapes.DataProperty(*, xml: Element, shape: Shape)
Represents a single Data Property item associated with a Shape object
A property a shape inherits from its master is handed out marked
inherited. Settingvalueon one materialises an override row on the instance rather than writing to the master page’s XML.- get_attribute(name: str, attrib: str) str | None
Get the attribute value of the cell element
- inherited_by(shape: Shape) DataProperty
This property as an instance of the master sees it, marked inherited.
The copy reads the master’s Row element, so label, type and prompt are already resolved; the first write to
valuecallsmake_local(), which givesshapea row of its own.
- label: str | None
- name: str | None
- prompt: str | None
- remove_attribute(name: str, attrib: str) bool
Remove the attribute from the cell element
- set_attribute(name: str, attrib: str, value: str) bool
Set the attribute value of the cell element
- sort_key: str | None
- property value: str | None
Get the value of the data property, or None when it has none.
Reading is free of side effects: it neither creates the
Valuecell nor tidies aNo Formulaformula, so inspecting a document does not change the bytes it saves.
- value_type: str | None
- xml: Element
Connect and Container
- class vsdx.connectors.Connect(xml: Element | None = None, page: Page | None = None)
Connect class to represent a connection between two Shape objects
- property connector_shape_id: str | None
- property shape_id: str | None
Connection records also expose the raw from_id, to_id, from_rel
and to_rel values from the Visio Connect element. from_id is the
connector shape ID. to_id is the connected shape ID. The relationship
fields identify the source and target cells, such as BeginX, EndX,
PinX or Connections.X1.
- vsdx.connectors.Connect.from_id: str | None
- vsdx.connectors.Connect.to_id: str | None
- vsdx.connectors.Connect.from_rel: str | None
- vsdx.connectors.Connect.to_rel: str | None
- class vsdx.containers.Container(page: Page)
Read/write view over a CFF (swimlane) diagram structure.
Membership is geometric:
lane_of()maps a shape to the lane whose vertical band contains its centre, mirroring Visio’s own containment behaviour. There are no membership cells to write.- add_shape_to_lane(shape: Shape, lane: Shape) None
Assign a shape to a lane by geometry: set the shape’s PinY to the lane’s centre, keeping its PinX. Mirrors Visio’s own behaviour when a shape is dragged into a lane; membership stays geometric.
- add_swimlane(label: str | None = None) Shape
Add a lane above the current top lane by cloning it and shifting one lane pitch. The Swimlane List and CFF Container grow to match.
- Returns:
the new lane Shape
- static find(page: Page) Container | None
Return a Container for the page, or None if this is not a CFF page.
- static lane_band(lane: Shape) tuple[float, float]
(bottom, top) Y band of a lane, from its centre and height.
- static lane_heading(lane: Shape) Shape | None
The lane’s heading sub-shape (child carrying MasterShape).
Package limits
- class vsdx.vsdxfile.PackageLimits(max_members: int = 512, max_member_size: int = 67108864, max_total_uncompressed: int = 268435456, max_ratio: float = 100.0)
Conservative caps applied while loading a package from disk.
The defaults suit documents from unknown sources: a hostile or accidental archive is rejected well before it can exhaust process memory. Even at the caps the loader materialises at most
max_total_uncompressedbytes (256 MiB by default); callers loading larger trusted documents should raise the caps explicitly viaVisioFile(filename, limits=PackageLimits(...))or a JSON file passed aslimits_pathwith the same keys.- classmethod from_json_file(path: str) PackageLimits
Load limits from a JSON object; unusable files are PackageLimitError, not surprises.
- max_member_size: int = 67108864
- max_members: int = 512
- max_ratio: float = 100.0
- max_total_uncompressed: int = 268435456
- class vsdx.vsdxfile.PackageLimitError(reason: str, message: str)
A package violated a load limit: size, member count, ratio, names or duplicates.
reasonis a stable slug (member_size,total_size,member_count,compression_ratio,duplicate_member,member_name,limits_file) so callers can branch by failure mode.