Spaces:
Sleeping
Sleeping
レビューを元に修正
Browse files- .env.example +2 -0
- .gitignore +1 -0
- README.md +3 -1
- data/inputInfo.csv +0 -0
- requirements.txt +4 -2
- src/aws/s3.py +38 -0
- src/database.py +82 -31
- src/forms/change_request.py +22 -12
.env.example
CHANGED
@@ -1,2 +1,4 @@
|
|
1 |
OPENAI_API_KEY=XXX
|
2 |
PINECONE_API_KEY=YYY
|
|
|
|
|
|
1 |
OPENAI_API_KEY=XXX
|
2 |
PINECONE_API_KEY=YYY
|
3 |
+
AWS_ACCESS_KEY_ID=ZZZ
|
4 |
+
AWS_SECRET_ACCESS_KEY=AAA
|
.gitignore
CHANGED
@@ -163,6 +163,7 @@ cython_debug/
|
|
163 |
.DS_Store
|
164 |
|
165 |
# 申請書/報告書はリポジトリにはアップロードしない。
|
|
|
166 |
data/output.docx
|
167 |
data/output_deviation.docx
|
168 |
data/output_deviation_occurrence.docx
|
|
|
163 |
.DS_Store
|
164 |
|
165 |
# 申請書/報告書はリポジトリにはアップロードしない。
|
166 |
+
data/inputInfo.csv
|
167 |
data/output.docx
|
168 |
data/output_deviation.docx
|
169 |
data/output_deviation_occurrence.docx
|
README.md
CHANGED
@@ -17,7 +17,9 @@ license: other
|
|
17 |
## 1. .env.exampleを参考に.envを作成し、OpenAIとPINECONEのAPIキーを設定
|
18 |
```
|
19 |
OPENAI_API_KEY =
|
20 |
-
PINECONE_API_KEY
|
|
|
|
|
21 |
```
|
22 |
値はnotionで管理されているので、参照する。
|
23 |
[OpenAI API](https://www.notion.so/equesai/OpenAI-API-b2029c9b5d774eaebd7318a702ec31f1?pvs=4)
|
|
|
17 |
## 1. .env.exampleを参考に.envを作成し、OpenAIとPINECONEのAPIキーを設定
|
18 |
```
|
19 |
OPENAI_API_KEY =
|
20 |
+
PINECONE_API_KEY =
|
21 |
+
AWS_ACCESS_KEY_ID =
|
22 |
+
AWS_SECRET_ACCESS_KEY =
|
23 |
```
|
24 |
値はnotionで管理されているので、参照する。
|
25 |
[OpenAI API](https://www.notion.so/equesai/OpenAI-API-b2029c9b5d774eaebd7318a702ec31f1?pvs=4)
|
data/inputInfo.csv
DELETED
File without changes
|
requirements.txt
CHANGED
@@ -8,7 +8,9 @@ streamlit == 1.36.0
|
|
8 |
python-docx == 1.1.2
|
9 |
pinecone-client == 4.1.2
|
10 |
pre-commit == 3.7.1
|
|
|
|
|
11 |
pandas-stubs == 2.2.2.240603
|
12 |
boto3-stubs == 1.34.149
|
13 |
-
fsspec
|
14 |
-
s3fs
|
|
|
8 |
python-docx == 1.1.2
|
9 |
pinecone-client == 4.1.2
|
10 |
pre-commit == 3.7.1
|
11 |
+
pandas == 2.2.2
|
12 |
+
boto3 == 1.34.131
|
13 |
pandas-stubs == 2.2.2.240603
|
14 |
boto3-stubs == 1.34.149
|
15 |
+
# fsspec == 2024.6.1
|
16 |
+
# s3fs == 2024.6.1
|
src/aws/s3.py
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from io import StringIO
|
2 |
+
from typing import List
|
3 |
+
|
4 |
+
import boto3
|
5 |
+
import pandas as pd
|
6 |
+
|
7 |
+
s3 = boto3.client("s3")
|
8 |
+
bucket_name = "eques-pharma-docs"
|
9 |
+
# bucket_name = "bankyo-pharmaceutical"
|
10 |
+
|
11 |
+
|
12 |
+
# Download the CSV file from S3
|
13 |
+
def download_csv_from_s3(file_name: str) -> pd.DataFrame:
|
14 |
+
obj = s3.get_object(Bucket=bucket_name, Key=file_name)
|
15 |
+
data = pd.read_csv(obj["Body"])
|
16 |
+
return data
|
17 |
+
|
18 |
+
|
19 |
+
def save_to_s3(data: pd.DataFrame, file_name: str) -> None:
|
20 |
+
csv_buffer = StringIO()
|
21 |
+
data.to_csv(csv_buffer, index=False)
|
22 |
+
s3.put_object(Bucket=bucket_name, Key=file_name, Body=csv_buffer.getvalue())
|
23 |
+
|
24 |
+
|
25 |
+
def get_all_objects() -> List[str]:
|
26 |
+
response = s3.list_objects_v2(Bucket=bucket_name)
|
27 |
+
csv_files = [
|
28 |
+
obj["Key"]
|
29 |
+
for obj in response.get("Contents", [])
|
30 |
+
if obj["Key"].endswith(".csv")
|
31 |
+
]
|
32 |
+
return csv_files
|
33 |
+
|
34 |
+
|
35 |
+
def get_csv_content(file_name: str) -> pd.DataFrame:
|
36 |
+
obj = s3.get_object(Bucket=bucket_name, Key=file_name)
|
37 |
+
df = pd.read_csv(obj["Body"])
|
38 |
+
return df.iloc[0]
|
src/database.py
CHANGED
@@ -1,54 +1,105 @@
|
|
1 |
-
|
|
|
2 |
from typing import List
|
3 |
|
4 |
-
import boto3
|
5 |
import pandas as pd
|
6 |
import streamlit as st
|
7 |
|
8 |
-
|
9 |
|
10 |
-
# Initialize the S3 client
|
11 |
-
s3 = boto3.client("s3")
|
12 |
-
|
13 |
-
# Specify the bucket name and file name
|
14 |
bucket_name = "eques-pharma-docs"
|
15 |
-
file_name = "inputInfo.csv"
|
16 |
-
|
17 |
-
|
18 |
-
# Download the CSV file from S3
|
19 |
-
def download_csv_from_s3(bucket_name: str, file_name: str) -> pd.DataFrame:
|
20 |
-
obj = s3.get_object(Bucket=bucket_name, Key=file_name)
|
21 |
-
data = pd.read_csv(obj["Body"])
|
22 |
-
return data
|
23 |
|
24 |
|
25 |
def write_csv(
|
26 |
-
|
27 |
-
company_name: str,
|
28 |
change_type: List[str],
|
29 |
-
|
30 |
-
|
31 |
input: str,
|
32 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
) -> None:
|
34 |
all_types = []
|
35 |
for i in range(len(change_type)):
|
36 |
-
all_type = [i + 1, change_type[i],
|
37 |
all_types.append(all_type)
|
38 |
|
39 |
-
|
40 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
new_data = pd.DataFrame(
|
42 |
-
[
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
)
|
44 |
-
data = pd.concat([data, new_data], ignore_index=True)
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
|
49 |
|
50 |
def display_csv() -> None:
|
51 |
-
|
52 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
st.write("**データベース**")
|
54 |
-
|
|
|
|
1 |
+
import csv
|
2 |
+
from datetime import datetime
|
3 |
from typing import List
|
4 |
|
5 |
+
# import boto3
|
6 |
import pandas as pd
|
7 |
import streamlit as st
|
8 |
|
9 |
+
from src.aws.s3 import get_all_objects, get_csv_content, save_to_s3
|
10 |
|
|
|
|
|
|
|
|
|
11 |
bucket_name = "eques-pharma-docs"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
|
13 |
|
14 |
def write_csv(
|
15 |
+
applicant_name: str,
|
|
|
16 |
change_type: List[str],
|
17 |
+
category: List[str],
|
18 |
+
subcategory: List[str],
|
19 |
input: str,
|
20 |
+
output_factory: str,
|
21 |
+
output_username: str,
|
22 |
+
output_date: str,
|
23 |
+
output_change_target: str,
|
24 |
+
output_change_period: str,
|
25 |
+
output_change_content: str,
|
26 |
+
output_change_reason: str,
|
27 |
+
output_effect: str,
|
28 |
+
output_resource: str,
|
29 |
+
output_other: str,
|
30 |
) -> None:
|
31 |
all_types = []
|
32 |
for i in range(len(change_type)):
|
33 |
+
all_type = [i + 1, change_type[i], category[i], subcategory[i]]
|
34 |
all_types.append(all_type)
|
35 |
|
36 |
+
column_names = [
|
37 |
+
"申請者",
|
38 |
+
"全ての変更タイプ",
|
39 |
+
"入力",
|
40 |
+
"出力:工場",
|
41 |
+
"出力:申請者名",
|
42 |
+
"出力:申請日",
|
43 |
+
"出力:変更対象",
|
44 |
+
"出力:実施予定時期",
|
45 |
+
"出力:変更内容",
|
46 |
+
"出力:変更理由",
|
47 |
+
"出力:品質への影響",
|
48 |
+
"出力:参考資料",
|
49 |
+
"出力:備考",
|
50 |
+
]
|
51 |
new_data = pd.DataFrame(
|
52 |
+
[
|
53 |
+
[
|
54 |
+
applicant_name,
|
55 |
+
all_types,
|
56 |
+
input,
|
57 |
+
output_factory,
|
58 |
+
output_username,
|
59 |
+
output_date,
|
60 |
+
output_change_target,
|
61 |
+
output_change_period,
|
62 |
+
output_change_content,
|
63 |
+
output_change_reason,
|
64 |
+
output_effect,
|
65 |
+
output_resource,
|
66 |
+
output_other,
|
67 |
+
]
|
68 |
+
],
|
69 |
+
columns=column_names,
|
70 |
)
|
71 |
+
# data = pd.concat([data, new_data], ignore_index=True)
|
72 |
+
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
73 |
+
file_name = f"{timestamp}.csv"
|
74 |
+
save_to_s3(new_data, file_name)
|
75 |
|
76 |
|
77 |
def display_csv() -> None:
|
78 |
+
datas = get_all_objects()
|
79 |
+
header = [
|
80 |
+
"申請者",
|
81 |
+
"全ての変更タイプ",
|
82 |
+
"入力",
|
83 |
+
"出力:工場",
|
84 |
+
"出力:申請者名",
|
85 |
+
"出力:申請日",
|
86 |
+
"出力:変更対象",
|
87 |
+
"出力:実施予定時期",
|
88 |
+
"出力:変更内容",
|
89 |
+
"出力:変更理由",
|
90 |
+
"出力:品質への影響",
|
91 |
+
"出力:参考資料",
|
92 |
+
"出力:備考",
|
93 |
+
]
|
94 |
+
path = "data/inputsData.csv"
|
95 |
+
with open(path, mode="w", newline="") as file:
|
96 |
+
writer = csv.writer(file)
|
97 |
+
writer.writerow(header)
|
98 |
+
if datas:
|
99 |
+
for data in datas:
|
100 |
+
data = get_csv_content(data)
|
101 |
+
writer.writerow(data)
|
102 |
+
# datas.to_csv("data/inputInfo.csv", index=False)
|
103 |
st.write("**データベース**")
|
104 |
+
df = pd.read_csv(path)
|
105 |
+
st.dataframe(df)
|
src/forms/change_request.py
CHANGED
@@ -280,10 +280,10 @@ def change_request_form() -> None:
|
|
280 |
st.session_state[f"category_{change_serial_number}"],
|
281 |
st.session_state[f"subcategory_{change_serial_number}"],
|
282 |
)
|
283 |
-
for
|
284 |
next_question_number = len(question_about_this_change) + 1
|
285 |
question_about_this_change.append(
|
286 |
-
f"Q{change_serial_number}-{next_question_number} : {individual_questions[
|
287 |
)
|
288 |
question_about_this_change.append(
|
289 |
f"Q{change_serial_number}-"
|
@@ -427,26 +427,36 @@ def change_request_form() -> None:
|
|
427 |
output_change_application(st.session_state["contents"])
|
428 |
|
429 |
type = []
|
430 |
-
|
431 |
-
|
432 |
|
433 |
-
for
|
434 |
-
|
435 |
-
|
|
|
|
|
436 |
st.session_state[f"category_{change_serial_number}"]
|
437 |
)
|
438 |
-
|
439 |
st.session_state[f"subcategory_{change_serial_number}"]
|
440 |
)
|
441 |
|
442 |
write_csv(
|
443 |
st.session_state["applicant_name"],
|
444 |
-
"A社",
|
445 |
type,
|
446 |
-
|
447 |
-
|
448 |
user_prompt,
|
449 |
-
st.session_state["contents"],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
450 |
)
|
451 |
st.session_state["document_generated"] = True
|
452 |
|
|
|
280 |
st.session_state[f"category_{change_serial_number}"],
|
281 |
st.session_state[f"subcategory_{change_serial_number}"],
|
282 |
)
|
283 |
+
for change_serial_number in range(len(individual_questions)):
|
284 |
next_question_number = len(question_about_this_change) + 1
|
285 |
question_about_this_change.append(
|
286 |
+
f"Q{change_serial_number}-{next_question_number} : {individual_questions[change_serial_number]}"
|
287 |
)
|
288 |
question_about_this_change.append(
|
289 |
f"Q{change_serial_number}-"
|
|
|
427 |
output_change_application(st.session_state["contents"])
|
428 |
|
429 |
type = []
|
430 |
+
category = []
|
431 |
+
subcategory = []
|
432 |
|
433 |
+
for change_serial_number in range(
|
434 |
+
start_from_one, change_number + upper_bound_correction
|
435 |
+
):
|
436 |
+
type.append(st.session_state[f"type_{change_serial_number}"])
|
437 |
+
category.append(
|
438 |
st.session_state[f"category_{change_serial_number}"]
|
439 |
)
|
440 |
+
subcategory.append(
|
441 |
st.session_state[f"subcategory_{change_serial_number}"]
|
442 |
)
|
443 |
|
444 |
write_csv(
|
445 |
st.session_state["applicant_name"],
|
|
|
446 |
type,
|
447 |
+
category,
|
448 |
+
subcategory,
|
449 |
user_prompt,
|
450 |
+
st.session_state["contents"]["工場"],
|
451 |
+
st.session_state["contents"]["申請者"],
|
452 |
+
st.session_state["contents"]["申請日"],
|
453 |
+
st.session_state["contents"]["変更対象"],
|
454 |
+
st.session_state["contents"]["実施予定時期"],
|
455 |
+
st.session_state["contents"]["変更内容"],
|
456 |
+
st.session_state["contents"]["変更理由"],
|
457 |
+
st.session_state["contents"]["品質への影響"],
|
458 |
+
st.session_state["contents"]["添付資料"],
|
459 |
+
st.session_state["contents"]["備考"],
|
460 |
)
|
461 |
st.session_state["document_generated"] = True
|
462 |
|