Spaces:
Running
Running
Merge pull request #6 from EQUES-Inc/feature/history
Browse files- main.py +17 -11
- src/aws/s3.py +3 -2
- src/entity/document.py +7 -0
- src/forms/deviation_notification_report.py +207 -1
- src/forms/history_common.py +87 -0
main.py
CHANGED
@@ -1,18 +1,24 @@
|
|
1 |
import streamlit as st
|
2 |
|
|
|
3 |
from src.forms.deviation_investigation_report import deviation_investigation_report_form
|
4 |
-
from src.forms.deviation_notification_report import
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
}
|
10 |
|
11 |
selected_page = st.sidebar.selectbox(
|
12 |
-
"作成する文書を選択してください。",
|
13 |
)
|
|
|
14 |
match selected_page:
|
15 |
-
case
|
16 |
-
|
17 |
-
case
|
18 |
-
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import streamlit as st
|
2 |
|
3 |
+
from src.entity.document import DocumentNames
|
4 |
from src.forms.deviation_investigation_report import deviation_investigation_report_form
|
5 |
+
from src.forms.deviation_notification_report import (
|
6 |
+
deviation_notification_report_form,
|
7 |
+
deviation_notification_report_history_file_path,
|
8 |
+
)
|
9 |
+
from src.forms.history_common import display_download_history
|
|
|
10 |
|
11 |
selected_page = st.sidebar.selectbox(
|
12 |
+
"作成する文書を選択してください。", [name.value for name in DocumentNames]
|
13 |
)
|
14 |
+
|
15 |
match selected_page:
|
16 |
+
case DocumentNames.DEVIATION_NOTIFICATION_REPORT.value:
|
17 |
+
deviation_notification_report_form()
|
18 |
+
case DocumentNames.DEVIATION_INVESTIGATION_REPORT.value:
|
19 |
+
deviation_investigation_report_form()
|
20 |
+
case DocumentNames.DEVIATION_NOTIFICATION_REPORT_HISTORY.value:
|
21 |
+
display_download_history(
|
22 |
+
DocumentNames.DEVIATION_NOTIFICATION_REPORT.value,
|
23 |
+
deviation_notification_report_history_file_path,
|
24 |
+
)
|
src/aws/s3.py
CHANGED
@@ -10,9 +10,10 @@ from src.utils import setup_logger
|
|
10 |
logger = setup_logger(__name__)
|
11 |
|
12 |
trial_bucket_name = "pharma-doc-trials"
|
13 |
-
|
14 |
-
"
|
15 |
)
|
|
|
16 |
csv_extension = ".csv"
|
17 |
err_msg_file_is_not_csv = "指定したファイルはcsvではありません。"
|
18 |
|
|
|
10 |
logger = setup_logger(__name__)
|
11 |
|
12 |
trial_bucket_name = "pharma-doc-trials"
|
13 |
+
base_deviation_notification_report_history_file_path_in_trial_bucket = (
|
14 |
+
"taiyo/deviation_notification_report_history.csv"
|
15 |
)
|
16 |
+
|
17 |
csv_extension = ".csv"
|
18 |
err_msg_file_is_not_csv = "指定したファイルはcsvではありません。"
|
19 |
|
src/entity/document.py
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from enum import Enum
|
2 |
+
|
3 |
+
|
4 |
+
class DocumentNames(Enum):
|
5 |
+
DEVIATION_NOTIFICATION_REPORT = "逸脱連絡書"
|
6 |
+
DEVIATION_INVESTIGATION_REPORT = "逸脱調査報告書"
|
7 |
+
DEVIATION_NOTIFICATION_REPORT_HISTORY = "逸脱連絡履歴"
|
src/forms/deviation_notification_report.py
CHANGED
@@ -1,11 +1,25 @@
|
|
1 |
import json
|
2 |
import os
|
3 |
from datetime import date, datetime
|
|
|
|
|
4 |
|
|
|
5 |
import streamlit as st
|
6 |
from dotenv import load_dotenv
|
7 |
from openai import OpenAI
|
8 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
from src.prompts.deviation_notification_report import (
|
10 |
deviation_notification_system_template_review,
|
11 |
deviation_notification_systemprompt_output_format_instructions,
|
@@ -13,6 +27,11 @@ from src.prompts.deviation_notification_report import (
|
|
13 |
)
|
14 |
from src.utils import output_deviation_notification_report, setup_logger
|
15 |
|
|
|
|
|
|
|
|
|
|
|
16 |
OCCURRENCE_CLASSIFICATIONS = [
|
17 |
"",
|
18 |
"工程内外観",
|
@@ -282,8 +301,8 @@ def deviation_notification_report_form() -> None:
|
|
282 |
"課名": st.session_state["section_name"],
|
283 |
"発生場所": st.session_state["occurrence_place"],
|
284 |
"発見者": st.session_state["discoverer"],
|
285 |
-
"発生日": formatted_occurrence_date,
|
286 |
"発見日": formatted_discovery_date,
|
|
|
287 |
"品質保証課への第一報日": formatted_first_report_date,
|
288 |
"発生事象の分類": st.session_state["occurrence_classification"],
|
289 |
"逸脱概要": str(response_data["逸脱概要"]),
|
@@ -305,6 +324,35 @@ def deviation_notification_report_form() -> None:
|
|
305 |
)
|
306 |
|
307 |
output_deviation_notification_report(st.session_state["contents"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
308 |
st.session_state["document_generated"] = True
|
309 |
|
310 |
if st.session_state["document_generated"]:
|
@@ -321,6 +369,11 @@ def deviation_notification_report_form() -> None:
|
|
321 |
for key, value in st.session_state["contents"].items():
|
322 |
st.markdown(f"**{key}**: {value}")
|
323 |
|
|
|
|
|
|
|
|
|
|
|
324 |
deviation_notification_user_template_review = f"""
|
325 |
## 今回の「逸脱概要」:
|
326 |
{st.session_state["contents"]["逸脱概要"]}
|
@@ -348,3 +401,156 @@ def deviation_notification_report_form() -> None:
|
|
348 |
|
349 |
logger.info(f"**レビュー結果** : {review}")
|
350 |
st.markdown(f"**レビュー結果** : {review}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import json
|
2 |
import os
|
3 |
from datetime import date, datetime
|
4 |
+
from typing import Any, List
|
5 |
+
from zoneinfo import ZoneInfo
|
6 |
|
7 |
+
import pandas as pd
|
8 |
import streamlit as st
|
9 |
from dotenv import load_dotenv
|
10 |
from openai import OpenAI
|
11 |
|
12 |
+
from src.aws.s3 import (
|
13 |
+
base_deviation_notification_report_history_file_path_in_trial_bucket,
|
14 |
+
)
|
15 |
+
from src.aws.s3 import get_client as get_s3_client
|
16 |
+
from src.aws.s3 import (
|
17 |
+
get_csv_as_pd_dataframe_from_s3,
|
18 |
+
save_pd_dataframe_as_csv_to_s3,
|
19 |
+
trial_bucket_name,
|
20 |
+
)
|
21 |
+
from src.entity.document import DocumentNames
|
22 |
+
from src.forms.history_common import display_history
|
23 |
from src.prompts.deviation_notification_report import (
|
24 |
deviation_notification_system_template_review,
|
25 |
deviation_notification_systemprompt_output_format_instructions,
|
|
|
27 |
)
|
28 |
from src.utils import output_deviation_notification_report, setup_logger
|
29 |
|
30 |
+
deviation_notification_report_history_file_path = (
|
31 |
+
"data/deviation_notification_report_history.csv"
|
32 |
+
)
|
33 |
+
|
34 |
+
|
35 |
OCCURRENCE_CLASSIFICATIONS = [
|
36 |
"",
|
37 |
"工程内外観",
|
|
|
301 |
"課名": st.session_state["section_name"],
|
302 |
"発生場所": st.session_state["occurrence_place"],
|
303 |
"発見者": st.session_state["discoverer"],
|
|
|
304 |
"発見日": formatted_discovery_date,
|
305 |
+
"発生日": formatted_occurrence_date,
|
306 |
"品質保証課への第一報日": formatted_first_report_date,
|
307 |
"発生事象の分類": st.session_state["occurrence_classification"],
|
308 |
"逸脱概要": str(response_data["逸脱概要"]),
|
|
|
324 |
)
|
325 |
|
326 |
output_deviation_notification_report(st.session_state["contents"])
|
327 |
+
|
328 |
+
save_deviation_notification_report_history(
|
329 |
+
st.session_state["contents"]["件名"],
|
330 |
+
st.session_state["contents"]["管理番号"],
|
331 |
+
st.session_state["contents"]["品名"],
|
332 |
+
st.session_state["contents"]["品目コード"],
|
333 |
+
st.session_state["contents"]["工程名"],
|
334 |
+
st.session_state["contents"]["標準書番号"],
|
335 |
+
st.session_state["contents"]["ロット番号"],
|
336 |
+
st.session_state["contents"]["課名"],
|
337 |
+
st.session_state["contents"]["発生場所"],
|
338 |
+
st.session_state["contents"]["発見者"],
|
339 |
+
st.session_state["contents"]["発見日"],
|
340 |
+
st.session_state["contents"]["発生日"],
|
341 |
+
st.session_state["contents"]["品質保証課への第一報日"],
|
342 |
+
st.session_state["contents"]["発生事象の分類"],
|
343 |
+
st.session_state["contents"]["逸脱概要"],
|
344 |
+
st.session_state["contents"]["応急措置"],
|
345 |
+
st.session_state["contents"]["調査(根本原因・品質影響等)の提案"],
|
346 |
+
st.session_state["contents"]["調査の実施部署"],
|
347 |
+
st.session_state["contents"][
|
348 |
+
"措置(回復措置・製品等に対する措置)の提案"
|
349 |
+
],
|
350 |
+
st.session_state["contents"]["措置の実施部署"],
|
351 |
+
st.session_state["contents"]["調査回答期限(30営業日)"],
|
352 |
+
st.session_state["contents"]["添付資料"],
|
353 |
+
answers,
|
354 |
+
)
|
355 |
+
|
356 |
st.session_state["document_generated"] = True
|
357 |
|
358 |
if st.session_state["document_generated"]:
|
|
|
369 |
for key, value in st.session_state["contents"].items():
|
370 |
st.markdown(f"**{key}**: {value}")
|
371 |
|
372 |
+
display_history(
|
373 |
+
DocumentNames.DEVIATION_NOTIFICATION_REPORT.value,
|
374 |
+
deviation_notification_report_history_file_path,
|
375 |
+
)
|
376 |
+
|
377 |
deviation_notification_user_template_review = f"""
|
378 |
## 今回の「逸脱概要」:
|
379 |
{st.session_state["contents"]["逸脱概要"]}
|
|
|
401 |
|
402 |
logger.info(f"**レビュー結果** : {review}")
|
403 |
st.markdown(f"**レビュー結果** : {review}")
|
404 |
+
|
405 |
+
|
406 |
+
def save_deviation_notification_report_history(
|
407 |
+
subject: str,
|
408 |
+
control_number: str,
|
409 |
+
product_name: str,
|
410 |
+
item_code: str,
|
411 |
+
process_name: str,
|
412 |
+
standard_number: str,
|
413 |
+
lot_number: str,
|
414 |
+
section_name: str,
|
415 |
+
occurrence_place: str,
|
416 |
+
discoverer: str,
|
417 |
+
discovery_date: str,
|
418 |
+
occurrence_date: str,
|
419 |
+
first_report_date: str,
|
420 |
+
occurrence_classification: str,
|
421 |
+
output_deviation_summary: str,
|
422 |
+
output_emergency_measures: str,
|
423 |
+
output_proposed_investigation: str,
|
424 |
+
investigation_department: str,
|
425 |
+
output_proposed_measures: str,
|
426 |
+
measures_department: str,
|
427 |
+
survey_response_deadline: str,
|
428 |
+
attached_files: str,
|
429 |
+
answers: List[str],
|
430 |
+
) -> None:
|
431 |
+
s3_client = get_s3_client()
|
432 |
+
try:
|
433 |
+
env = os.environ["ENV"]
|
434 |
+
if env != "production":
|
435 |
+
file_name, file_extension = os.path.splitext(
|
436 |
+
base_deviation_notification_report_history_file_path_in_trial_bucket
|
437 |
+
)
|
438 |
+
deviation_notification_report_history_file_path_in_trial_bucket = (
|
439 |
+
f"{file_name}_{env}{file_extension}"
|
440 |
+
)
|
441 |
+
else:
|
442 |
+
deviation_notification_report_history_file_path_in_trial_bucket = (
|
443 |
+
base_deviation_notification_report_history_file_path_in_trial_bucket
|
444 |
+
)
|
445 |
+
df = get_csv_as_pd_dataframe_from_s3(
|
446 |
+
s3_client,
|
447 |
+
trial_bucket_name,
|
448 |
+
deviation_notification_report_history_file_path_in_trial_bucket,
|
449 |
+
)
|
450 |
+
except s3_client.exceptions.NoSuchKey:
|
451 |
+
df = pd.DataFrame()
|
452 |
+
|
453 |
+
new_row_data = create_new_row_data(
|
454 |
+
subject,
|
455 |
+
control_number,
|
456 |
+
product_name,
|
457 |
+
item_code,
|
458 |
+
process_name,
|
459 |
+
standard_number,
|
460 |
+
lot_number,
|
461 |
+
section_name,
|
462 |
+
occurrence_place,
|
463 |
+
discoverer,
|
464 |
+
discovery_date,
|
465 |
+
occurrence_date,
|
466 |
+
first_report_date,
|
467 |
+
occurrence_classification,
|
468 |
+
output_deviation_summary,
|
469 |
+
output_emergency_measures,
|
470 |
+
output_proposed_investigation,
|
471 |
+
investigation_department,
|
472 |
+
output_proposed_measures,
|
473 |
+
measures_department,
|
474 |
+
survey_response_deadline,
|
475 |
+
attached_files,
|
476 |
+
answers,
|
477 |
+
)
|
478 |
+
|
479 |
+
new_row = pd.DataFrame([new_row_data])
|
480 |
+
df = pd.concat([df, new_row], ignore_index=True)
|
481 |
+
|
482 |
+
# NOTE: トライアル版のため、排他制御は実施しない。バケットはバージョニングする。
|
483 |
+
save_pd_dataframe_as_csv_to_s3(
|
484 |
+
s3_client,
|
485 |
+
df,
|
486 |
+
trial_bucket_name,
|
487 |
+
deviation_notification_report_history_file_path_in_trial_bucket,
|
488 |
+
)
|
489 |
+
|
490 |
+
|
491 |
+
def create_new_row_data(
|
492 |
+
subject: str,
|
493 |
+
control_number: str,
|
494 |
+
product_name: str,
|
495 |
+
item_code: str,
|
496 |
+
process_name: str,
|
497 |
+
standard_number: str,
|
498 |
+
lot_number: str,
|
499 |
+
section_name: str,
|
500 |
+
occurrence_place: str,
|
501 |
+
discoverer: str,
|
502 |
+
discovery_date: str,
|
503 |
+
occurrence_date: str,
|
504 |
+
first_report_date: str,
|
505 |
+
occurrence_classification: str,
|
506 |
+
output_deviation_summary: str,
|
507 |
+
output_emergency_measures: str,
|
508 |
+
output_proposed_investigation: str,
|
509 |
+
investigation_department: str,
|
510 |
+
output_proposed_measures: str,
|
511 |
+
measures_department: str,
|
512 |
+
survey_response_deadline: str,
|
513 |
+
attached_files: str,
|
514 |
+
answers: List[str],
|
515 |
+
) -> dict[str, Any]:
|
516 |
+
now = datetime.now(ZoneInfo("Asia/Tokyo"))
|
517 |
+
data = {
|
518 |
+
"件名": subject,
|
519 |
+
"作成日時": now,
|
520 |
+
"管理番号": control_number,
|
521 |
+
"品名": product_name,
|
522 |
+
"品目コード": item_code,
|
523 |
+
"工程名": process_name,
|
524 |
+
"標準書番号": standard_number,
|
525 |
+
"ロット番号": lot_number,
|
526 |
+
"課名": section_name,
|
527 |
+
"発生場所": occurrence_place,
|
528 |
+
"発見者": discoverer,
|
529 |
+
"発見日": discovery_date,
|
530 |
+
"発生日": occurrence_date,
|
531 |
+
"品質保証課への第一報日": first_report_date,
|
532 |
+
"発生事象の分類": occurrence_classification,
|
533 |
+
"逸脱概要": output_deviation_summary,
|
534 |
+
"応急処置": output_emergency_measures,
|
535 |
+
"調査(根本原因・品質影響等)の提案": output_proposed_investigation,
|
536 |
+
"調査の実施部署": investigation_department,
|
537 |
+
"措置(回復措置・製品等に対する措置)の提案": output_proposed_measures,
|
538 |
+
"措置の実施部署": measures_department,
|
539 |
+
"調査回答期限(30営業日)": survey_response_deadline,
|
540 |
+
"添付資料": attached_files,
|
541 |
+
"逸脱内容(回答)": answers[0],
|
542 |
+
"発見の経緯(回答)": answers[1],
|
543 |
+
"応急処置とその理由(回答)": answers[2],
|
544 |
+
"当該ロットの品質評価(回答)": answers[3],
|
545 |
+
"安定性モニタリングの対象ロットか(回答)": answers[4],
|
546 |
+
"安定性モニタリングの検体採取表の更新(回答)": answers[5],
|
547 |
+
"在庫ロットの品質評価・状況確認(回答)": answers[6],
|
548 |
+
"メーカーへの調査依頼(回答)": answers[7],
|
549 |
+
"生産スケジュール・受注状況の変更(回答)": answers[8],
|
550 |
+
"出荷日の変更(回答)": answers[9],
|
551 |
+
"製造販売業者への連絡(回答)": answers[10],
|
552 |
+
"他製品・他ラインへの影響(回答)": answers[11],
|
553 |
+
"過去製造ロットの品質の再評価(回答)": answers[12],
|
554 |
+
"その他の調査・措置(回答)": answers[13],
|
555 |
+
}
|
556 |
+
return data
|
src/forms/history_common.py
ADDED
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
|
3 |
+
import streamlit as st
|
4 |
+
|
5 |
+
from src.aws.s3 import (
|
6 |
+
base_deviation_notification_report_history_file_path_in_trial_bucket,
|
7 |
+
get_client,
|
8 |
+
get_csv_as_pd_dataframe_from_s3,
|
9 |
+
trial_bucket_name,
|
10 |
+
)
|
11 |
+
from src.entity.document import DocumentNames
|
12 |
+
|
13 |
+
|
14 |
+
def display_history(document_name: str, history_file_path: str) -> None:
|
15 |
+
match document_name:
|
16 |
+
case DocumentNames.DEVIATION_NOTIFICATION_REPORT.value:
|
17 |
+
base_history_file_path_in_trial_bucket = (
|
18 |
+
base_deviation_notification_report_history_file_path_in_trial_bucket
|
19 |
+
)
|
20 |
+
|
21 |
+
s3_client = get_client()
|
22 |
+
env = os.environ["ENV"]
|
23 |
+
if env != "production":
|
24 |
+
file_name, file_extension = os.path.splitext(
|
25 |
+
base_history_file_path_in_trial_bucket
|
26 |
+
)
|
27 |
+
history_file_path_in_trial_bucket = f"{file_name}_{env}{file_extension}"
|
28 |
+
else:
|
29 |
+
history_file_path_in_trial_bucket = base_history_file_path_in_trial_bucket
|
30 |
+
data = get_csv_as_pd_dataframe_from_s3(
|
31 |
+
s3_client,
|
32 |
+
trial_bucket_name,
|
33 |
+
history_file_path_in_trial_bucket,
|
34 |
+
)
|
35 |
+
data.to_csv(history_file_path, index=False)
|
36 |
+
st.write(f"**{document_name}作成履歴**")
|
37 |
+
st.dataframe(data)
|
38 |
+
return
|
39 |
+
|
40 |
+
|
41 |
+
def display_download_history(document_name: str, history_file_path: str) -> None:
|
42 |
+
match document_name:
|
43 |
+
case DocumentNames.DEVIATION_NOTIFICATION_REPORT.value:
|
44 |
+
base_history_file_path_in_trial_bucket = (
|
45 |
+
base_deviation_notification_report_history_file_path_in_trial_bucket
|
46 |
+
)
|
47 |
+
|
48 |
+
s3_client = get_client()
|
49 |
+
try:
|
50 |
+
env = os.environ["ENV"]
|
51 |
+
if env != "production":
|
52 |
+
file_name, file_extension = os.path.splitext(
|
53 |
+
base_history_file_path_in_trial_bucket
|
54 |
+
)
|
55 |
+
history_file_path_in_trial_bucket = f"{file_name}_{env}{file_extension}"
|
56 |
+
else:
|
57 |
+
history_file_path_in_trial_bucket = base_history_file_path_in_trial_bucket
|
58 |
+
data = get_csv_as_pd_dataframe_from_s3(
|
59 |
+
s3_client,
|
60 |
+
trial_bucket_name,
|
61 |
+
history_file_path_in_trial_bucket,
|
62 |
+
)
|
63 |
+
except s3_client.exceptions.NoSuchKey:
|
64 |
+
st.write(f"{document_name}作成履歴がありません。")
|
65 |
+
return
|
66 |
+
except Exception:
|
67 |
+
st.error(
|
68 |
+
f"システムの内部エラーにより、{document_name}作成履歴の表示ができません。システム管理者に問い合わせて下さい。"
|
69 |
+
)
|
70 |
+
return
|
71 |
+
data.to_csv(history_file_path, index=False)
|
72 |
+
st.write(f"**{document_name}作成履歴**")
|
73 |
+
st.dataframe(data)
|
74 |
+
file_exists = os.path.isfile(history_file_path)
|
75 |
+
if file_exists:
|
76 |
+
with open(history_file_path, "rb") as file:
|
77 |
+
st.download_button(
|
78 |
+
label="ダウンロード",
|
79 |
+
data=file,
|
80 |
+
file_name="history.csv",
|
81 |
+
mime="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
82 |
+
)
|
83 |
+
else:
|
84 |
+
st.error(
|
85 |
+
f"システムの内部エラーにより、{document_name}作成履歴の表示ができません。システム管理者に問い合わせて下さい。"
|
86 |
+
)
|
87 |
+
return
|