diff --git a/datacontract/templates/partials/datacontract_information.html b/datacontract/templates/partials/datacontract_information.html
new file mode 100644
index 00000000..7134a94e
--- /dev/null
+++ b/datacontract/templates/partials/datacontract_information.html
@@ -0,0 +1,66 @@
+
+
Info
+
Information about the data contract
+
+
+
+
+
+
+
+
- Title
+ - {{ datacontract.info.title }}
+
+
+
+
- Version
+ - {{ datacontract.info.version }}
+
+
+ {% if datacontract.info.status %}
+
+
- Status
+ - {{ datacontract.info.status }}
+
+ {% endif %}
+
+ {% if datacontract.info.description %}
+
+
- Description
+ -
+ {{ datacontract.info.description }}
+
+
+ {% endif %}
+
+ {% if datacontract.info.owner %}
+
+
- Owner
+ -
+ {{ datacontract.info.owner }}
+
+
+ {% endif %}
+
+ {% if datacontract.info.contact %}
+
+
- Contact
+
-
+ {% if datacontract.info.contact.name %}
+ {{ datacontract.info.contact.name }}
+ {% endif %}
+ {% if datacontract.info.contact.email %}
+ {{ datacontract.info.contact.email }}
+ {% endif %}
+ {% if datacontract.info.contact.url %}
+
+ {% endif %}
+
+
+ {% endif %}
+
+
+
+
\ No newline at end of file
diff --git a/datacontract/templates/partials/datacontract_servicelevels.html b/datacontract/templates/partials/datacontract_servicelevels.html
new file mode 100644
index 00000000..fab0579a
--- /dev/null
+++ b/datacontract/templates/partials/datacontract_servicelevels.html
@@ -0,0 +1,253 @@
+
+
Service Levels
+
Service levels of the data contract
+
+
+
+
+ {% if datacontract.servicelevels.availability %}
+
+
+ Availability
+
+ {% if datacontract.servicelevels.availability.description %}
+
+
- Description
+ -
+ {{ datacontract.servicelevels.availability.description }}
+
+
+ {% endif %}
+ {% if datacontract.servicelevels.availability.percentage %}
+
+
- Percentage
+ -
+ {{ datacontract.servicelevels.availability.percentage }}
+
+
+ {% endif %}
+
+ {% endif %}
+ {% if datacontract.servicelevels.retention %}
+
+
+ Retention
+
+ {% if datacontract.servicelevels.retention.description %}
+
+
- Description
+ -
+ {{ datacontract.servicelevels.retention.description }}
+
+
+ {% endif %}
+ {% if datacontract.servicelevels.retention.period %}
+
+
- Period
+ -
+ {{ datacontract.servicelevels.retention.period }}
+
+
+ {% endif %}
+ {% if datacontract.servicelevels.retention.unlimited %}
+
+
- Unlimited
+ -
+ {{ datacontract.servicelevels.retention.unlimited }}
+
+
+ {% endif %}
+
+ {% endif %}
+ {% if datacontract.servicelevels.latency %}
+
+
+ Latency
+
+ {% if datacontract.servicelevels.latency.description %}
+
+
- Description
+ -
+ {{ datacontract.servicelevels.latency.description }}
+
+
+ {% endif %}
+ {% if datacontract.servicelevels.latency.threshold %}
+
+
- Threshold
+ -
+ {{ datacontract.servicelevels.latency.threshold }}
+
+
+ {% endif %}
+ {% if datacontract.servicelevels.latency.sourceTimestampField %}
+
+
- Source Timestamp field
+ -
+ {{ datacontract.servicelevels.latency.sourceTimestampField
+ }}
+
+
+ {% endif %}
+ {% if datacontract.servicelevels.latency.processedTimestampField %}
+
+
- Processed Timestamp field
+ -
+ {{ datacontract.servicelevels.latency.processedTimestampField
+ }}
+
+
+ {% endif %}
+
+ {% endif %}
+ {% if datacontract.servicelevels.freshness %}
+
+
+ Freshness
+
+ {% if datacontract.servicelevels.freshness.description %}
+
+
- Description
+ -
+ {{ datacontract.servicelevels.freshness.description }}
+
+
+ {% endif %}
+ {% if datacontract.servicelevels.freshness.threshold %}
+
+
- Threshold
+ -
+ {{ datacontract.servicelevels.freshness.threshold }}
+
+
+ {% endif %}
+ {% if datacontract.servicelevels.freshness.timestampField %}
+
+
- Timestamp field
+ -
+ {{ datacontract.servicelevels.freshness.timestampField }}
+
+
+ {% endif %}
+
+ {% endif %}
+ {% if datacontract.servicelevels.frequency %}
+
+
+ Frequency
+
+ {% if datacontract.servicelevels.frequency.description %}
+
+
- Description
+ -
+ {{ datacontract.servicelevels.frequency.description }}
+
+
+ {% endif %}
+ {% if datacontract.servicelevels.frequency.type %}
+
+
- Type
+ -
+ {{ datacontract.servicelevels.frequency.type }}
+
+
+ {% endif %}
+ {% if datacontract.servicelevels.frequency.interval %}
+
+
- Interval
+ -
+ {{ datacontract.servicelevels.frequency.interval }}
+
+
+ {% endif %}
+ {% if datacontract.servicelevels.frequency.cron %}
+
+
- Cron
+ -
+ {{ datacontract.servicelevels.frequency.cron }}
+
+
+ {% endif %}
+
+ {% endif %}
+ {% if datacontract.servicelevels.support %}
+
+
+ Support
+
+ {% if datacontract.servicelevels.support.description %}
+
+
- Description
+ -
+ {{ datacontract.servicelevels.support.description }}
+
+
+ {% endif %}
+ {% if datacontract.servicelevels.support.time %}
+
+
- Time
+ -
+ {{ datacontract.servicelevels.support.time }}
+
+
+ {% endif %}
+ {% if datacontract.servicelevels.support.responseTime %}
+
+
- Response Time
+ -
+ {{ datacontract.servicelevels.support.responseTime }}
+
+
+ {% endif %}
+
+ {% endif %}
+ {% if datacontract.servicelevels.backup %}
+
+
+ Backup
+
+ {% if datacontract.servicelevels.backup.description %}
+
+
- Description
+ -
+ {{ datacontract.servicelevels.backup.description }}
+
+
+ {% endif %}
+ {% if datacontract.servicelevels.backup.internal %}
+
+
- Interval
+ -
+ {{ datacontract.servicelevels.backup.interval }}
+
+
+ {% endif %}
+ {% if datacontract.servicelevels.backup.cron %}
+
+
- Cron
+ -
+ {{ datacontract.servicelevels.backup.cron }}
+
+
+ {% endif %}
+ {% if datacontract.servicelevels.backup.recoveryTime %}
+
+
- Recovery Time
+ -
+ {{ datacontract.servicelevels.backup.recoveryTime }}
+
+
+ {% endif %}
+ {% if datacontract.servicelevels.backup.recoveryPoint %}
+
+
- Recovery Point
+ -
+ {{ datacontract.servicelevels.backup.recoveryPoint }}
+
+
+ {% endif %}
+
+ {% endif %}
+
+
+
\ No newline at end of file
diff --git a/datacontract/templates/partials/datacontract_terms.html b/datacontract/templates/partials/datacontract_terms.html
new file mode 100644
index 00000000..2186df38
--- /dev/null
+++ b/datacontract/templates/partials/datacontract_terms.html
@@ -0,0 +1,44 @@
+
+
Terms
+
Terms and conditions of the data contract
+
+
+
+
+
+
+
+
- Usage
+ -
+ {{ datacontract.terms.usage }}
+
+
+
+
+
- Limitations
+ -
+ {{ datacontract.terms.limitations }}
+
+
+
+ {% if datacontract.terms.billing %}
+
+
- Billing
+ -
+ {{ datacontract.terms.billing }}
+
+
+ {% endif %}
+
+ {% if datacontract.terms.noticePeriod %}
+
+
- Notice Period
+ -
+ {{ datacontract.terms.noticePeriod }}
+
+
+ {% endif %}
+
+
+
+
\ No newline at end of file
diff --git a/datacontract/templates/partials/definition.html b/datacontract/templates/partials/definition.html
new file mode 100644
index 00000000..80ecae87
--- /dev/null
+++ b/datacontract/templates/partials/definition.html
@@ -0,0 +1,99 @@
+
+
+
+
+
+
+
+
+
+ {{ definition_name }}
+ {{ definition.domain }}
+ {{ definition.description }}
+ |
+
+
+
+
+
+
+ {% if definition.title %}
+ {{ definition.title }}
+ {% endif %}
+ {{ definition.name }}
+
+ |
+
+
+ {{ definition.type }}
+ {% if definition.format %}
+ {{ definition.format }}
+ {% endif %}
+
+ |
+
+ {% if definition.example %}
+
+ Example: {{ definition.example }}
+
+ {% endif %}
+ {% if definition.tags %}
+
+ Tags:
+ {% for tag in definition.tags %}
+ {{ tag }}
+ {% endfor %}
+
+ {% endif %}
+ {% if definition.enum %}
+
+ Enum:
+ {% for value in definition.enum %}
+ {{ value }}
+ {% endfor %}
+
+ {% endif %}
+
+ {% if definition.minLength %}
+ minLength:{{ definition.minLength }}
+ {% endif %}
+ {% if definition.maxLength %}
+ maxLength:{{ definition.maxLength }}
+ {% endif %}
+ {% if definition.pattern %}
+ pattern:{{ definition.pattern }}
+ {% endif %}
+ {% if definition.precision %}
+ precision:{{ definition.precision }}
+ {% endif %}
+ {% if definition.scale %}
+ scale:{{ definition.scale }}
+ {% endif %}
+ {% if definition.minimum %}
+ minimum:{{ definition.minimum }}
+ {% endif %}
+ {% if definition.exclusiveMinimum %}
+ exclusiveMinimum:{{ definition.exclusiveMinimum }}
+ {% endif %}
+ {% if definition.maximum %}
+ maximum:{{ definition.maximum }}
+ {% endif %}
+ {% if definition.exclusiveMaximum %}
+ exclusiveMaximum:{{ definition.exclusiveMaximum }}
+ {% endif %}
+ {% if definition.classification %}
+ {{ definition.classification }}
+ {% endif %}
+ {% if definition.pii %}
+ PII
+ {% endif %}
+
+ |
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/datacontract/templates/partials/example.html b/datacontract/templates/partials/example.html
new file mode 100644
index 00000000..ce423f5a
--- /dev/null
+++ b/datacontract/templates/partials/example.html
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+ {{ example.model }}
+ {{ example.type }}
+ {{ example.description }}
+ |
+
+
+
+
+
+ {{ example.data }}
+ |
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/datacontract/templates/partials/model_field.html b/datacontract/templates/partials/model_field.html
new file mode 100644
index 00000000..02186383
--- /dev/null
+++ b/datacontract/templates/partials/model_field.html
@@ -0,0 +1,97 @@
+{% if nested %}
+
+
+ {# poor mans approach to indenting things a bit #}
+ {% for i in range(0,level)%}
+
+ {% endfor %}
+
+ ↳
+
+{% else %}
+ |
+
+{% endif %}
+
+ {% if field.title %}
+ {{ field.title }}
+ {% endif %}
+ {{ field_name }}
+
+ |
+
+ {% if field.type %}
+ {{ field.type }}
+ {% endif %}
+ |
+
+ {% if field.description %}
+ {{ field.description }}
+ {% else %}
+ No description
+ {% endif %}
+
+ {% if field.example %}
+
+ Example: {{ field.example }}
+
+ {% endif %}
+
+
+ {% if field.primary %}
+ primary
+ {% endif %}
+ {% if field.required %}
+ required
+ {% endif %}
+ {% if field.unique %}
+ unique
+ {% endif %}
+ {% if field.format %}
+ format:{{ field.format }}
+ {% endif %}
+ {% if field.minLength %}
+ minLength:{{ field.minLength }}
+ {% endif %}
+ {% if field.maxLength %}
+ maxLength:{{ field.maxLength }}
+ {% endif %}
+ {% if field.pattern %}
+ pattern:{{ field.pattern }}
+ {% endif %}
+ {% if field.precision %}
+ precision:{{ field.precision }}
+ {% endif %}
+ {% if field.scale %}
+ scale:{{ field.scale }}
+ {% endif %}
+ {% if field.minimum %}
+ minimum:{{ field.minimum }}
+ {% endif %}
+ {% if field.exclusiveMinimum %}
+ exclusiveMinimum:{{ field.exclusiveMinimum }}
+ {% endif %}
+ {% if field.maximum %}
+ maximum:{{ field.maximum }}
+ {% endif %}
+ {% if field.exclusiveMaximum %}
+ exclusiveMaximum:{{ field.exclusiveMaximum }}
+ {% endif %}
+ {% if field.classification %}
+ {{ field.classification }}
+ {% endif %}
+ {% if field.pii %}
+ PII
+ {% endif %}
+
+ |
+
+
+{% if field.fields %}
+{% for field_name, field in field.fields.items() %}
+ {{ render_partial('partials/model_field.html', nested = True, field_name=field_name, field = field, level = level + 1) }}
+{% endfor %}
+
+
+
+{% endif %}
\ No newline at end of file
diff --git a/datacontract/templates/partials/server.html b/datacontract/templates/partials/server.html
new file mode 100644
index 00000000..aab8fa10
--- /dev/null
+++ b/datacontract/templates/partials/server.html
@@ -0,0 +1,144 @@
+
+
+
+
Server
+ {{server_name}}
+
+
+
+ {% if server.type %}
+
+
+
Type
+ {{server.type}}
+
+
+ {% endif %}
+
+ {% if server.project %}
+
+
+
Project
+ {{server.project}}
+
+
+ {% endif %}
+
+ {% if server.dataset %}
+
+
+
Dataset
+ {{server.dataset}}
+
+
+ {% endif %}
+
+ {% if server.location %}
+
+
+
Location
+ {{server.location}}
+
+
+ {% endif %}
+
+ {% if server.endpointUrl %}
+
+
+
Endpoint URL
+ {{server.endpointUrl}}
+
+
+ {% endif %}
+
+ {% if server.account %}
+
+
+
Account
+ {{server.account}}
+
+
+ {% endif %}
+
+ {% if server.host %}
+
+
+
Host
+ {{server.host}}
+
+
+ {% endif %}
+
+ {% if server.port %}
+
+
+
Port
+ {{server.port}}
+
+
+ {% endif %}
+
+ {% if server.catalog %}
+
+
+
Catalog
+ {{server.catalog}}
+
+
+ {% endif %}
+
+ {% if server.database %}
+
+
+
Database
+ {{server.database}}
+
+
+ {% endif %}
+
+ {% if server.schema_ %}
+
+
+
Schema
+ {{server.schema_}}
+
+
+ {% endif %}
+
+ {% if server.topic %}
+
+
+
Topic
+ {{server.topic}}
+
+
+ {% endif %}
+
+ {% if server.path %}
+
+
+
Path
+ {{server.path}}
+
+
+ {% endif %}
+
+ {% if server.format %}
+
+
+
Format
+ {{server.format}}
+
+
+ {% endif %}
+
+ {% if server.delimiter %}
+
+
+
Delimiter
+ {{server.delimiter}}
+
+
+ {% endif %}
+
+
\ No newline at end of file
diff --git a/datacontract/templates/style/output.css b/datacontract/templates/style/output.css
index 5ffc44d1..56c62617 100644
--- a/datacontract/templates/style/output.css
+++ b/datacontract/templates/style/output.css
@@ -757,6 +757,10 @@ video {
width: 2.5rem;
}
+.w-2 {
+ width: 0.5rem;
+}
+
.w-2\/12 {
width: 16.666667%;
}
@@ -781,6 +785,10 @@ video {
width: 18rem;
}
+.w-9\/12 {
+ width: 75%;
+}
+
.w-full {
width: 100%;
}
@@ -858,11 +866,6 @@ video {
column-gap: 1rem;
}
-.gap-x-6 {
- -moz-column-gap: 1.5rem;
- column-gap: 1.5rem;
-}
-
.gap-y-6 {
row-gap: 1.5rem;
}
@@ -1381,10 +1384,6 @@ video {
flex-direction: row;
}
- .sm\:flex-col {
- flex-direction: column;
- }
-
.sm\:flex-wrap {
flex-wrap: wrap;
}
diff --git a/datacontract/templates/style/tailwind.config.js b/datacontract/templates/style/tailwind.config.js
index 1aa627c6..baf2346c 100644
--- a/datacontract/templates/style/tailwind.config.js
+++ b/datacontract/templates/style/tailwind.config.js
@@ -1,5 +1,5 @@
module.exports = {
- content: ["../datacontract.html", "../index.html"],
+ content: ["../datacontract.html", "../index.html", "../partials/model_field.html", "../partials/definition.html", "../partials/datacontract_information.html", "../partials/datacontract_servicelevels.html", "../partials/datacontract_terms.html", "../partials/example.html"],
theme: { },
plugins: [],
}
\ No newline at end of file
diff --git a/pyproject.toml b/pyproject.toml
index 630ede12..59dffb99 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -41,7 +41,8 @@ dependencies = [
"deltalake~=0.17.0",
"boto3>=1.34.41,<1.34.99",
"botocore>=1.34.41,<1.34.99",
- "jsonschema>=4.22"
+ "jsonschema>=4.22",
+ "jinja_partials >= 0.2.1"
]
[project.optional-dependencies]
diff --git a/tests/test_changelog.py b/tests/test_changelog.py
index 90a8bf32..fce7dccd 100644
--- a/tests/test_changelog.py
+++ b/tests/test_changelog.py
@@ -599,7 +599,7 @@ def test_definition_added():
output = result.stdout
assert result.exit_code == 0
- assert "16 changes: 0 error, 13 warning, 3 info\n" in output
+ assert "17 changes: 0 error, 13 warning, 4 info\n" in output
assert (
r"""warning [field_ref_added] at
./fixtures/breaking/datacontract-definitions-v2.yaml
@@ -705,6 +705,13 @@ def test_definition_added():
added with value: `['my_enum']`"""
in output
)
+ assert (
+ """info [field_example_added] at
+./fixtures/breaking/datacontract-definitions-v2.yaml
+ in models.my_table.fields.my_field.example
+ added with value: `my_example`"""
+ in output
+ )
def test_definition_removed():
@@ -719,7 +726,7 @@ def test_definition_removed():
output = result.stdout
assert result.exit_code == 0
- assert "16 changes: 3 error, 9 warning, 4 info\n" in output
+ assert "17 changes: 3 error, 9 warning, 5 info\n" in output
assert (
r"""warning [field_ref_removed] at
./fixtures/breaking/datacontract-definitions-v1.yaml
@@ -825,6 +832,13 @@ def test_definition_removed():
removed field property"""
in output
)
+ assert (
+ """info [field_example_removed] at
+./fixtures/breaking/datacontract-definitions-v1.yaml
+ in models.my_table.fields.my_field.example
+ removed field property"""
+ in output
+ )
def test_definition_updated():
@@ -839,7 +853,7 @@ def test_definition_updated():
output = result.stdout
assert result.exit_code == 0
- assert "16 changes: 12 error, 1 warning, 3 info\n" in output
+ assert "17 changes: 12 error, 1 warning, 4 info\n" in output
assert (
r"""warning [field_ref_updated] at
./fixtures/breaking/datacontract-definitions-v3.yaml
@@ -946,3 +960,10 @@ def test_definition_updated():
changed from `['my_enum']` to `['my_enum_2']`"""
in output
)
+ assert (
+ """info [field_example_updated] at
+./fixtures/breaking/datacontract-definitions-v3.yaml
+ in models.my_table.fields.my_field.example
+ changed from `my_example` to `my_example_2`"""
+ in output
+ )