Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SDFV: Add web serving capability #1013

Merged
merged 2 commits into from
Jun 2, 2022
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
64 changes: 46 additions & 18 deletions dace/cli/sdfv.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,50 +6,78 @@
import sys
import os
import platform
from typing import Optional, Union
import functools

import dace
import tempfile
import jinja2


def view(sdfg, filename=None):
def partialclass(cls, *args, **kwds):
class NewCls(cls):
__init__ = functools.partialmethod(cls.__init__, *args, **kwds)

return NewCls


def view(sdfg: dace.SDFG, filename: Optional[Union[str, int]] = None):
"""View an sdfg in the system's HTML viewer
:param sdfg: the sdfg to view, either as `dace.SDFG` object or a json string
:param filename: the filename to write the HTML to. If `None`, a temporary file will be created.
:param filename: the filename to write the HTML to. If `None`, a
temporary file will be created. If an integer,
the generated HTML and related sources will be
served using a basic web server on that port,
blocking the current thread.
"""
if type(sdfg) is dace.SDFG:
sdfg = dace.serialize.dumps(sdfg.to_json())

basepath = os.path.join(os.path.dirname(os.path.realpath(dace.__file__)), 'viewer')
template_loader = jinja2.FileSystemLoader(searchpath=os.path.join(basepath, 'templates'))
template_env = jinja2.Environment(loader=template_loader)
template = template_env.get_template('sdfv.html')

html = template.render(sdfg=json.dumps(sdfg), dir=basepath + '/')

if filename is None:
fd, html_filename = tempfile.mkstemp(suffix=".sdfg.html")
elif isinstance(filename, int):
dirname = tempfile.mkdtemp()
html_filename = os.path.join(dirname, "sdfg.html")
fd = None
else:
fd = None
html_filename = filename + ".html"

basepath = os.path.join(os.path.dirname(os.path.realpath(dace.__file__)), 'viewer')
template_loader = jinja2.FileSystemLoader(searchpath=os.path.join(basepath, 'templates'))
template_env = jinja2.Environment(loader=template_loader)
template = template_env.get_template('sdfv.html')

# if we are serving, the base path should just be root
html = template.render(sdfg=json.dumps(sdfg), dir="/" if isinstance(filename, int) else (basepath + '/'))

with open(html_filename, "w") as f:
f.write(html)

print("File saved at %s" % html_filename)

system = platform.system()

if system == 'Windows':
os.system(html_filename)
elif system == 'Darwin':
os.system('open %s' % html_filename)
else:
os.system('xdg-open %s' % html_filename)

if fd is not None:
os.close(fd)

if isinstance(filename, int):
# link in the web resources
os.symlink(os.path.join(basepath, 'webclient'), os.path.join(dirname, 'webclient'))

# start the web server
import http.server
handler = partialclass(http.server.SimpleHTTPRequestHandler, directory=dirname)
httpd = http.server.HTTPServer(('localhost', 8000), handler)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't you want to use the given port here?

httpd.serve_forever()
else:
system = platform.system()

if system == 'Windows':
os.system(html_filename)
elif system == 'Darwin':
os.system('open %s' % html_filename)
else:
os.system('xdg-open %s' % html_filename)


def main():
if len(sys.argv) != 2:
Expand Down