Python API

Strata’s engine lives in strata.project and has no FreeCAD or Qt dependency: it can run in FreeCAD’s Python console, in freecadcmd, or in plain Python (it needs Git). The examples in Automate with Python are tested and are the best place to start.

from strata.project import Project

project = Project.locate("C:/cad/Gearbox/Gearbox.FCStd")   # None if not in a project
project.create_version("V3", "Released for tooling")
for entry in project.history()[:5]:
    print(entry.author, entry.title)

Revision arguments (rev, rev_a, rev_b, from_rev) are commit ids such as entry.sha or version.sha. For the latest state of a workspace use project.repo.rev_parse("refs/heads/<workspace>"); project.head() is the latest state of the current one. merge_plan is the exception: it takes a workspace name. Document paths (doc, docs) are relative to the project folder with forward slashes, for example Parts/Bracket.FCStd; project.rel(path) converts an absolute path.

Opening and creating projects

Project.locate(path)

The project containing path (a file or folder), searching upwards; None if there is none.

Project.open(root)

The project at root (cached per folder).

Project.create(root, user=None, email=None)

Turn on version control for root and record Start. Returns the existing project if there already is one.

Project.join(url, root, user=None, email=None)

Copy a shared project from url into root (new or empty) with its full history and write out its documents.

Attributes: root (folder), name (folder name), dir (the .strata folder), repo (low-level strata.gitcore.Repo).

Recording and history

record(docs=None, kind="save", title=None, body="")

Record the files on disk as a history entry of the current workspace. docs limits it to some documents (default: all in the folder). The title is generated from the changes unless given. Returns the commit id, or None if nothing changed.

history(workspace=None, limit=500)

HistoryEntry list for a workspace (default: current), newest first.

documents(rev=None)

Documents in the project at rev (default: latest).

documents_on_disk()

.FCStd files currently in the folder.

export_document(rev, doc, dest_dir=None)

Write doc as it was at rev to dest_dir (default .strata/previews/…​) and return its path.

HistoryEntry: sha, title, body, kind (start, save, workspace, restore, merge), author, time (Unix time), docs, parents, versions (names of versions at this entry).

Versions

versions()

All versions, newest first, as Version(name, description, sha, ref, author, time, workspace).

suggest_version_name()

The next free Vn.

create_version(name, description="", rev=None)

Create a version of rev, or of the current state (recorded first) if rev is None. Names must be unique.

Workspaces

current_workspace()

Name of the current workspace (main for Main).

workspaces()

Workspace(name, head, current, remote_only) list; .display is the readable name.

create_workspace(name, from_rev=None, description="", switch=True)

Create a workspace from from_rev (default: latest) and switch to it. Returns (name, changed_docs).

switch_workspace(name)

Record, then switch. Returns the documents rewritten on disk.

delete_workspace(name)

Delete a workspace other than Main and the current one. Versions are kept.

Restore, compare and merge

restore(rev, docs=None)

Bring the current workspace back to rev, completely or only docs, as a new history entry. Returns the documents rewritten on disk.

diff(rev_a, rev_b)

{doc: DocDiff} for every document that differs (see strata.docdiff).

merge_plan(source)

Analyse merging workspace source (or a full ref) into the current one: MergePlan(take_theirs, ours_only, conflicts, auto_merge, unchanged, fast_forward, …​). take_theirs: changed only in the source; ours_only: changed only in the target; conflicts: changed in both; auto_merge: {doc: side} changed in both where side ("ours" or "theirs") only edited the document’s properties.

merge_decisions(plan, strategy="merge", resolutions=None)

What merge would do: {doc: "ours" | "theirs" | "both" | "merged" | None}; None means a choice is needed.

merge(plan, resolutions=None, strategy="merge")

Perform it. strategy is "merge" (Merge changes), "keep" (Keep target) or "replace" (Replace with source). resolutions overrides per document with "ours", "theirs", "both" (keep a copy) or "merged" (combine model and properties). Raises StrataError if a conflict is left without a choice. Returns the documents rewritten on disk.

can_undo_merge()

True if the latest entry is a merge that has not been synced.

undo_merge()

Return to the state before that merge; the merge leaves history. Returns the documents rewritten on disk.

document_properties(doc, rev=None)

{"Part number", "Description", "Company", custom…​} of a document, on disk or at rev.

Releases

release(version, document, part_number, revision=None, description="", approval=False)

Release one document of a Version. The revision defaults to the next free one. With approval=True the release is created as Pending. A rejected revision, or an obsolete one marked re-releasable, can be released again as a new attempt.

set_release_state(release, state, comment="", reusable=False)

"Released" (approve), "Rejected" or "Obsolete", with a comment. reusable=True with "Obsolete" marks the revision as re-releasable.

releases()

Release(part_number, revision, description, state, sha, version, document, author, time, approver, attempt, reusable, comment) list, one per release attempt; for a revision released more than once, the attempt with the highest number counts.

revision_history(part_number)

Every attempt of every revision of a part number, newest first.

next_revision(part_number)

The next free revision in the project’s revision scheme.

strata.project.next_revision(existing, scheme="letters") computes the same from a list of labels; REVISION_SCHEMES lists the schemes ("letters", "numeric").

Sharing

remote_url()

The shared location, or None.

set_remote(url)

Set the shared location. A local or network folder is prepared automatically.

sync()

Record, fetch, fast-forward or merge, and push. Returns SyncResult(pushed, pulled, merged, needs_merge, changed_docs). Workspaces in needs_merge changed on both sides in the same documents; merge them with merge_plan("refs/remotes/origin/<name>").

Settings

settings() returns the project settings (record_on_save, track_binary, revision_scheme); save_settings({…​}) updates them. project.repo.set_identity(name, email) sets your name and email for this project.

strata.docdiff

DocDiff describes how one document changed:

status

"added", "removed", "modified" or "unchanged"

added, removed

lists of (name, label, type)

modified

list of ObjChange(name, label, type, props, geometry, appearance, renamed_from); props is a list of PropChange(name, old, new) with readable values such as "12 mm"

document_props

changes to the document’s own properties

docdiff.summarize(diff) returns the one-line description used for history titles. docdiff.diff_documents(old_xml, new_xml, …​) compares two Document.xml contents directly.

strata.fc (inside FreeCAD)

fc.project_for(doc), fc.active_project()

The project of a FreeCAD document, or of the active one.

fc.open_preview(project, rev, doc, label)

Open a read-only copy of doc at rev, labelled Name @ label.

fc.compare_overlay(project, rev_a, rev_b, doc, label_a, label_b)

Create the 3D comparison document and return the volume summary.

fc.reload(project, docs)

Re-open documents after their files changed on disk.

fc.set_document_properties(project, {doc: {column: value}})

Write part number, description, company and custom properties into documents, save them and record one history entry. An empty custom value removes that property.

fc.export_revision(project, rev, doc, folder, basename)

Write doc as recorded at rev to <basename>.FCStd and, if it has solids, <basename>.step. Returns the paths.

Errors

strata.project.StrataError

a request that cannot be done, with a message meant for users, for example A version named 'V1' already exists.

strata.gitcore.GitError

Git reported an error, for example an unreachable shared location.

strata.gitcore.GitMissing

Git is not installed.