Coloring's picture
feat: add Flow component
176823e
import os
import re
from typing import Callable
import gradio as gr
import modelscope_studio 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") and not demo.startswith("__")
]
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
is_modelscope_studio = os.getenv('MODELSCOPE_ENVIRONMENT') == 'studio'
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 [
filename for filename in os.listdir(os.path.dirname(file_path))
if filename.endswith(".md")
]
if is_modelscope_studio:
self.markdown_files = list(
filter(
lambda x: x.endswith("-zh_CN.md") or
(f"{'.'.join(x.split('.')[:-1])}-zh_CN.md" not in self.
markdown_files), self.markdown_files))
else:
self.markdown_files = list(
filter(lambda x: not x.endswith("-zh_CN.md"),
self.markdown_files))
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,
code_position='left',
prefix='',
suffix=''):
content = self.read_file(f"./demos/{demo_name}.py")
module = self.demo_modules[demo_name]
with gr.Accordion("Show Demo", open=False):
def render_code():
mgr.Markdown(f"""{prefix}
````python
{content}
````
{suffix}""",
header_links=True,
custom_components=custom_components)
if code_position == 'top':
with gr.Row():
with gr.Column():
render_code()
with gr.Row():
if code_position == 'left':
with gr.Column():
render_code()
with gr.Column():
module.demo.render()
if code_position == 'right':
with gr.Column():
render_code()
if code_position == 'bottom':
with gr.Row():
with gr.Column():
render_code()
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,
preview=False)
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"],
code_position=item["code_position"])
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])
tab_name = tab_name.split("-zh_CN")[0]
with gr.TabItem(tab_name, id=tab_name):
self.render_markdown(
markdown_file,
on_tab_link_click=tab_link_click,
components_tabs=components_tabs)
elif (len(self.markdown_files) == 1):
self.render_markdown(self.markdown_files[0],
on_tab_link_click=tab_link_click,
components_tabs=components_tabs)
return demo