Skip to main content

Data Stewardship Wizard: Models

GitHub release (latest SemVer) PyPI LICENSE CII Best Practices Python Version

Models of Data Stewardship Wizard data, their transformations and tooling for scripts

Installation

pip install dsw-models
pip install 'dsw-models[rendering]'  # Markdown helpers of the document context

What is inside

Module Purpose
knowledge_model.flat Compiled knowledge model (entity maps and UUID lists)
knowledge_model.events Knowledge model events
knowledge_model.package .km bundles and their packages
knowledge_model.tree Nested knowledge model for authoring (by hand or by tools)
knowledge_model.graph, .visitor Read-only navigation and visitors
knowledge_model.compiler, .bundle Events → knowledge model
knowledge_model.diff, .squash Knowledge model → events, squashing events
knowledge_model.builder, .validation Fluent building and semantic validation
knowledge_model.migrations Upgrading bundles from older metamodel versions
document_template.metadata, .migrations template.json (local and packaged)
document_context.wire, .graph Document context and its object model for templates
project.* Project events, replies, content, squashing and reports
schemas JSON Schemas of the models

Models use the JSON (camelCase) names of the Data Stewardship Wizard API. They reject unknown keys unless asked otherwise:

import json

from dsw.models.knowledge_model.package import KnowledgeModelBundle
from dsw.models.strictness import UnknownKeys, load

with open('dsw_root_2.8.1.km') as file:
    bundle = load(KnowledgeModelBundle, json.load(file))            # strict
    # load(KnowledgeModelBundle, data, unknown_keys=UnknownKeys.IGNORE) drops unknown keys

data = bundle.to_json_data()  # JSON-compatible data as the server writes it

Knowledge models

Compile a bundle and navigate the result:

from dsw.models.knowledge_model import graph
from dsw.models.knowledge_model.bundle import compile_bundle

km = compile_bundle(bundle)                   # flat.KnowledgeModel of the bundle's package
km_graph = graph.KnowledgeModel(km)

for chapter in km_graph.chapters:
    for question in chapter.questions:
        print(question.title, [tag.name for tag in question.tags])

Every node knows its parent, children, ancestors and resolved references (answer.follow_up_questions, question.required_phase, item_select.list_question …). Reverse lookups answer questions such as "which questions use this integration" (integration.questions).

Walk the knowledge model with a visitor; the most specific visit_<kind> method wins:

from dsw.models.knowledge_model.visitor import SKIP, KnowledgeModelVisitor, walk


class QuestionsWithoutReferences(KnowledgeModelVisitor):

    def __init__(self):
        self.found = []

    def visit_question(self, question):
        if not question.references:
            self.found.append(question)

    def visit_answer(self, answer):
        if answer.label == 'No':
            return SKIP  # do not descend into follow-up questions


visitor = QuestionsWithoutReferences()
walk(km_graph, visitor)

Building and changing knowledge models

from dsw.models.knowledge_model.builder import KnowledgeModelBuilder

builder = KnowledgeModelBuilder()
phase = builder.phase('Before submitting the proposal')
findability = builder.metric('Findability', abbreviation='F')
chapter = builder.chapter('Data description')
question = chapter.options_question('Will you reuse existing data?', required_phase=phase)
question.answer('Yes', metric_measures=[(findability, 1.0, 1.0)]).value_question('Which data?')
question.answer('No')

km = builder.build()
bundle = builder.to_bundle(organization_id='example', km_id='data', version='1.0.0', name='Data')

To change an existing knowledge model, edit a copy of the flat model and let diff produce the events (entities are matched by UUID; the result is verified by replaying it):

from dsw.models.knowledge_model.diff import decompile, diff
from dsw.models.knowledge_model.squash import squash

changed = km.model_copy(deep=True)
changed.entities.chapters[changed.chapter_uuids[0]].title = 'Data'
events = squash(diff(km, changed))   # or decompile(changed) for a new package

validation.validate(km) reports errors, warnings and infos with a location and a hint, e.g. [warning] too-few-answers at Chapter 'Data' › OptionsQuestion 'Reuse?': ….

convert.flat_to_tree() and convert.tree_to_flat() convert to and from the nested model; schemas.knowledge_model_schema('tree', compact=True) gives a smaller schema without titles, defaults and discriminator mappings.

Older bundles

from dsw.models.knowledge_model.migrations import migrate_bundle

bundle = load(KnowledgeModelBundle, migrate_bundle(old_data), unknown_keys=UnknownKeys.IGNORE)

Projects

from dsw.models.project.content import compile_project_events
from dsw.models.project.report import generate_report
from dsw.models.project.walker import walk_replies

content = compile_project_events(events)                  # replies, labels, phase
report = generate_report(km, content.replies, content.phase_uuid)
for item in walk_replies(km_graph, content.replies):     # questions as the questionnaire shows them
    print(item.path, item.question.title, item.reply)

Document templates and contexts

from dsw.models.document_template.metadata import DocumentTemplateMetadata
from dsw.models.document_template.migrations import migrate_template_json

result = migrate_template_json(old_template_json)   # best effort, with warnings
metadata = load(DocumentTemplateMetadata, result.data)

document_context.wire.DocumentContext validates the document context sent to the document worker; document_context.graph.DocumentContext is the object model templates get from ctx|to_context_obj.

JSON Schemas

from dsw.models import schemas

schema = schemas.knowledge_model_bundle_schema(schema_id='https://example.org/km-bundle.json')

Available: knowledge_model_bundle_schema, knowledge_model_schema, template_json_schema, document_context_schema and project_events_schema (JSON Schema 2020-12).

Examples

Runnable scripts — validating a .km bundle, building one, diffing two knowledge models and generating JSON Schemas — are in examples/.

License

This project is licensed under the Apache License v2.0 - see the LICENSE file for more details.

Metadata

Release files for dsw-models 4.35.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dsw-models 4.35.0
File Size Uploaded Provenance
dsw_models-4.35.0.tar.gz 2.3 MB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for dsw-models 4.35.0
File Interpreter ABI Platform
dsw_models-4.35.0-py3-none-any.whl Python 3 none any Details

Total release size: 2.4 MB

Release files / dsw_models-4.35.0.tar.gz

Download URL dsw_models-4.35.0.tar.gz
Size 2.3 MB
Tags Source
SHA-256 checksum
How to use checksums
4c0458b63e981dcde318421ccfb2e5b15d72f803f7bb5b3fda37bc23e46f6882
BLAKE2b-256 checksum
How to use checksums
fe5412877cc79a5ac1f87ae641c246402818dbfb30cb9affd7af8f5028886096
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.

Transparency log

Release files / dsw_models-4.35.0-py3-none-any.whl

Download URL dsw_models-4.35.0-py3-none-any.whl
Size 88.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
248cf1ba0f357c00e173fd2c1960c58d0d99e8911e004f5ae70c3dd33605398b
BLAKE2b-256 checksum
How to use checksums
2f6547a42ef1e471ef13c11758cd30b7febac175fe4c1202c7ecf79b8b0cd780
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.

Transparency log

Security for dsw-models 4.35.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for dsw_models-4.35.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

4.35.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page