Skip to content

Commit

Permalink
Issues/193 fix all todos in html export (datacontract#203)
Browse files Browse the repository at this point in the history
* Make Examples in Fields work

- we have to have them declared in the model to make them show up at all :)

* Add Definitions in HTML Export

- add examples to the model, so we can render them
- create new tables akin to what we do for the models

* Add examples

* Handle nested fields in HTML Export

We just go one level deep but add an additional set of rows for fields contained in a models field.

* Update CHANGELOG

* Update Tests for breaking and changelog

Now that we include the `example` property in the field there's more things being pointed out, so adjust the tests accordingly

* Handle Model Fields and their nesting through partials

- added jinja partials as dependency
- extracted the model and the nesting handling out to its own partial

* Update definitions

- move them to their opwn partial
- move enum into the content column
- try to highlight the different optional aspects a tad

* Move some more blocks into partials

* Add partials to manifest

* Removew the nested headline

---------

Co-authored-by: jochen <[email protected]>
  • Loading branch information
jpraetorius and jochenchrist authored May 16, 2024
1 parent 96bf6e6 commit 949c7d1
Show file tree
Hide file tree
Showing 17 changed files with 810 additions and 615 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `datacontract import --format jsonschema`: Import from JSON schema (#91)
- `datacontract export --format jsonschema`: Improved export by exporting more additional information
- `datacontract publish`: Publish the data contract to the Data Mesh Manager
- HTML Export: Added support for Service Levels, Definitions, Examples and nested Fields (one level deep)

## [0.10.3] - 2024-05-05

Expand Down
5 changes: 2 additions & 3 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
include datacontract/templates/index.html
include datacontract/templates/datacontract.html
include datacontract/templates/style/output.css
include datacontract/templates/style/output.css
recursive-include datacontract/templates/ **/*.html
4 changes: 4 additions & 0 deletions datacontract/breaking/breaking_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ class BreakingRules:
field_tags_removed = Severity.INFO
field_tags_updated = Severity.INFO

field_example_added = Severity.INFO
field_example_updated = Severity.INFO
field_example_removed = Severity.INFO

# quality Rules
quality_added = Severity.INFO
quality_removed = Severity.WARNING
Expand Down
3 changes: 3 additions & 0 deletions datacontract/export/html_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import pytz
import yaml
import jinja_partials
from jinja2 import Environment, PackageLoader, select_autoescape

from datacontract.model.data_contract_specification import \
Expand All @@ -20,6 +21,8 @@ def to_html(data_contract_spec: DataContractSpecification) -> str:
default_for_string=True,
),
)
# Set up for partials
jinja_partials.register_environment(env)

# Load the required template
# needs to be included in /MANIFEST.in
Expand Down
2 changes: 2 additions & 0 deletions datacontract/model/data_contract_specification.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class Definition(pyd.BaseModel):
pii: bool = None
classification: str = None
tags: List[str] = []
example: str = None


class Field(pyd.BaseModel):
Expand Down Expand Up @@ -86,6 +87,7 @@ class Field(pyd.BaseModel):
items: "Field" = None
precision: int = None
scale: int = None
example: str = None
config: Dict[str, Any] = None


Expand Down
631 changes: 33 additions & 598 deletions datacontract/templates/datacontract.html

Large diffs are not rendered by default.

66 changes: 66 additions & 0 deletions datacontract/templates/partials/datacontract_information.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<div class=" px-4 sm:px-0">
<h1 class="text-base font-semibold leading-6 text-gray-900" id="info">Info</h1>
<p class="text-sm text-gray-500">Information about the data contract</p>
</div>
<div class="mt-2 overflow-hidden shadow sm:rounded-lg bg-white">

<div class="px-4 py-5 sm:px-6">

<dl class="grid grid-cols-1 gap-x-4 gap-y-6 sm:grid-cols-2">
<div class="sm:col-span-1">
<dt class="text-sm font-medium text-gray-500">Title</dt>
<dd class="mt-1 text-sm text-gray-900">{{ datacontract.info.title }}</dd>
</div>

<div class="sm:col-span-1">
<dt class="text-sm font-medium text-gray-500">Version</dt>
<dd class="mt-1 text-sm text-gray-900">{{ datacontract.info.version }}</dd>
</div>

{% if datacontract.info.status %}
<div class="sm:col-span-1">
<dt class="text-sm font-medium text-gray-500">Status</dt>
<dd class="mt-1 text-sm text-gray-900">{{ datacontract.info.status }}</dd>
</div>
{% endif %}

{% if datacontract.info.description %}
<div class="sm:col-span-2">
<dt class="text-sm font-medium text-gray-500">Description</dt>
<dd class="mt-1 text-sm text-gray-900" >
<span class="whitespace-pre-wrap">{{ datacontract.info.description }}</span>
</dd>
</div>
{% endif %}

{% if datacontract.info.owner %}
<div class="sm:col-span-1">
<dt class="text-sm font-medium text-gray-500">Owner</dt>
<dd class="mt-1 text-sm text-gray-900">
<span>{{ datacontract.info.owner }}</span>
</dd>
</div>
{% endif %}

{% if datacontract.info.contact %}
<div class="sm:col-span-1">
<dt class="text-sm font-medium text-gray-500">Contact</dt>
<dd class="mt-1 text-sm text-gray-900">
{% if datacontract.info.contact.name %}
{{ datacontract.info.contact.name }}
{% endif %}
{% if datacontract.info.contact.email %}
<a href="mailto:{{ datacontract.info.contact.email }}" class="text-sky-500 hover:text-gray-700">{{ datacontract.info.contact.email }}</a>
{% endif %}
{% if datacontract.info.contact.url %}
<div>
<a href="{{ datacontract.info.contact.url }}" class="text-sky-500 hover:text-gray-700">{{ datacontract.info.contact.url }}</a>
</div>
{% endif %}
</dd>
</div>
{% endif %}

</dl>
</div>
</div>
253 changes: 253 additions & 0 deletions datacontract/templates/partials/datacontract_servicelevels.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
<div class="px-4 sm:px-0">
<h1 class="text-base font-semibold leading-6 text-gray-900">Service Levels</h1>
<p class="text-sm text-gray-500">Service levels of the data contract</p>
</div>
<div class="mt-2 overflow-hidden shadow sm:rounded-lg bg-white">
<div class="px-4 py-5 sm:px-6">
<dl class="grid grid-cols-1 gap-x-4 gap-y-6 divide-y">
{% if datacontract.servicelevels.availability %}
<div class="grid sm:grid-cols-2" >
<h2 class="sm:col-span-2 mt-2 text-base font-semibold leading-6 text-gray-900" id="availability">
Availability
</h2>
{% if datacontract.servicelevels.availability.description %}
<div class="sm:col-span-1">
<dt class="text-sm font-medium text-gray-500">Description</dt>
<dd class="mt-1 text-sm text-gray-900">
<span class="whitespace-pre-wrap">{{ datacontract.servicelevels.availability.description }}</span>
</dd>
</div>
{% endif %}
{% if datacontract.servicelevels.availability.percentage %}
<div class="sm:col-span-1">
<dt class="text-sm font-medium text-gray-500">Percentage</dt>
<dd class="mt-1 text-sm text-gray-900">
<span class="whitespace-pre-wrap">{{ datacontract.servicelevels.availability.percentage }}</span>
</dd>
</div>
{% endif %}
</div>
{% endif %}
{% if datacontract.servicelevels.retention %}
<div class="grid sm:grid-cols-2" >
<h2 class="sm:col-span-2 mt-2 text-base font-semibold leading-6 text-gray-900" id="retention">
Retention
</h2>
{% if datacontract.servicelevels.retention.description %}
<div class="sm:col-span-1">
<dt class="text-sm font-medium text-gray-500">Description</dt>
<dd class="mt-1 text-sm text-gray-900">
<span class="whitespace-pre-wrap">{{ datacontract.servicelevels.retention.description }}</span>
</dd>
</div>
{% endif %}
{% if datacontract.servicelevels.retention.period %}
<div class="sm:col-span-1">
<dt class="text-sm font-medium text-gray-500">Period</dt>
<dd class="mt-1 text-sm text-gray-900">
<span class="whitespace-pre-wrap">{{ datacontract.servicelevels.retention.period }}</span>
</dd>
</div>
{% endif %}
{% if datacontract.servicelevels.retention.unlimited %}
<div class="sm:col-span-1">
<dt class="text-sm font-medium text-gray-500">Unlimited</dt>
<dd class="mt-1 text-sm text-gray-900">
<span class="whitespace-pre-wrap font-mono">{{ datacontract.servicelevels.retention.unlimited }}</span>
</dd>
</div>
{% endif %}
</div>
{% endif %}
{% if datacontract.servicelevels.latency %}
<div class="grid sm:grid-cols-2" >
<h2 class="sm:col-span-2 mt-2 text-base font-semibold leading-6 text-gray-900" id="latency">
Latency
</h2>
{% if datacontract.servicelevels.latency.description %}
<div class="sm:col-span-1">
<dt class="text-sm font-medium text-gray-500">Description</dt>
<dd class="mt-1 text-sm text-gray-900">
<span class="whitespace-pre-wrap">{{ datacontract.servicelevels.latency.description }}</span>
</dd>
</div>
{% endif %}
{% if datacontract.servicelevels.latency.threshold %}
<div class="sm:col-span-1">
<dt class="text-sm font-medium text-gray-500">Threshold</dt>
<dd class="mt-1 text-sm text-gray-900">
<span class="whitespace-pre-wrap">{{ datacontract.servicelevels.latency.threshold }}</span>
</dd>
</div>
{% endif %}
{% if datacontract.servicelevels.latency.sourceTimestampField %}
<div class="sm:col-span-1">
<dt class="text-sm font-medium text-gray-500">Source Timestamp field</dt>
<dd class="mt-1 text-sm text-gray-900">
<span class="whitespace-pre-wrap font-mono">{{ datacontract.servicelevels.latency.sourceTimestampField
}}</span>
</dd>
</div>
{% endif %}
{% if datacontract.servicelevels.latency.processedTimestampField %}
<div class="sm:col-span-1">
<dt class="text-sm font-medium text-gray-500">Processed Timestamp field</dt>
<dd class="mt-1 text-sm text-gray-900">
<span class="whitespace-pre-wrap font-mono">{{ datacontract.servicelevels.latency.processedTimestampField
}}</span>
</dd>
</div>
{% endif %}
</div>
{% endif %}
{% if datacontract.servicelevels.freshness %}
<div class="grid sm:grid-cols-2" >
<h2 class="sm:col-span-2 mt-2 text-base font-semibold leading-6 text-gray-900" id="freshness">
Freshness
</h2>
{% if datacontract.servicelevels.freshness.description %}
<div class="sm:col-span-1">
<dt class="text-sm font-medium text-gray-500">Description</dt>
<dd class="mt-1 text-sm text-gray-900">
<span class="whitespace-pre-wrap">{{ datacontract.servicelevels.freshness.description }}</span>
</dd>
</div>
{% endif %}
{% if datacontract.servicelevels.freshness.threshold %}
<div class="sm:col-span-1">
<dt class="text-sm font-medium text-gray-500">Threshold</dt>
<dd class="mt-1 text-sm text-gray-900">
<span class="whitespace-pre-wrap">{{ datacontract.servicelevels.freshness.threshold }}</span>
</dd>
</div>
{% endif %}
{% if datacontract.servicelevels.freshness.timestampField %}
<div class="sm:col-span-1">
<dt class="text-sm font-medium text-gray-500">Timestamp field</dt>
<dd class="mt-1 text-sm text-gray-900">
<span class="whitespace-pre-wrap font-mono">{{ datacontract.servicelevels.freshness.timestampField }}</span>
</dd>
</div>
{% endif %}
</div>
{% endif %}
{% if datacontract.servicelevels.frequency %}
<div class="grid sm:grid-cols-2" >
<h2 class="sm:col-span-2 mt-2 text-base font-semibold leading-6 text-gray-900" id="frequency">
Frequency
</h2>
{% if datacontract.servicelevels.frequency.description %}
<div class="sm:col-span-1">
<dt class="text-sm font-medium text-gray-500">Description</dt>
<dd class="mt-1 text-sm text-gray-900">
<span class="whitespace-pre-wrap">{{ datacontract.servicelevels.frequency.description }}</span>
</dd>
</div>
{% endif %}
{% if datacontract.servicelevels.frequency.type %}
<div class="sm:col-span-1">
<dt class="text-sm font-medium text-gray-500">Type</dt>
<dd class="mt-1 text-sm text-gray-900">
<span class="whitespace-pre-wrap">{{ datacontract.servicelevels.frequency.type }}</span>
</dd>
</div>
{% endif %}
{% if datacontract.servicelevels.frequency.interval %}
<div class="sm:col-span-1">
<dt class="text-sm font-medium text-gray-500">Interval</dt>
<dd class="mt-1 text-sm text-gray-900">
<span class="whitespace-pre-wrap">{{ datacontract.servicelevels.frequency.interval }}</span>
</dd>
</div>
{% endif %}
{% if datacontract.servicelevels.frequency.cron %}
<div class="sm:col-span-1">
<dt class="text-sm font-medium text-gray-500">Cron</dt>
<dd class="mt-1 text-sm text-gray-900">
<span class="whitespace-pre-wrap font-mono">{{ datacontract.servicelevels.frequency.cron }}</span>
</dd>
</div>
{% endif %}
</div>
{% endif %}
{% if datacontract.servicelevels.support %}
<div class="grid sm:grid-cols-2" >
<h2 class="sm:col-span-2 mt-2 text-base font-semibold leading-6 text-gray-900" id="support">
Support
</h2>
{% if datacontract.servicelevels.support.description %}
<div class="sm:col-span-1">
<dt class="text-sm font-medium text-gray-500">Description</dt>
<dd class="mt-1 text-sm text-gray-900">
<span class="whitespace-pre-wrap">{{ datacontract.servicelevels.support.description }}</span>
</dd>
</div>
{% endif %}
{% if datacontract.servicelevels.support.time %}
<div class="sm:col-span-1">
<dt class="text-sm font-medium text-gray-500">Time</dt>
<dd class="mt-1 text-sm text-gray-900">
<span class="whitespace-pre-wrap">{{ datacontract.servicelevels.support.time }}</span>
</dd>
</div>
{% endif %}
{% if datacontract.servicelevels.support.responseTime %}
<div class="sm:col-span-1">
<dt class="text-sm font-medium text-gray-500">Response Time</dt>
<dd class="mt-1 text-sm text-gray-900">
<span class="whitespace-pre-wrap">{{ datacontract.servicelevels.support.responseTime }}</span>
</dd>
</div>
{% endif %}
</div>
{% endif %}
{% if datacontract.servicelevels.backup %}
<div class="grid sm:grid-cols-2" >
<h2 class="sm:col-span-2 mt-2 text-base font-semibold leading-6 text-gray-900" id="backup">
Backup
</h2>
{% if datacontract.servicelevels.backup.description %}
<div class="sm:col-span-1">
<dt class="text-sm font-medium text-gray-500">Description</dt>
<dd class="mt-1 text-sm text-gray-900">
<span class="whitespace-pre-wrap">{{ datacontract.servicelevels.backup.description }}</span>
</dd>
</div>
{% endif %}
{% if datacontract.servicelevels.backup.internal %}
<div class="sm:col-span-1">
<dt class="text-sm font-medium text-gray-500">Interval</dt>
<dd class="mt-1 text-sm text-gray-900">
<span class="whitespace-pre-wrap">{{ datacontract.servicelevels.backup.interval }}</span>
</dd>
</div>
{% endif %}
{% if datacontract.servicelevels.backup.cron %}
<div class="sm:col-span-1">
<dt class="text-sm font-medium text-gray-500">Cron</dt>
<dd class="mt-1 text-sm text-gray-900">
<span class="whitespace-pre-wrap font-mono">{{ datacontract.servicelevels.backup.cron }}</span>
</dd>
</div>
{% endif %}
{% if datacontract.servicelevels.backup.recoveryTime %}
<div class="sm:col-span-1">
<dt class="text-sm font-medium text-gray-500">Recovery Time</dt>
<dd class="mt-1 text-sm text-gray-900">
<span class="whitespace-pre-wrap">{{ datacontract.servicelevels.backup.recoveryTime }}</span>
</dd>
</div>
{% endif %}
{% if datacontract.servicelevels.backup.recoveryPoint %}
<div class="sm:col-span-1">
<dt class="text-sm font-medium text-gray-500">Recovery Point</dt>
<dd class="mt-1 text-sm text-gray-900">
<span class="whitespace-pre-wrap">{{ datacontract.servicelevels.backup.recoveryPoint }}</span>
</dd>
</div>
{% endif %}
</div>
{% endif %}
</dl>
</div>
</div>
Loading

0 comments on commit 949c7d1

Please sign in to comment.