Skip to content

Commit

Permalink
Merge pull request #2 from probabl-ai/more-templates
Browse files Browse the repository at this point in the history
More templates
  • Loading branch information
koaning authored Jun 21, 2024
2 parents 318d7b3 + fe0a18a commit ba6977e
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 8 deletions.
33 changes: 30 additions & 3 deletions mandr/app.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from flask import Flask, Response
from flask import Flask, Response, request
from pathlib import Path
import json
from jinja2 import Template
from .infomander import InfoMander, VIEWS_KEY
from .templates import TemplateRenderer
from rich.console import Console

console = Console()
Expand All @@ -13,6 +14,7 @@
def fetch_mander(*path):
return InfoMander('/'.join(path))


def render_views(*path):
mander = fetch_mander(*path)
view_nav_templ = read_template('partials/views.html')
Expand All @@ -24,10 +26,12 @@ def render_views(*path):
first_name=first_name
)


def render_info(*path):
mander = fetch_mander(*path)
return '<pre class="text-xs">' + json.dumps({k: str(v) for k, v in mander.fetch().items() if not k.startswith("_")}, indent=2) + '</pre>'


def render_logs(*path):
mander = fetch_mander(*path)
view_nav_templ = read_template('partials/logs.html')
Expand All @@ -36,15 +40,18 @@ def render_logs(*path):
first_name=list(mander['_logs'].items())[0][0]
)


def render_artifacts(*path):
mander = fetch_mander(*path)
view_nav_templ = read_template('partials/artifacts.html')
return view_nav_templ.render(artifacts=list(mander['_artifacts'].items()))


def read_template(path):
p = Path(__file__).parent / 'templates' / path
return Template(p.read_text())


def render_top_nav(*args):
nav_temp = read_template('partials/nav-top.html')
path_pairs = []
Expand All @@ -59,19 +66,22 @@ def render_top_nav(*args):
console.log(f'{path_pairs=}')
return nav_temp.render(path_pairs=path_pairs, links_out=links_out)


def render_mid_nav(*args):
nav_temp = read_template('partials/nav-mid.html')
return nav_temp.render(path='/'.join(args))


def render_mander(*args):
p = Path(__file__).parent / 'templates' / 'page.html'
t = Template(p.read_text())
res = render_top_nav(*args)
res += render_mid_nav(*args)
return t.render(body=res)

@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')

@app.route('/', defaults={'path': ''}, methods=['GET', 'POST'])
@app.route('/<path:path>', methods=['GET', 'POST'])
def home(path):
if 'favicon' in path:
return Response('', status=400)
Expand All @@ -87,7 +97,24 @@ def home(path):
return render_logs(*path_parts[1:])
if path_parts[0] == 'artifacts':
return render_artifacts(*path_parts[1:])
if path_parts[0] == 'sketchpad':
return render_sketchpad(*path_parts[1:])
if path_parts[0] == 'render':
return render_template(*path_parts[1:])
return render_mander(*path.split('/'))


def render_sketchpad(*path):
mander = fetch_mander(*path)
children = [f'{m.path}' for m in mander.children()]
return read_template('sketchpad.html').render(children=sorted(children), mander_path=mander.path)


def render_template(*path):
mander = fetch_mander(*path)
template_rendered = TemplateRenderer(mander)
return template_rendered.render(request.form['template'])


if __name__ == '__main__':
app.run(debug=True, reload=True)
5 changes: 3 additions & 2 deletions mandr/infomander.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class InfoMander:
"""Represents a dictionary, on disk, with a path-like structure."""
def __init__(self, path):
# Set local disk paths
self.path = path
self.project_path = Path('.datamander/' + path)
self.cache = Cache(self.project_path / STATS_FOLDER)

Expand All @@ -39,7 +40,7 @@ def __init__(self, path):
def _check_key(self, key):
if key in [ARTIFACTS_KEY, TEMPLATES_KEY, VIEWS_KEY, LOGS_KEY]:
raise ValueError(f'Cannot overwrite {key} key. This is reserved for internal use.')

def add_info(self, key, value, method='overwrite'):
if method == 'overwrite':
self.cache[key] = value
Expand All @@ -62,7 +63,7 @@ def add_artifact(self, key, obj, **metadata):
if not file_location.parent.exists():
file_location.parent.mkdir(parents=True)
dump(obj, file_location)
self._add_to_key(ARTIFACTS_KEY, key, {'path': file_location, **metadata})
self._add_to_key(ARTIFACTS_KEY, key, {'obj': obj, **metadata})

def add_view(self, key, html):
self._check_key(key)
Expand Down
9 changes: 6 additions & 3 deletions mandr/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@


def sklearn_model_repr(pipeline):
print('pipeline', pipeline)
return estimator_html_repr(pipeline)


Expand Down Expand Up @@ -45,6 +46,7 @@ def insert_custom_ui(self, template):
# For each registered element, check if it is there.
for name, func in registry.items():
element_of_interest = f'<{name}'
print('element_of_interest', element_of_interest)
start = template.find(element_of_interest)
end = template[start:].find("/>")
substr = template[start:start + end + 2]
Expand All @@ -53,11 +55,12 @@ def insert_custom_ui(self, template):
params = {k: self.clean_value(v) for k, v in elems}
for k, v in params.items():
if v.startswith('@mander'):
params[k] = self.datamander.get(v)
params[k] = self.mander.get(v)
ui = func(**params)
return template.replace(substr, ui)
template = template.replace(substr, ui)
return template

def render(self, template):
final_template = self.insert_custom_ui(template)
return markdown.markdown(Template(final_template).render(**self.datamander.fetch()))
res = markdown.markdown(Template(final_template).render(**self.mander.fetch()))
return res
46 changes: 46 additions & 0 deletions mandr/templates/sketchpad.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
Template Sketchpad
</title>
<script src="https://cdn.tailwindcss.com?plugins=forms,typography"></script>
<script src="//unpkg.com/alpinejs" defer></script>
<script src="https://cdn.jsdelivr.net/npm/vega@5"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-lite@5"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-embed@6"></script>
<script src="https://cdn.jsdelivr.net/gh/koaning/justcharts/justcharts.js"></script>
<script src="https://unpkg.com/[email protected]" integrity="sha384-ujb1lZYygJmzgSwoxRggbCHcjc0rB2XoQrxeTUQyRjrOnlCoYta87iKBWq3EsdM2" crossorigin="anonymous"></script>
</head>
<body>
<main>
<div class="m-4">
<h1 class="text-4xl font-bold">Template Sketchpad</h1>
<small class="text-gray-400">The template can be edited on the right and will be live updated.</small>
<div class="flex pt-4">
<div class="w-1/2 m-2">
<form name="main" id="template-form">
{% for child in children %}<br/>
<a href="/sketchpad/{{child}}" class='text-sm text-gray-400'>{{child}}</a>
{% endfor %}
<p class="text-md font-bold">Template</p>
<textarea name='template' class="w-full h-64 p-2 bg-gray-100 rounded-md font-mono" placeholder="Enter ManderMarkdown text here"></textarea>
</form>
<button class="btn primary rounded-md bg-gray-100" hx-trigger='click' hx-post='/render/{{mander_path}}' hx-include="#template-form" hx-target="#template-out" >Submit</button>
</div>
<div class="w-1/2 m-2">
<p class="text-md font-bold">Rendered output</p>
<div class="w-full border-dotted border-2 rounded-md">
<article class="prose p-2">
<div id="template-out"></div>
</article>
<br/><br/>
</div>
</div>
</div>
</div>
</main>
</body>
</html>

0 comments on commit ba6977e

Please sign in to comment.