justmywyw's picture
Upload folder using huggingface_hub
630cbf4 verified
raw
history blame
4.96 kB
import os
import re
from typing import Callable
import gradio as gr
import modelscope_gradio_components as mgr
from .parse_markdown import parse_markdown
with open(os.path.join(os.path.dirname(__file__), "tab-link.js")) as f:
tab_link_js = f.read()
custom_components = {
"tab-link": {
"props": ["tab", "component-tab"],
"js": tab_link_js
}
}
def remove_formatter(markdown_text):
pattern = r"^---[\s\S]*?---"
replaced_text = re.sub(pattern, "", markdown_text)
return replaced_text
def list_demos(dir_path: str, prefix=''):
result = []
if (not os.path.isdir(dir_path)):
return result
for name in os.listdir(dir_path):
path = os.path.join(dir_path, name)
if os.path.isfile(path):
result.append(prefix + name)
elif os.path.isdir(path):
sub_prefix = prefix + name + '/'
result.extend(list_demos(path, sub_prefix))
return result
def get_demo_modules(file_path: str):
import importlib.util
demos = [
demo for demo in list_demos(
os.path.join(os.path.dirname(file_path), "demos"))
if demo.endswith(".py")
]
demo_modules = {}
for demo in demos:
demo_name = demo.split(".")[0]
spec = importlib.util.spec_from_file_location(
"demo", os.path.join(os.path.dirname(file_path), "demos", demo))
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
demo_modules[demo_name] = module
return demo_modules
class Docs:
def __init__(self, file_path: str, markdown_files: list = None):
self.file_path = file_path
self.demo_modules = get_demo_modules(file_path)
# default current directory
self.markdown_files = markdown_files if markdown_files else [
file_name for file_name in os.listdir(os.path.dirname(file_path))
if file_name.endswith(".md")
]
self.tabs = None
def read_file(self, relative_path: str):
with open(os.path.join(os.path.dirname(self.file_path), relative_path),
"r") as f:
return f.read()
def render_demo(self, demo_name, prefix='', suffix=''):
content = self.read_file(f"./demos/{demo_name}.py")
module = self.demo_modules[demo_name]
with gr.Accordion("Show Demo", open=False):
with gr.Row():
with gr.Column():
mgr.Markdown(f"""
{prefix}
````python
{content}
````
{suffix}
""",
header_links=True,
custom_components=custom_components)
with gr.Column():
module.demo.render()
def render_markdown(self,
markdown_file,
on_tab_link_click: Callable = None,
components_tabs=None):
items = parse_markdown(remove_formatter(self.read_file(markdown_file)),
read_file=self.read_file)
for item in items:
if item["type"] == "text":
md = mgr.Markdown(item["value"],
header_links=True,
custom_components=custom_components)
# 过滤
deps = [dep for dep in [components_tabs, self.tabs] if dep]
if len(deps) > 0:
md.custom(fn=on_tab_link_click, outputs=deps)
elif item["type"] == "demo":
self.render_demo(item["name"],
prefix=item["prefix"],
suffix=item["suffix"])
def render(self, components_tabs=None):
def tab_link_click(data: gr.EventData):
tab: str = data._data["value"].get("tab", '')
component_tab: str = data._data["value"].get("component_tab", '')
if tab and tabs:
return {tabs: gr.update(selected=tab)}
elif components_tabs and component_tab:
return {components_tabs: gr.update(selected=component_tab)}
with gr.Blocks() as demo:
if len(self.markdown_files) > 1:
with gr.Tabs() as tabs:
self.tabs = tabs
for markdown_file in self.markdown_files:
tab_name = ".".join(markdown_file.split(".")[:-1])
with gr.TabItem(tab_name, id=tab_name):
self.render_markdown(
markdown_file,
on_tab_link_click=tab_link_click,
components_tabs=components_tabs)
else:
self.render_markdown(self.markdown_files[0],
on_tab_link_click=tab_link_click,
components_tabs=components_tabs)
return demo