テキストファイルを読み込み ollamaでGoogleカレンダーに送れる形式にする
PDFからテキストと抽出するので
1 | pip install pdf2image pytesseract |
Tesseract OCRのインストール
1 | brew install tesseract |
日本語言語データを追加
1 | brew install tesseract-lang |
とりあえずここまではOK
以前PDFの内容の取り出しはしたことがあるので
肝心の文章から予定を ollamaで取り出しを行う
テキストから日時とイベント情報を抽出します。今回のテキストでは、日付が「10月7日~10月15日」や「10月25日(金)」のように記載されています。これらを正規表現とdateparserライブラリで解析する
1 | pip install dateparser |
PDFの前に
テキストファイルの読み込み
テキストをOllamaで解析し、日時と予定を抽出
GoogleカレンダーAPIを使って予定を追加
を行うようにする
これはメールでお知らせすることがあるため
1 2 3 4 5 6 7 8 | def read_text_file(file_path): with open (file_path, 'r' , encoding= 'utf-8' ) as file : text = file . read () return text # 使用例 text_file_path = 'school_notice.txt' # テキストファイルのパス text_content = read_text_file(text_file_path) |
でテキストファイルを読み込む
Ollamaを使用してテキストを解析し、日時とイベント情報を抽出
PythonからOllamaを呼び出す
Ollamaがローカルで動作している前提で、requestsライブラリを使用してHTTPリクエストを送信
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | import requests import json def parse_text_with_ollama(text): # OllamaのAPIエンドポイント # Ollamaに送信するプロンプトを作成 prompt = f "" " 以下の文章から、日時とそれに対応する予定を抽出してください。結果はJSON形式で、 "date" と "event" のキーを持つオブジェクトのリストとして返してください。 文章: {text} 出力例: [ {{ "date" : "2024-10-07" , "event" : "ペットボトルの準備" }}, {{ "date" : "2024-10-25" , "event" : "準備物の確認" }} ] "" " payload = { 'model' : 'your-ollama-model-name' , # 使用するOllamaモデルの名前 'prompt' : prompt } response = requests.post(ollama_url, json=payload) response_text = response.text # Ollamaの出力からJSON部分を抽出 try: start_index = response_text.index( '[' ) end_index = response_text.rindex( ']' ) + 1 json_str = response_text[start_index:end_index] events = json.loads(json_str) except (ValueError, json.JSONDecodeError) as e: print( "Ollamaからのレスポンスの解析に失敗しました:" , e) events = [] return events # 使用例 events = parse_text_with_ollama(text_content) print( "抽出されたイベント:" , events) 抽出されたイベントをGoogleカレンダーに追加 import os from datetime import datetime, timedelta from google.oauth2.credentials import Credentials from googleapiclient.discovery import build def add_events_to_calendar(events): creds = None if os.path.exists( 'token.json' ): creds = Credentials.from_authorized_user_file( 'token.json' , SCOPES) else : print( "token.json が見つかりません。認証を実行してください。" ) return service = build( 'calendar' , 'v3' , credentials=creds) for event in events: # 日付の形式を確認し、必要に応じて変換 try: event_date = datetime.strptime(event[ 'date' ], '%Y-%m-%d' ) except ValueError: print(f "無効な日付形式: {event['date']}" ) continue event_body = { 'summary' : event[ 'event' ], 'start' : { 'date' : event_date.strftime( '%Y-%m-%d' ), 'timeZone' : 'Asia/Tokyo' , }, 'end' : { 'date' : (event_date + timedelta(days=1)).strftime( '%Y-%m-%d' ), 'timeZone' : 'Asia/Tokyo' , }, } # イベントをカレンダーに追加 created_event = service.events().insert(calendarId= 'primary' , body=event_body).execute() print(f "イベントが作成されました: {created_event.get('htmlLink')}" ) # 使用例 add_events_to_calendar(events) |
これらを
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | import os import requests import json from datetime import datetime, timedelta from google.oauth2.credentials import Credentials from googleapiclient.discovery import build def read_text_file(file_path): with open (file_path, 'r' , encoding= 'utf-8' ) as file : text = file . read () return text def parse_text_with_ollama(text): # OllamaのAPIエンドポイント # Ollamaに送信するプロンプトを作成 prompt = f "" " 以下の文章から、日時とそれに対応する予定を抽出してください。結果はJSON形式で、 "date" と "event" のキーを持つオブジェクトのリストとして返してください。 文章: {text} 出力例: [ {{ "date" : "2024-10-07" , "event" : "ペットボトルの準備" }}, {{ "date" : "2024-10-25" , "event" : "準備物の確認" }} ] "" " payload = { 'model' : 'your-ollama-model-name' , # 使用するOllamaモデルの名前 'prompt' : prompt } response = requests.post(ollama_url, json=payload) response_text = response.text # Ollamaの出力からJSON部分を抽出 try: start_index = response_text.index( '[' ) end_index = response_text.rindex( ']' ) + 1 json_str = response_text[start_index:end_index] events = json.loads(json_str) except (ValueError, json.JSONDecodeError) as e: print( "Ollamaからのレスポンスの解析に失敗しました:" , e) events = [] return events def add_events_to_calendar(events): creds = None if os.path.exists( 'token.json' ): creds = Credentials.from_authorized_user_file( 'token.json' , SCOPES) else : print( "token.json が見つかりません。認証を実行してください。" ) return service = build( 'calendar' , 'v3' , credentials=creds) for event in events: # 日付の形式を確認し、必要に応じて変換 try: event_date = datetime.strptime(event[ 'date' ], '%Y-%m-%d' ) except ValueError: print(f "無効な日付形式: {event['date']}" ) continue event_body = { 'summary' : event[ 'event' ], 'start' : { 'date' : event_date.strftime( '%Y-%m-%d' ), 'timeZone' : 'Asia/Tokyo' , }, 'end' : { 'date' : (event_date + timedelta(days=1)).strftime( '%Y-%m-%d' ), 'timeZone' : 'Asia/Tokyo' , }, } # イベントをカレンダーに追加 created_event = service.events().insert(calendarId= 'primary' , body=event_body).execute() print(f "イベントが作成されました: {created_event.get('htmlLink')}" ) # メインの実行部分 text_file_path = 'school_notice.txt' # テキストファイルのパス text_content = read_text_file(text_file_path) events = parse_text_with_ollama(text_content) print( "抽出されたイベント:" , events) add_events_to_calendar(events) |
というように1つにすることもできるが
検証と後で他でも使えるように
モジュールにして他でも使えるようにしたい
1 | calendar_module.py |
に
1 2 3 | read_text_file(file_path) parse_text_with_ollama(text, model_name) add_events_to_calendar(events, calendar_id= 'primary' , token_file= 'token.json' ) |
を入れる
1 | touch calendar_module.py |
でファイルを作成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | import os import requests import json from datetime import datetime, timedelta from google.oauth2.credentials import Credentials from googleapiclient.discovery import build def read_text_file(file_path): "" "テキストファイルを読み込み、その内容を文字列として返します。" "" with open (file_path, 'r' , encoding= 'utf-8' ) as file : text = file . read () return text def parse_text_with_ollama(text, model_name= 'your-ollama-model-name' ): "" " Ollamaを使用してテキストから日時とイベントを抽出します。 Args: text (str): 解析するテキスト。 model_name (str): 使用するOllamaモデルの名前。 Returns: list: 抽出されたイベントのリスト。 "" " # OllamaのAPIエンドポイント # Ollamaに送信するプロンプトを作成 prompt = f "" " 以下の文章から、日時とそれに対応する予定を抽出してください。結果はJSON形式で、 "date" と "event" のキーを持つオブジェクトのリストとして返してください。 文章: {text} 出力例: [ {{ "date" : "2024-10-07" , "event" : "ペットボトルの準備" }}, {{ "date" : "2024-10-25" , "event" : "準備物の確認" }} ] "" " payload = { 'model' : model_name, 'prompt' : prompt } response = requests.post(ollama_url, json=payload) response_text = response.text # Ollamaの出力からJSON部分を抽出 try: start_index = response_text.index( '[' ) end_index = response_text.rindex( ']' ) + 1 json_str = response_text[start_index:end_index] events = json.loads(json_str) except (ValueError, json.JSONDecodeError) as e: print( "Ollamaからのレスポンスの解析に失敗しました:" , e) events = [] return events def add_events_to_calendar(events, calendar_id= 'primary' , token_file= 'token.json' ): "" " 抽出されたイベントをGoogleカレンダーに追加します。 Args: events (list): イベントのリスト。 calendar_id (str): イベントを追加するカレンダーのID。 token_file (str): 認証トークンファイルのパス。 "" " creds = None if os.path.exists(token_file): creds = Credentials.from_authorized_user_file(token_file, SCOPES) else : print(f "{token_file} が見つかりません。認証を実行してください。" ) return service = build( 'calendar' , 'v3' , credentials=creds) for event in events: # 日付の形式を確認し、必要に応じて変換 try: event_date = datetime.strptime(event[ 'date' ], '%Y-%m-%d' ) except ValueError: print(f "無効な日付形式: {event['date']}" ) continue event_body = { 'summary' : event[ 'event' ], 'start' : { 'date' : event_date.strftime( '%Y-%m-%d' ), 'timeZone' : 'Asia/Tokyo' , }, 'end' : { 'date' : (event_date + timedelta(days=1)).strftime( '%Y-%m-%d' ), 'timeZone' : 'Asia/Tokyo' , }, } # イベントをカレンダーに追加 created_event = service.events().insert(calendarId=calendar_id, body=event_body).execute() print(f "イベントが作成されました: {created_event.get('htmlLink')}" ) |
として保存
モジュールを作成したら、別のスクリプトからインポートして使用
1 | touch main.py |
でファイルを作成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | from calendar_module import read_text_file, parse_text_with_ollama, add_events_to_calendar # テキストファイルのパス text_file_path = 'school_notice.txt' # 処理するテキストファイルのパス # テキストの読み込み text_content = read_text_file(text_file_path) # Ollamaでテキストを解析(モデル名を指定) events = parse_text_with_ollama(text_content, model_name= 'your-ollama-model-name' ) # 抽出されたイベントを表示 print( "抽出されたイベント:" , events) # Googleカレンダーにイベントを追加 add_events_to_calendar(events, calendar_id= 'primary' , token_file= 'token.json' ) |
とする
ただし今回はテストなので
とりあえずカレンダーにイベントを追加する部分はコメントアウトし
まずは Ollamaの結果を見る
またモデルには
parse_text_with_ollama関数内のモデル名をelyzaに変更
model_name引数のデフォルト値をelyza:jp8bに設定
ということで
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | import os import requests import json from datetime import datetime, timedelta from google.oauth2.credentials import Credentials from googleapiclient.discovery import build def read_text_file(file_path): "" "テキストファイルを読み込み、その内容を文字列として返します。" "" with open (file_path, 'r' , encoding= 'utf-8' ) as file : text = file . read () return text def parse_text_with_ollama(text, model_name= 'elyza:jp8b' ): "" " Ollamaを使用してテキストから日時とイベントを抽出します。 Args: text (str): 解析するテキスト。 model_name (str): 使用するOllamaモデルの名前(デフォルトは 'elyza:jp8b' )。 Returns: list: 抽出されたイベントのリスト。 "" " # OllamaのAPIエンドポイント # Ollamaに送信するプロンプトを作成 prompt = f "" " 以下の文章から、日時とそれに対応する予定を抽出してください。結果はJSON形式で、 "date" と "event" のキーを持つオブジェクトのリストとして返してください。 文章: {text} 出力例: [ {{ "date" : "2024-10-07" , "event" : "ペットボトルの準備" }}, {{ "date" : "2024-10-25" , "event" : "準備物の確認" }} ] "" " payload = { 'model' : model_name, 'prompt' : prompt } response = requests.post(ollama_url, json=payload) response_text = response.text # Ollamaの出力からJSON部分を抽出 try: # レスポンスをJSONとして直接パース events = json.loads(response_text.strip()) except json.JSONDecodeError: try: # JSON部分のみを抽出 start_index = response_text.index( '[' ) end_index = response_text.rindex( ']' ) + 1 json_str = response_text[start_index:end_index] events = json.loads(json_str) except (ValueError, json.JSONDecodeError) as e: print( "Ollamaからのレスポンスの解析に失敗しました:" , e) events = [] return events def add_events_to_calendar(events, calendar_id= 'primary' , token_file= 'token.json' ): "" " 抽出されたイベントをGoogleカレンダーに追加します。 Args: events (list): イベントのリスト。 calendar_id (str): イベントを追加するカレンダーのID。 token_file (str): 認証トークンファイルのパス。 "" " creds = None if os.path.exists(token_file): creds = Credentials.from_authorized_user_file(token_file, SCOPES) else : print(f "{token_file} が見つかりません。認証を実行してください。" ) return service = build( 'calendar' , 'v3' , credentials=creds) for event in events: # 日付の形式を確認し、必要に応じて変換 try: event_date = datetime.strptime(event[ 'date' ], '%Y-%m-%d' ) except ValueError: print(f "無効な日付形式: {event['date']}" ) continue event_body = { 'summary' : event[ 'event' ], 'start' : { 'date' : event_date.strftime( '%Y-%m-%d' ), 'timeZone' : 'Asia/Tokyo' , }, 'end' : { 'date' : (event_date + timedelta(days=1)).strftime( '%Y-%m-%d' ), 'timeZone' : 'Asia/Tokyo' , }, } # イベントをカレンダーに追加 created_event = service.events().insert(calendarId=calendar_id, body=event_body).execute() print(f "イベントが作成されました: {created_event.get('htmlLink')}" ) |
というように
1 | calendar_module.py |
を変更
またmain.pyを
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | from calendar_module import read_text_file, parse_text_with_ollama, add_events_to_calendar # テキストファイルのパス text_file_path = 'school_notice.txt' # 処理するテキストファイルのパス # テキストの読み込み text_content = read_text_file(text_file_path) # Ollamaでテキストを解析(モデル名を指定) events = parse_text_with_ollama(text_content, model_name= 'elyza:jp8b' ) # 抽出されたイベントを表示 print( "抽出されたイベント:" , events) # Googleカレンダーにイベントを追加 #add_events_to_calendar(events, calendar_id='primary', token_file='token.json') |
としておく
1 | touch school_notice.txt |
でテキストを
学校からのお知らせ内容をテキストファイルにして実験
しかし
1 2 | Ollamaからのレスポンスの解析に失敗しました: substring not found 抽出されたイベント: [] |
となってしまう
機能を分割して問題を探す
以前のコードを見たらリクエストURLが
1 |
なので
1 | ollama_url = 'http://localhost:11434/api/generate' |
に修正
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | import requests import json def parse_text_with_ollama(text, model_name= 'elyza/jp8b' ): "" " Ollamaを使用してテキストから日時とイベントを抽出します。 Args: text (str): 解析するテキスト。 model_name (str): 使用するOllamaモデルの名前(デフォルトは 'elyza/jp8b' )。 Returns: list: 抽出されたイベントのリスト。 "" " # OllamaのAPIエンドポイント(修正) # Ollamaに送信するプロンプトを作成 prompt = f "" " 以下の文章から、日時とそれに対応する予定を抽出してください。結果はJSON形式で、 "date" と "event" のキーを持つオブジェクトのリストとして返してください。 文章: {text} 出力例: [ {{ "date" : "2024-10-07" , "event" : "ペットボトルの準備" }}, {{ "date" : "2024-10-25" , "event" : "準備物の確認" }} ] "" " payload = { 'model' : model_name, 'prompt' : prompt } try: response = requests.post(ollama_url, json=payload) response.raise_for_status() # レスポンスをJSONとしてパース response_json = response.json() # テキスト部分を取得 response_text = response_json.get( 'response' , '' ) except requests.exceptions.RequestException as e: print( "Ollamaへのリクエストに失敗しました:" , e) return [] except json.JSONDecodeError as e: print( "OllamaからのレスポンスがJSON形式ではありません:" , e) return [] # Ollamaの出力からJSON部分を抽出 try: start_index = response_text.index( '[' ) end_index = response_text.rindex( ']' ) + 1 json_str = response_text[start_index:end_index] events = json.loads(json_str) except (ValueError, json.JSONDecodeError) as e: print( "Ollamaからのレスポンスの解析に失敗しました:" , e) events = [] return events |
とした
しかし
1 2 | Ollamaからのレスポンスの解析に失敗しました: Expecting value: line 1 column 2 (char 1) 抽出されたイベント: |
となる
ChatGGPTで情報を調べると以下の方になる
Ollamaはストリーミング形式でレスポンスを返しています。
つまり、モデルの生成結果が複数のJSONオブジェクトとして順次送られてきています
{“model”:”elyza:jp8b”,”created_at”:”…”,”response”:”…”,”done”:false}
この”response”フィールドに、モデルが生成したテキストの一部が含まれています。全体のレスポンスを組み立てるには、これらの”response”フィールドを順番に連結する必要があります
requestsライブラリを使用して、ストリーミングレスポンスを処理します。response.iter_lines()を使用して、各行を逐次処理
各行をJSONとしてパースし、”response”フィールドの値を取り出して連結
連結したテキストがJSON文字列(リスト)であることを前提に、json.loads()でパース
となるようにコード変更
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | import requests import json def parse_text_with_ollama(text, model_name= 'elyza:jp8b' ): "" " Ollamaを使用してテキストから日時とイベントを抽出します。 Args: text (str): 解析するテキスト。 model_name (str): 使用するOllamaモデルの名前。 Returns: list: 抽出されたイベントのリスト。 "" " # OllamaのAPIエンドポイント # Ollamaに送信するプロンプトを作成 prompt = f "" " 以下の文章から、日付とそれに対応する予定を抽出してください。結果は純粋なJSON形式で、日本語で、 "date" と "event" のキーを持つオブジェクトのリストとして返してください。 文章: {text} 出力例: [ {{ "date" : "2024-10-07" , "event" : "ペットボトルの準備" }}, {{ "date" : "2024-10-25" , "event" : "準備物の確認" }} ] 重要事項: - 出力は純粋なJSON形式で、追加のテキストや説明は含めないでください。 - 日付は "YYYY-MM-DD" の形式で出力してください。 - イベント名は元の文章から適切に抽出してください。 "" " payload = { 'model' : model_name, 'prompt' : prompt } try: # ストリーミングレスポンスを取得 response = requests.post(ollama_url, json=payload, stream=True) response.raise_for_status() # レスポンスのストリームを処理 response_text = '' for line in response.iter_lines(): if line: line_str = line.decode( 'utf-8' ) # 各行をJSONとしてパース line_json = json.loads(line_str) # "response"フィールドを連結 response_text += line_json.get( 'response' , '' ) print( "Ollamaのレスポンス:" ) print(response_text) except requests.exceptions.RequestException as e: print( "Ollamaへのリクエストに失敗しました:" , e) return [] except json.JSONDecodeError as e: print( "レスポンスの解析に失敗しました:" , e) return [] # 連結したテキストをJSONとして解析 try: events = json.loads(response_text) except json.JSONDecodeError as e: print( "Ollamaからのレスポンスの解析に失敗しました:" , e) events = [] return events |
とする
実行結果は
1 2 3 4 | { 'date' : '2024-10-07' , 'event' : 'ペットボトルの準備' } { 'date' : '2024-10-15' , 'event' : None} { 'date' : '2024-10-25' , 'event' : '準備物の確認' } { 'date' : '2024-10-26' , 'event' : None} |
となる
一応はエラーは消えたが他のものを試してみる
台風10号の影響により、9月2日(月)の給食が中止となりました。 弁当の準備をお願いします。 8月30日(金)現時点では、日課の変更はありません。 台風や大雨の状況によっては、変更する場合があります。 4月にコドモンで知らせした、「R6年度 自然災害発生時、警報発表・避難情報発表時等に伴う学校の対処」とおり対応します。 今一度御確認ください。
という文章で実験すると
1 2 | { 'date' : '8月30日' , 'event' : '弁当の準備' } { 'date' : '9月2日' , 'event' : '給食中止' } |
とほぼ目的に近いものになる
1 2 3 4 5 6 7 | PTA会員 様 Caros membros do PTA 日頃よりPTA活動に御理解・御協力いただいき、ありがとうございます。 令和7年度のPTA本部役員候補選考の時期になりました。 アンケート形式にて本部役員の立候補を募ります。 添付の文書を御一読いただき、以下のリンクからアンケートに回答をお願いします。 回答期限は9月30日(月)とします。 |
だと
1 2 3 4 5 6 7 8 | Ollamaのレスポンス: [ { "date" : "2024-09-25" , "event" : "PTA本部役員候補選出についてのアンケート" }, { "date" : "2024-09-30" , "event" : "アンケート回答期限" } ] 抽出されたイベント: { 'date' : '2024-09-25' , 'event' : 'PTA本部役員候補選出についてのアンケート' } { 'date' : '2024-09-30' , 'event' : 'アンケート回答期限' } |
テキストファイルの内容によっては
1 | 抽出されたイベント: { 'date' : '2024-10-07' , 'event' : 'ペットボトルの準備' } { 'date' : '2024-10-15' , 'event' : None} { 'date' : '2024-10-25' , 'event' : '準備物の確認' } { 'date' : '2024-10-26' , 'event' : None} |
となるため
プロンプトを改善して、モデルにeventがnullにならないように強調
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | prompt = f "" " 以下の文章から、日付とそれに対応する予定を抽出してください。結果は純粋なJSON形式で、日本語で、 "date" と "event" のキーを持つオブジェクトのリストとして返してください。 文章: {text} 出力例: [ {{ "date" : "2024-10-07" , "event" : "ペットボトルの準備" }}, {{ "date" : "2024-10-25" , "event" : "準備物の確認" }} ] 重要事項: - 出力は純粋なJSON形式で、追加のテキストや説明は含めないでください。 - 日付は "YYYY-MM-DD" の形式で出力してください。 - **イベント名が存在しない場合、そのエントリを出力しないでください。** - イベント名は元の文章から適切に抽出してください。 "" " リスト内包表記を使用:eventsリストからevent[ 'event' ]がNoneでないイベントだけを新しいリストにします。 is not Noneを使用:event[ 'event' ]がNoneでないことを確認 # Ollamaでテキストを解析(モデル名を指定) events = parse_text_with_ollama(text_content, model_name= 'elyza:jp8b' ) # 抽出されたイベントを表示 print( "抽出されたイベント:" ) for event in events: print(event) # eventがNoneのものを削除 events = [event for event in events if event[ 'event' ] is not None] # フィルタリング後のイベントを表示 print( "有効なイベント:" ) for event in events: print(event) |
これらを変更するので
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | import requests import json def parse_text_with_ollama(text, model_name= 'elyza:jp8b' ): "" " Ollamaを使用してテキストから日時とイベントを抽出します。 Args: text (str): 解析するテキスト。 model_name (str): 使用するOllamaモデルの名前。 Returns: list: 抽出されたイベントのリスト。 "" " # OllamaのAPIエンドポイント # Ollamaに送信するプロンプトを作成 prompt = f "" " 以下の文章から、日付とそれに対応する予定を抽出してください。結果は純粋なJSON形式で、日本語で、 "date" と "event" のキーを持つオブジェクトのリストとして返してください。 文章: {text} 出力例: [ {{ "date" : "2024-10-07" , "event" : "ペットボトルの準備" }}, {{ "date" : "2024-10-25" , "event" : "準備物の確認" }} ] 重要事項: - 出力は純粋なJSON形式で、追加のテキストや説明は含めないでください。 - 日付は "YYYY-MM-DD" の形式で出力してください。 - イベント名は元の文章から適切に抽出してください。 "" " payload = { 'model' : model_name, 'prompt' : prompt } try: # ストリーミングレスポンスを取得 response = requests.post(ollama_url, json=payload, stream=True) response.raise_for_status() # レスポンスのストリームを処理 response_text = '' for line in response.iter_lines(): if line: line_str = line.decode( 'utf-8' ) # 各行をJSONとしてパース line_json = json.loads(line_str) # "response"フィールドを連結 response_text += line_json.get( 'response' , '' ) print( "Ollamaのレスポンス:" ) print(response_text) except requests.exceptions.RequestException as e: print( "Ollamaへのリクエストに失敗しました:" , e) return [] except json.JSONDecodeError as e: print( "レスポンスの解析に失敗しました:" , e) return [] # 連結したテキストをJSONとして解析 try: events = json.loads(response_text) except json.JSONDecodeError as e: print( "Ollamaからのレスポンスの解析に失敗しました:" , e) events = [] return events |
を
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | import requests import json def parse_text_with_ollama(text, model_name= 'elyza:jp8b' ): "" " Ollamaを使用してテキストから日時とイベントを抽出します。 Args: text (str): 解析するテキスト。 model_name (str): 使用するOllamaモデルの名前。 Returns: list: 抽出されたイベントのリスト。 "" " # OllamaのAPIエンドポイント # Ollamaに送信するプロンプトを作成 prompt = f "" " 以下の文章から、日付とそれに対応する予定を抽出してください。結果は純粋なJSON形式で、日本語で、 "date" と "event" のキーを持つオブジェクトのリストとして返してください。 文章: {text} 出力例: [ {{ "date" : "2024-10-07" , "event" : "ペットボトルの準備" }}, {{ "date" : "2024-10-25" , "event" : "準備物の確認" }} ] 重要事項: - 出力は純粋なJSON形式で、追加のテキストや説明は含めないでください。 - 日付は "YYYY-MM-DD" の形式で出力してください。 - **イベント名が存在しない場合、そのエントリを出力しないでください。** - イベント名は元の文章から適切に抽出してください。 "" " payload = { 'model' : model_name, 'prompt' : prompt } try: # ストリーミングレスポンスを取得 response = requests.post(ollama_url, json=payload, stream=True) response.raise_for_status() # レスポンスのストリームを処理 response_text = '' for line in response.iter_lines(): if line: line_str = line.decode( 'utf-8' ) # 各行をJSONとしてパース line_json = json.loads(line_str) # "response"フィールドを連結 response_text += line_json.get( 'response' , '' ) print( "Ollamaのレスポンス:" ) print(response_text) except requests.exceptions.RequestException as e: print( "Ollamaへのリクエストに失敗しました:" , e) return [] except json.JSONDecodeError as e: print( "レスポンスの解析に失敗しました:" , e) return [] # 連結したテキストをJSONとして解析 try: events = json.loads(response_text) except json.JSONDecodeError as e: print( "Ollamaからのレスポンスの解析に失敗しました:" , e) events = [] return events |
にして
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | from ollama_module import parse_text_with_ollama from google_calendar_module import add_events_to_calendar # テキストファイルのパス text_file_path = 'school_notice.txt' # 処理するテキストファイルのパス # テキストの読み込み with open (text_file_path, 'r' , encoding= 'utf-8' ) as file : text_content = file . read () # Ollamaでテキストを解析(モデル名を指定) events = parse_text_with_ollama(text_content, model_name= 'elyza:jp8b' ) # 抽出されたイベントを表示 print( "抽出されたイベント:" ) for event in events: print(event) # Googleカレンダーにイベントを追加 # add_events_to_calendar(events, calendar_id='primary', token_file='token.json', credentials_file='credentials.json') |
を
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | from ollama_module import parse_text_with_ollama from google_calendar_module import add_events_to_calendar # テキストファイルのパス text_file_path = 'school_notice.txt' # 処理するテキストファイルのパス # テキストの読み込み with open (text_file_path, 'r' , encoding= 'utf-8' ) as file : text_content = file . read () # Ollamaでテキストを解析(モデル名を指定) events = parse_text_with_ollama(text_content, model_name= 'elyza:jp8b' ) # 抽出されたイベントを表示 print( "抽出されたイベント:" ) for event in events: print(event) # eventがNoneのものを削除 events = [event for event in events if event[ 'event' ] is not None] # フィルタリング後のイベントを表示 print( "有効なイベント:" ) for event in events: print(event) # 有効なイベントがある場合のみGoogleカレンダーに追加 if events: add_events_to_calendar(events, calendar_id= 'primary' , token_file= 'token.json' , credentials_file= 'credentials.json' ) else : print( "有効なイベントがありません。" ) |
とした