nlpblogs commited on
Commit
ae217ed
·
verified ·
1 Parent(s): 9c28e92

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +198 -0
app.py ADDED
@@ -0,0 +1,198 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from cryptography.fernet import Fernet
3
+ import time
4
+ import pandas as pd
5
+ import io
6
+ from transformers import pipeline
7
+ from streamlit_extras.stylable_container import stylable_container
8
+ import json
9
+
10
+ st.subheader("Table Question Answering (QA)", divider="blue")
11
+
12
+ # generate Fernet key
13
+ if 'fernet_key' not in st.session_state:
14
+ st.session_state.fernet_key = Fernet.generate_key()
15
+
16
+ key = st.session_state.fernet_key
17
+
18
+
19
+ # function for generating and validating fernet key
20
+ def generate_fernet_token(key, data):
21
+ fernet = Fernet(key)
22
+ token = fernet.encrypt(data.encode())
23
+ return token
24
+
25
+ def validate_fernet_token(key, token, ttl_seconds):
26
+
27
+ fernet = Fernet(key)
28
+ try:
29
+ decrypted_data = fernet.decrypt(token, ttl=ttl_seconds).decode()
30
+ return decrypted_data, None
31
+ except Exception as e:
32
+ return None, f"Expired token: {e}"
33
+
34
+ # sidebar
35
+ with st.sidebar:
36
+ with stylable_container(
37
+ key="test_button",
38
+ css_styles="""
39
+ button {
40
+ background-color: yellow;
41
+ border: 1px solid black;
42
+ padding: 5px;
43
+ color: black;
44
+ }
45
+ """,
46
+ ):
47
+ st.button("ONE-DAY SUBSCRIPTION")
48
+
49
+
50
+ expander = st.expander("**Important notes on the Table Question Answering (QA) App**")
51
+ expander.write('''
52
+
53
+ **Supported File Formats**
54
+ This app accepts files in .csv and .xlsx formats.
55
+
56
+
57
+ **How to Use**
58
+ Upload your file first. Then, type your question into the text area provided and click the 'Retrieve your answer' button.
59
+
60
+
61
+ **Usage Limits**
62
+ You can ask up to 30 questions per day. Once you reach this limit, you will need to wait until the daily automatic renewal to continue using the app. The app's daily renewal occurs automatically.
63
+
64
+
65
+ **Subscription Management**
66
+ This app uses a one-day subscription plan. To cancel your subscription, please visit your Account settings.
67
+
68
+
69
+ **Authorization**
70
+ For security purposes, your authorization access expires hourly. To restore access, click the "Request Authorization" button. A file must be uploaded before you can request authorization.
71
+
72
+
73
+ **Customization**
74
+ To change the app's background color to white or black, click the three-dot menu on the right-hand side of your app, go to Settings and then Choose app theme, colors and fonts.
75
+
76
+
77
+ **File Handling and Errors**
78
+ The app may display an error message if your file is corrupt, contains missing values, or has other errors.
79
+ To get your file cleaned and pre-processed before using this QA app, please use our Text Preprocessing Service which can be found in the navigation menu of our website: https://nlpblogs.com/
80
+
81
+ For any other errors or inquiries, please contact us at [email protected]
82
+
83
+ ''')
84
+
85
+
86
+ # count attempts based on questions
87
+ if 'question_attempts' not in st.session_state:
88
+ st.session_state['question_attempts'] = 0
89
+
90
+ max_attempts = 3
91
+
92
+ # upload file
93
+ upload_file = st.file_uploader("Upload your file. Accepted file formats include: .csv, .xlsx", type=['csv', 'xlsx'])
94
+ df = None
95
+
96
+ if upload_file is not None:
97
+ file_extension = upload_file.name.split('.')[-1].lower()
98
+ if file_extension == 'csv':
99
+ try:
100
+ df = pd.read_csv(io.StringIO(upload_file.getvalue().decode("utf-8")))
101
+ if df.isnull().values.any():
102
+ st.error("Error: The CSV file contains missing values.")
103
+ st.stop()
104
+ else:
105
+ new_columns = [f'column_{i+1}' for i in range(len(df.columns))]
106
+ df.columns = new_columns
107
+
108
+ st.dataframe(df, key="csv_dataframe")
109
+ st.write("_number of rows_", df.shape[0])
110
+ st.write("_number of columns_", df.shape[1])
111
+ except pd.errors.ParserError:
112
+ st.error("Error: The CSV file is not readable or is incorrectly formatted.")
113
+ st.stop()
114
+ except UnicodeDecodeError:
115
+ st.error("Error: The CSV file could not be decoded.")
116
+ st.stop()
117
+ except Exception as e:
118
+ st.error(f"An unexpected error occurred while reading CSV: {e}")
119
+ st.stop()
120
+ elif file_extension == 'xlsx':
121
+ try:
122
+ df = pd.read_excel(io.BytesIO(upload_file.getvalue()))
123
+ if df.isnull().values.any():
124
+ st.error("Error: The Excel file contains missing values.")
125
+ st.stop()
126
+ else:
127
+ new_columns = [f'column_{i+1}' for i in range(len(df.columns))]
128
+ df.columns = new_columns
129
+ st.dataframe(df, key="excel_dataframe")
130
+ st.write("_number of rows_", df.shape[0])
131
+ st.write("_number of columns_", df.shape[1])
132
+ except ValueError:
133
+ st.error("Error: The Excel file is not readable or is incorrectly formatted.")
134
+ st.stop()
135
+ except Exception as e:
136
+ st.error(f"An unexpected error occurred while reading Excel: {e}")
137
+ st.stop()
138
+ else:
139
+ st.warning("Unsupported file type.")
140
+ st.stop()
141
+
142
+ # generate and validate Fernet token for the current file
143
+ if 'fernet_token' not in st.session_state:
144
+ if df is not None:
145
+ st.session_state.fernet_token = generate_fernet_token(key, df.to_json())
146
+ else:
147
+ st.stop()
148
+
149
+ decrypted_data_streamlit, error_streamlit = validate_fernet_token(key, st.session_state.fernet_token, ttl_seconds=10)
150
+
151
+ if error_streamlit:
152
+ st.warning("Please press Request Authorization. Please note that a file should be uploaded before you press Request Authorization.")
153
+ if st.button("Request Authorization"):
154
+ st.session_state.fernet_token = generate_fernet_token(key, df.to_json())
155
+ st.success("Authorization granted")
156
+ decrypted_data_streamlit, error_streamlit = validate_fernet_token(key, st.session_state.fernet_token, ttl_seconds=10)
157
+ if error_streamlit:
158
+ st.error(f"Your authorization has expired: {error_streamlit}")
159
+ st.stop()
160
+ if error_streamlit:
161
+ st.error("Please upload a file.")
162
+ st.stop()
163
+ else:
164
+ try:
165
+ df = pd.read_json(decrypted_data_streamlit)
166
+ except Exception as e:
167
+ st.error(f"Error decoding data: {e}")
168
+ st.stop()
169
+ else:
170
+ st.error(f"Your authorization has expired: {error_streamlit}")
171
+ st.stop()
172
+
173
+ st.divider()
174
+
175
+ # ask question
176
+ def clear_question():
177
+ st.session_state["question"] = ""
178
+
179
+ question = st.text_input("Type your question here and then press **Retrieve your answer**:", key="question")
180
+ st.button("Clear question", on_click=clear_question)
181
+
182
+ #retrive answer
183
+ if st.button("Retrieve your answer"):
184
+ if st.session_state['question_attempts'] >= max_attempts:
185
+ st.error(f"You have asked {max_attempts} questions. You have reached your daily request limit. Your subscription will renew automatically. To cancel, please go to your Account.")
186
+ st.stop()
187
+ st.session_state['question_attempts'] += 1
188
+ if error_streamlit:
189
+ st.warning("Please enter a question before retrieving the answer.")
190
+ else:
191
+ with st.spinner('Wait for it...'):
192
+ time.sleep(2)
193
+ if df is not None:
194
+ tqa = pipeline(task="table-question-answering", model="google/tapas-base-finetuned-wikisql-supervised")
195
+ st.write(tqa(table=df, query=question)['answer'])
196
+
197
+ st.divider()
198
+ st.write(f"Number of questions asked: {st.session_state['question_attempts']}/{max_attempts}")