Files
markitdown/app.py
JOUNGWOOK KWON 7b040a4445 Add Streamlit web UI and Docker support
- app.py: Streamlit-based web UI for file-to-markdown conversion
- Dockerfile.ui: Docker image for UI (ffmpeg, ExifTool, port 8501)
- .dockerignore: whitelist app.py for Docker build
- CLAUDE.md: project instructions for Claude Code

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 15:10:41 +09:00

118 lines
3.6 KiB
Python

import io
import tempfile
import os
import streamlit as st
from markitdown import MarkItDown
st.set_page_config(
page_title="MarkItDown",
page_icon="📄",
layout="wide",
)
st.title("📄 MarkItDown")
st.caption("파일을 Markdown으로 변환합니다")
SUPPORTED_EXTENSIONS = [
"pdf", "docx", "pptx", "xlsx", "xls",
"jpg", "jpeg", "png",
"mp3", "wav",
"html", "htm",
"csv", "json", "xml",
"ipynb", "epub", "zip", "msg",
]
# Sidebar
with st.sidebar:
st.header("설정")
show_preview = st.toggle("Markdown 렌더링 미리보기", value=True)
st.divider()
st.markdown("**지원 포맷**")
st.markdown(
"PDF · DOCX · PPTX · XLSX · XLS\n\n"
"JPG · PNG · MP3 · WAV\n\n"
"HTML · CSV · JSON · XML\n\n"
"IPYNB · EPUB · ZIP · MSG"
)
# URL 변환
url_tab, file_tab = st.tabs(["URL 변환", "파일 업로드"])
md = MarkItDown()
with url_tab:
url = st.text_input("URL 입력", placeholder="https://example.com 또는 YouTube URL")
if st.button("변환", key="url_btn", disabled=not url):
with st.spinner("변환 중..."):
try:
result = md.convert(url)
st.session_state["url_result"] = result.text_content
st.session_state["url_filename"] = "output.md"
except Exception as e:
st.error(f"변환 실패: {e}")
if "url_result" in st.session_state:
_content = st.session_state["url_result"]
col1, col2 = st.columns([1, 1]) if show_preview else (st.container(), None)
with col1:
st.subheader("Markdown 원문")
st.code(_content, language="markdown")
if show_preview and col2:
with col2:
st.subheader("미리보기")
st.markdown(_content)
st.download_button(
"⬇️ .md 파일 다운로드",
data=_content,
file_name=st.session_state["url_filename"],
mime="text/markdown",
)
with file_tab:
uploaded = st.file_uploader(
"파일을 끌어다 놓거나 클릭해서 선택하세요",
type=SUPPORTED_EXTENSIONS,
)
if uploaded is not None:
if st.button("변환", key="file_btn"):
with st.spinner("변환 중..."):
try:
suffix = os.path.splitext(uploaded.name)[1]
with tempfile.NamedTemporaryFile(delete=False, suffix=suffix) as tmp:
tmp.write(uploaded.getvalue())
tmp_path = tmp.name
result = md.convert(tmp_path)
os.unlink(tmp_path)
st.session_state["file_result"] = result.text_content
st.session_state["file_filename"] = os.path.splitext(uploaded.name)[0] + ".md"
except Exception as e:
st.error(f"변환 실패: {e}")
if "file_result" in st.session_state:
_content = st.session_state["file_result"]
if show_preview:
col1, col2 = st.columns([1, 1])
with col1:
st.subheader("Markdown 원문")
st.code(_content, language="markdown")
with col2:
st.subheader("미리보기")
st.markdown(_content)
else:
st.subheader("Markdown 원문")
st.code(_content, language="markdown")
st.download_button(
"⬇️ .md 파일 다운로드",
data=_content,
file_name=st.session_state["file_filename"],
mime="text/markdown",
)