はじめに
先日、Microsoftが「MarkItDown」というツールを公開しました。このツールは、あらゆるフォーマットのファイルをマークダウン形式に変換してくれるツールです。
https://github.com/microsoft/markitdown
READMEを見てみると、コマンドラインで動かすことが想定されている。
markitdown path-to-file.pdf > document.md
markitdown path-to-file.pdf -o document.md
cat path-to-file.pdf | markitdown
チームメンバー全員が使い易いように、WEBにファイルをアップロードすればマークダウン形式に変換してくれるアプリを作成してみる。
本題
今回はDockerで環境構築をして、PythonライブラリのFlaskを用いてMarkItDownツールをブラウザで使えるようにしてみたいと思います。
ファイル構造は以下。
.
└── markitdown-app-docker
├── app.py
├── Dockerfile
├── docker-compose.yml
└── uploads/
Flaskで簡易的なアプリケーションを作成
以下のようにPythonライブラリのFlaskを利用して、簡易的なアプリケーションを作成しました。
アップロードしたファイルは一度UPLOAD_FOLDERに保存されます。(<-好み)
アップロードできるファイル拡張子をALLOWED_EXTENSIONSで制限しています。(<-好み)
from flask import Flask, request, render_template_string
import os
import subprocess
from markitdown import MarkItDown
app = Flask(__name__)
# アップロードされたファイルの保存先ディレクトリ
UPLOAD_FOLDER = 'uploads'
ALLOWED_EXTENSIONS = {'txt', 'html', 'docx', 'pdf', 'pptx', 'xlsm', 'csv', 'json', 'xml', 'zip'} # マークダウンに変換したいファイル形式
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
# アップロードされるファイルの拡張子をチェック
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
# ファイルが選択されているかチェック
if 'file' not in request.files:
return 'No file part'
file = request.files['file']
if file.filename == '':
return 'No selected file'
# ファイルを保存
if file and allowed_file(file.filename):
filename = os.path.join(app.config['UPLOAD_FOLDER'], file.filename)
file.save(filename)
# markitdownツールでマークダウンに変換
md = MarkItDown()
md_render = md.convert(filename)
md_content = md_render.text_content
# 変換したマークダウン内容を表示
return render_template_string("""
<h1>Markdown Output</h1>
<pre>{{ md_content }}</pre>
<br>
<a href="/">Go back</a>
""", md_content=md_content)
return '''
<!doctype html>
<title>Upload File</title>
<h1>Convert to Markdown</h1>
<form method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" value="Upload">
</form>
'''
if __name__ == '__main__':
app.run(host="0.0.0.0")
Dockerファイルの作成
Flaskで作成したアプリケーションを動作させるための環境をDockerで作成します。
基本的には、本家レポジトリのDockerfileを基に、少し変更しています。
FROM python:3.13-slim-bullseye
USER root
# 作業ディレクトリを設定
WORKDIR /app
# markitdownツールのインストール(Node.jsが必要)
RUN apt-get update && apt-get install -y --no-install-recommends \
ffmpeg \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
RUN pip install markitdown Flask
# アプリケーションのコードをコピー
COPY ./app.py /app/
# アップロード用のディレクトリを作成
RUN mkdir -p /app/uploads
# ポート5000を開放
EXPOSE 5000
# Flaskアプリケーションを実行
CMD ["python", "app.py"]
docker-composeを使いたい人は、以下のようなyamlファイルを作成する。
他と被らないポートを設定してください(ここでは、5555番ポートを指定)
services:
app:
build: .
ports:
- "5555:5000"
volumes:
- ./uploads:/app/uploads
environment:
- FLASK_ENV=development
完成
dockerコマンドでアプリケーションを立ち上げます。
docker compose up -d
その後、立ち上げたマシンにアクセスしてみる(例えば0.0.0.0:5555
)
すると、以下のような画面が立ち上がるので、ファイルを指定してアップロードすると、マークダウン形式に変換されたテキストが表示される。
終わりに
年末なので、元々目指していた形からはかなり簡易的な出来上がりになった。少なくとも、ドラッグアンドドロップでファイルのアップロードができるように改良したいところ。あとは、gpt-4oを使うmarkitdownや、リアルタイムにマークダウンを共同編集できたりすると嬉しいかも。今後、時間があれば改良していくかもしれないし、改良した際には記事もアップデートするかもしれない。良いお年を。