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

feat: custom server to serve maidr html #109

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions maidr/core/maidr.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
from __future__ import annotations

from typing import Literal

import io
import json
import uuid
from typing import Literal

from htmltools import HTML, HTMLDocument, Tag, tags
from lxml import etree

from matplotlib.figure import Figure

from maidr.core.context_manager import HighlightContextManager
from maidr.core.plot import MaidrPlot
from maidr.util.environment import Environment
from maidr.util.server import MaidrServer


class Maidr:
Expand Down Expand Up @@ -84,7 +84,10 @@ def show(self, renderer: Literal["auto", "ipython", "browser"] = "auto") -> obje
The renderer to use for the HTML preview.
"""
html = self._create_html_tag()
return html.show(renderer)
if Environment.is_interactive_shell():
return html.show(renderer)
else:
return MaidrServer.run_server(html)

def clear(self):
self._plots = []
Expand Down
61 changes: 61 additions & 0 deletions maidr/util/server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import os
import socket
import time
import webbrowser
from http.server import HTTPServer, SimpleHTTPRequestHandler
from socketserver import TCPServer
from threading import Thread
from typing import Any

import requests
from htmltools import Tag


def server_handler(path, port):
class MaidrServerHandler(SimpleHTTPRequestHandler):
def do_GET(self):
return SimpleHTTPRequestHandler.do_GET(self)

def __init__(self, *args: Any, **kwargs: Any):
super().__init__(*args, directory=path, **kwargs)

def log_message(
self, format, *args
): # pyright: ignore[reportMissingParameterType]
pass

with TCPServer(("", port), MaidrServerHandler) as httpd:
httpd.serve_forever()


class MaidrServer:
@staticmethod
def get_local_ip():
return socket.gethostbyname(socket.gethostname())

@staticmethod
def run_server(html: Tag):
ip_address = MaidrServer.get_local_ip()
file_name = str(int(time.time() * 1000)) + ".html"
html.save_html(file_name)

if not MaidrServer.check_server():
th: Thread = Thread(
target=server_handler,
args=(file_name, 6942),
daemon=True,
)
th.start()

url = "http://" + ip_address + ":6942" + "/" + file_name
webbrowser.open(url)

@staticmethod
def check_server(timeout=2):
try:
response = requests.head(
"http://" + MaidrServer.get_local_ip() + ":6942", timeout=timeout
)
return response.status_code == 200
except requests.ConnectionError:
return False