10
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Power AppsAdvent Calendar 2024

Day 17

【Power Apps】Power AppsからMarkItDown使ってみた【半分AWSじゃん】

Last updated at Posted at 2024-12-16

本記事はPower Apps Advent Calendar 2024 シリーズ2の17日目担当記事になります。
後日会社HP上の技術ブログでもアップさせていただく予定ですので、その際は記事内にリンクを追記させていただきます。

はじめに

こんにちは、reireです。

みなさん、MarkItDownはご存じでしょうか?
https://github.com/microsoft/markitdown
github

MarkItDownはつい最近Microsoftより公開されたPythonライブラリで、以下のような様々なファイルをMarkdownテキストに変換してくれるとのことです。

  • PDF (.pdf)
  • PowerPoint (.pptx)
  • Word (.docx)
  • Excel (.xlsx)
  • 画像(EXIFメタデータおよびOCR)
  • 音声(EXIFメタデータおよび音声の文字起こし)
  • HTML(Wikipediaなどの特別な処理を含む)
  • その他のさまざまなテキスト形式(csv、json、xmlなど)

OCR処理や音声ファイルの文字起こしまでしてくれる、というのはかなり気になりますね。

そこでさっそく試してみようと思ったのですが、ただ試しても面白みがないかな~と思い。
せっかくMicrosoftから提供されているのであれば、Power AppsPower Automateと絡められれば面白いのでは?ということでチャレンジしてみました。

ということで今回はPower AppsからMarkItDownを使う方法について解説していきたいと思います。

動作イメージ

こんな感じの動作になりました!
App_Excel

アーキテクチャ

今回は以下のようなアーキテクチャで構築していきました。
アーキテクチャ

つまるところ、AWS上のLambdaにMarkItDownの処理を実装、それをAPI GatewayでREST API化し、Power Automateを介してPower Appsから叩けるようにした感じです。

また、Power AppsではMarkdownテキストを直接描画できないので、Lambda側でMarkdownテキストをさらにHTMLテキストにしています。

今回はあくまでも個人でのテスト用ということで、各所かなり適当ですがお許しください!!!

構築

構築を始めていきます。

1. Lambda

1.1 Lambda関数の作成

まずはLambda関数を作成します。
Lambda関数

中身はこんな感じ。
エラー処理なんてそんなお利口さんなことはしません。

# 必要なモジュールをインポート
import json
import base64
import markdown
from markitdown import MarkItDown

def lambda_handler(event, context):

    md = markdown.Markdown(extensions=['tables'])
    markitdown = MarkItDown()

    # リクエストボディからJSONデータを解析
    body = json.loads(event['body'])

    # リクエストボディからファイルデータとファイル名を取得
    base64_data = body.get('file')
    file_name = body.get('filename')

    # Base64デコードしてバイナリデータを取得
    binary_data = base64.b64decode(base64_data)

    # 一時ファイルパスを生成
    file_path = f"/tmp/{file_name}"

    # デコードしたバイナリデータを一時ファイルに保存
    with open(file_path, "wb") as file:
        file.write(binary_data)

    # MarkItDownを使ってMarkdownに変換
    Markdown_text = markitdown.convert(file_path)

    # 変換結果のMarkdownをHTMLに変換
    HTML_text = md.convert(Markdown_text.text_content)

    # APIレスポンスでMarkdownテキストとHTMLテキストを返す
    return {
        'statusCode': 200,
        'body': json.dumps({
            'Markdown_Text': Markdown_text.text_content,
            'HTML_Text': HTML_text
        })
    }

1.2 Layerの作成、追加

次に、Lambda関数に対してLayerを追加します。

というのも、デフォルトのLambda環境ではMarkItDownなどのサードパーティー製ライブラリはインストールされていません。
そのため、自身で使用したいライブラリやモジュールをまとめて一度zip形式にし、Layerとして作成してあげる必要があります。

今回は本命であるMarkdown変換を行うMarkItDownライブラリと、変換したMarkdownテキストをさらにHTMLテキストに変換するMarkdownライブラリをLayerとして追加しました。
Lambda_Layer

MarkItDown結構ファイルサイズ大きかったのでS3にアップロードしています。
Lambda_Layer_S3

2. API Gateway

続いてAPI Gatewayです。

2.1 REST APIの作成

まずはREST APIを作成し、POSTメソッドを追加します。
API

Lambdaプロキシ統合は有効にしましょう。
API_Lambda

2.2 APIキーや使用量プラン

作成したAPIに対し、APIキーの作成と使用量プランの関連付けを行います。
API_planAPI_key

これで先ほど作成したLambda関数がAPIとして叩けるようになります。

3. Power Automate

ここまでくれば後はいつも通りPower Platformでの作業です。

3.1 フローのトリガー

トリガーはもちろんPower Appsのフロー呼び出しトリガー。
ファイル名、ファイルコンテンツを受け取ります。
Flow_trigger

3.2 API呼び出しとレスポンスの解析

続いてHTTPアクションを配置し、先ほどAPI Gatewayで作成したAPIのパラメーターを入力していきます。
Flow_HTTP

本来Power Automate上でAPIキーなどの機密性の高い値を扱う場合は、
ソリューション化して環境変数として設定してあげるようにしましょう。

その後はJsonの解析アクションでAPIからのレスポンスのJsonテキストを解析します。
Flow_Json

3.3 SharePoint上にファイル作成

APIから受け取ったMarkdownテキストをコンテンツにして任意のSharePointライブラリ上にファイルを作成し、リンクを取得するためにプロパティ取得のアクションを実行します。
Flow_Json
Flow_Json

3.4 Power Appsへの応答

最後にPower Apps応答アクションでHTMLテキストとファイルリンクを返して完成
Flow_App

4. Power Apps

これでMarkItDownを実行する準備は整いました。
最後にPower Appsを作成していきましょう。

4.1 Power Automateフローの追加

先ほど作成したPower AutomateフローをPower Appに追加します。
Apps_Flow_Add

4.2 コントロールの配置

以下のようにコントロールを配置します。
App_Control

4.3 各コントロールのプロパティ設定

以下のように、各コントロールのプロパティを設定していきます。

  • FileUploader

    FileUploader.MaxAttachments
    //今回は複数ファイルを一発で変換できるように構築していないため、とりあえず1ファイルに制限しておく
    1
    
    FileUploader.MaxSize
    //任意のサイズ
    30
    
  • FileContents

    FileContents.Image
    //FileUploaderにアップしたファイルのコンテンツを設定
    First(FileUploader.Attachments).Value
    
  • Button

    Button.OnSelect
    //Json関数でFileUploaderにアップしたファイルをBase64に変換し、不要な文字列を削除
    Set(
        FileJson,
        Substitute(Match(JSON(FileContents.Image,JSONFormat.IncludeBinaryData),"(?<=base64,).*").FullMatch,"""","")
    );
    
    //Power Automateフローを実行し、レスポンスを受け取る
    Set(
        res,
        Markitdown.Run(FileJson,First(FileUploader.Attachments).Name)
    );
    
    //FileUploaderをリセット
    Reset(FileUploader);
    
    //Markdownファイルのダウンロード
    Download(res.path);
    
  • HtmlViewer

    HtmlViewer.HtmlText
    res.htmltext
    

おつかれさまです、これでPower Apps側も完成です!

動作確認

動作を試してみましょう。

まずはExeclファイル
App_Excel
HTMLテキストを通してMarkdown表形式で表示され…
App_Excel
更にMarkdownファイルもダウンロードすることができました!

続いてドキュメントファイルを試してみましょう。
まずはWordから
App_Excel
App_Excel

そしてPowerPoint
App_Excel
App_Excel

こちらも単にテキストだけでなく、見出しやリストが反映されているようです!

このようにMarkItDownを使うことで、社内に散在する様々な文書のMarkdown化を効率よく進めることができそうですね!

おわり

かなり長くなってしまいましたが、Power AppsからMarkItDownを実行する手順の解説でした。
併せて、AWS上に自作のAPIを作成し、Power AutomateからHTTPアクションでリクエストする手順の解説にもなりましたね。

MarkItDownは最近公開されたライブラリですが、ざっくりExcelやWord、PowerPoint、PDFあたりはそこそこの感じでMarkdown化してくれる様子でした。

ただし、画像ファイルと音声ファイルについてはどうにも実行できず。
軽く調べてみた感じ、これらのMarkdown化を行うにはOpenAIなどのLLMとの連携が必要なように思われます。

GPT-4oを使ってみようと思ったのですが、OpenAIのライブラリまで追加しようとするとLambda Layerの容量制限に引っかかり、少なくとも今回の構成では実行できそうにありませんでした;;

また、MarkItDown自体の中身を見てみたところ既存ライブラリをまとめて使いやすいインターフェースにしたという側面が強いように見えますし、まだ発展途上という感じなんですかね、しばらく様子見つつ試してみます。

以上、MarkItDownを触ってみた所感でした。

実は本記事のネタを思いついたのがAdvent Calendar投稿日前日でして、そこから気合で構築、検証してなんとかAdvent Calendar当日の午前3時に書き上げるというかなりの雑構築&雑解説となってしまいました。
Advent Calendarに投稿するのにクオリティこんなんで大丈夫なのかと大変恐縮なのですが、テーマ自体はそこそこ面白いものを書けたのかな、と思います。
みなさんもぜひMarkItDownを試してみてはいかがでしょうか。

それでは今回はここまで。
引き続き、Power Platformを楽しんでいきましょう!

それでは

10
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?