ごく単純に、パス(フルでも相対でも)を指定することで、その中身のテキストを取ってくるコードが欲しいと思ったので、単に作成したClaudeに作ってもらっただけ
個人的な備忘録の意味合いも含めて、一応置いておく
TL;DR
パスからローカルファイルの中身を読み取るPythonコードはうまく作ってもらえた(実物は後述)
ただ、Difyのコードブロックで同じコード(+調整)を使っても、権限問題等のために中身読み取ってくれず、「Difyではローカルファイルの中身は(単純には)取得できない」とわかった
実際のコード
import sys
import os
def main(filePath: str) -> dict:
"""
ローカルファイルの内容を文字列として読み取る関数
Args:
ファイルパス (str): 読み取りたいファイルのパス
Returns:
dict: ファイルの内容を含む辞書
"""
print(filePath)
try:
# パスの正規化(スラッシュの統一など)
path = os.path.normpath(filePath)
# ファイルの存在確認
if not os.path.exists(path):
print(f"エラー: ファイル '{path}' が存在しません。パスを確認してください。")
return {
"result": f"エラー: ファイル '{path}' が存在しません。パスを確認してください。",
}
# ディレクトリではなくファイルかチェック
if not os.path.isfile(path):
print(f"エラー: '{path}' はファイルではありません。")
return {
"result": f"エラー: '{path}' はファイルではありません。",
}
# ファイルを開いて内容を読み取る(UTF-8エンコーディングで)
with open(path, 'r', encoding='utf-8') as file:
content = file.read()
print(content)
return {
"result": content,
}
except FileNotFoundError:
print(f"エラー: ファイル '{filePath}' が見つかりません。パスを確認してください。")
return {
"result": f"エラー: ファイル '{filePath}' が見つかりません。パスを確認してください。",
}
except PermissionError:
print(f"エラー: ファイル '{filePath}' にアクセスする権限がありません。")
return {
"result": f"エラー: ファイル '{filePath}' にアクセスする権限がありません。",
}
except UnicodeDecodeError:
# UTF-8で読み取れない場合は、他のエンコーディングを試す
try:
with open(filePath, 'r', encoding='shift_jis') as file:
content = file.read()
print(content)
return {
"result": content,
}
except UnicodeDecodeError:
print(f"エラー: ファイル '{filePath}' のエンコーディングが不明です。")
return {
"result": f"エラー: ファイル '{filePath}' のエンコーディングが不明です。",
}
except Exception as e:
print(f"予期しないエラーが発生しました: {str(e)}")
return {
"result": f"予期しないエラーが発生しました: {str(e)}",
}
# ここが重要: スクリプトが直接実行された時の処理
if __name__ == "__main__":
# コマンドライン引数の確認
if len(sys.argv) != 2:
print("使用方法: python simpleFileRead.py <ファイルパス>")
print("例: python simpleFileRead.py \"D:\\example\\file.txt\"")
sys.exit(1)
# 引数からファイルパスを取得
file_path = sys.argv[1]
# main関数を実行
result = main(file_path)
# 結果の表示(既にprint文が関数内にあるので、追加で表示したい場合)
print("\n=== 実行完了 ===")
print(f"戻り値のresult: {len(result['result'])} 文字")
Claudeに作ってもらったコードを元に、色々コマンドラインから確認するために print
追加しただけのもの
ちょっと意図があって、 print
と return
双方で結果を入れておくという面倒なことをしている
実行コマンド
これについて
python simpleFileRead.py "対象ファイルのフルパスもしくは相対パス"
のコマンドを叩くと、中身がreturnされ、コマンドライン上にも表示される
確認した感じ、 .txt
.md
.html
は中身が取得できた
( .pdf
.docx
.xlsx
も一応見てみたが、 UnicodeDecodeError
「エンコーディングが不明です」のエラーとなり中身は得られなかった)
それだけの話
本当の意図:Difyでの試用
単純なコードだが、一応は先の意図があって用意したものになる
実のところ、「ローカルホストのDifyからObsidian(もちろんローカルにValutがある)のファイルを読み込む・検索する」 ということを考え付き、いろいろと調べている(なのでタグにDifyとObsidianを入れている)
これがどうもClaude Codeなどと異なってそう単純にはいきそうにない
やるに当たり、MCP FileSystemSever用意したり、更にはそこを呼び出すためのhhtp-serverをJSで用意しないといけなかったりするようで、どうにも複雑になってきそうということは理解できた
(というか、どうもDifyは「ネット上のものにアクセスしてどうこうする」ことを想定して設計されているように思われる)
考えている・AIに設計してもらったりしてるうちに複雑になりすぎてしまったので、まず単純に「Difyでローカルのファイルが読めないか」を試すべく、とりあえずこれをやってみた、というのが本当の意図になる
(Difyでローカルファイル読むなら、ナレッジとしてファイルをインポートするのが正道になるが、「(頻繁でないにしても)内容の修正・追記があるファイルを使うには都度インポートしないといけないのか?」という面倒さがあり…)
Difyのコードブロックで使った結果
で、実際に上記のコード(の一部、3~75行)をDifyのワークフローのコードブロックに入れて実行してみたが、やはりというかなんというかエラーになった
詳しく調べると、どうも error: operation not permitted
あたりになっているようで、結論としては「Difyでは(ローカルホストだとしても)ローカルファイルを単純に読むことはできない」になりそうである
ここのあたり深く調べると、実行環境がLinuxでパスの書式が違うとか、そもそもサンドボックスで実行するから権限がないとか色々あるらしいが…
ということで別の方法、とりあえずはMCPで何らかできないかを考え直していくことになるが、DifyでもMCPは使えるようになっているとはいえ、設定の書式等がClaude CodeやCursorなんかと異なる感じでややクセがありそうでどうするか
ObsidianじゃなくNotion使え?そうだね
(実際のところ、Notionからの同期がなんかうまく決まらなかったのと、ローカルにこだわりたいのとでObsidianを読みたい、というところがある)