Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -7,21 +7,23 @@ from oauth2client.service_account import ServiceAccountCredentials
|
|
7 |
import PyPDF2
|
8 |
import io
|
9 |
|
10 |
-
# Set up OpenAI client
|
11 |
-
client = OpenAI(api_key=st.secrets["OPENAI_API_KEY"])
|
12 |
-
|
13 |
# Constants
|
14 |
WORD_LIMIT = 8000
|
|
|
15 |
|
16 |
-
#
|
|
|
|
|
|
|
17 |
scope = ["https://spreadsheets.google.com/feeds", "https://www.googleapis.com/auth/drive"]
|
18 |
creds = ServiceAccountCredentials.from_json_keyfile_name("genexam-2c8c645ecc0d.json", scope)
|
19 |
client_gs = gspread.authorize(creds)
|
20 |
sheet = client_gs.open("GeneXam user").sheet1
|
21 |
|
22 |
def check_user_in_sheet(username):
|
|
|
23 |
try:
|
24 |
-
users_list = sheet.col_values(1)
|
25 |
if username in users_list:
|
26 |
return True
|
27 |
return False
|
@@ -29,15 +31,59 @@ def check_user_in_sheet(username):
|
|
29 |
st.error(f"Error checking user: {str(e)}")
|
30 |
return False
|
31 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
def update_api_usage(username):
|
|
|
33 |
try:
|
34 |
users_list = sheet.col_values(1)
|
35 |
row_number = users_list.index(username) + 1
|
36 |
-
|
37 |
-
|
38 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
except Exception as e:
|
40 |
-
|
41 |
|
42 |
def extract_text_from_pdf(pdf_file):
|
43 |
"""Simple PDF text extraction with word limit check"""
|
@@ -55,6 +101,14 @@ def extract_text_from_pdf(pdf_file):
|
|
55 |
return None, f"Error processing PDF: {str(e)}"
|
56 |
|
57 |
def generate_questions_with_retry(knowledge_material, question_type, cognitive_level, extra_instructions, case_based, num_choices=None, max_retries=3):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
# Adjust number of questions based on type
|
59 |
if question_type == "Multiple Choice":
|
60 |
num_questions = 3
|
@@ -171,8 +225,16 @@ if 'username' not in st.session_state:
|
|
171 |
if username_input:
|
172 |
if check_user_in_sheet(username_input):
|
173 |
st.session_state['username'] = username_input
|
174 |
-
|
175 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
176 |
else:
|
177 |
st.warning("Username not found. Please try again.")
|
178 |
else:
|
@@ -180,6 +242,16 @@ if 'username' not in st.session_state:
|
|
180 |
else:
|
181 |
st.title(f"Welcome, {st.session_state['username']}! Generate your exam questions")
|
182 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
183 |
# Create tabs for input methods
|
184 |
tab1, tab2 = st.tabs(["Text Input", "PDF Upload"])
|
185 |
|
@@ -226,8 +298,8 @@ else:
|
|
226 |
if st.button("Generate Questions"):
|
227 |
if 'knowledge_material' in locals() and knowledge_material.strip():
|
228 |
with st.spinner("Generating questions..."):
|
229 |
-
# Your existing generate_questions_with_retry function call here
|
230 |
questions = generate_questions_with_retry(
|
|
|
231 |
knowledge_material,
|
232 |
question_type,
|
233 |
cognitive_level,
|
@@ -240,6 +312,16 @@ else:
|
|
240 |
st.write("### Generated Exam Questions:")
|
241 |
st.write(questions)
|
242 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
243 |
# Download button
|
244 |
st.download_button(
|
245 |
label="Download Questions",
|
|
|
7 |
import PyPDF2
|
8 |
import io
|
9 |
|
|
|
|
|
|
|
10 |
# Constants
|
11 |
WORD_LIMIT = 8000
|
12 |
+
DAILY_API_LIMIT = 5 # Set your desired limit per user per day
|
13 |
|
14 |
+
# Set up OpenAI client
|
15 |
+
client = OpenAI(api_key=st.secrets["OPENAI_API_KEY"])
|
16 |
+
|
17 |
+
# Google Sheets setup
|
18 |
scope = ["https://spreadsheets.google.com/feeds", "https://www.googleapis.com/auth/drive"]
|
19 |
creds = ServiceAccountCredentials.from_json_keyfile_name("genexam-2c8c645ecc0d.json", scope)
|
20 |
client_gs = gspread.authorize(creds)
|
21 |
sheet = client_gs.open("GeneXam user").sheet1
|
22 |
|
23 |
def check_user_in_sheet(username):
|
24 |
+
"""Check if user exists in sheet"""
|
25 |
try:
|
26 |
+
users_list = sheet.col_values(1) # UserID column
|
27 |
if username in users_list:
|
28 |
return True
|
29 |
return False
|
|
|
31 |
st.error(f"Error checking user: {str(e)}")
|
32 |
return False
|
33 |
|
34 |
+
def get_user_stats(username):
|
35 |
+
"""Get user's current API usage statistics"""
|
36 |
+
try:
|
37 |
+
users_list = sheet.col_values(1) # UserID column
|
38 |
+
row_number = users_list.index(username) + 1
|
39 |
+
|
40 |
+
daily_count = int(sheet.cell(row_number, 2).value) # DailyAPICount
|
41 |
+
total_count = int(sheet.cell(row_number, 3).value) # TotalAPICount
|
42 |
+
last_used = sheet.cell(row_number, 4).value # LastUsedDate
|
43 |
+
|
44 |
+
return {
|
45 |
+
'daily_count': daily_count,
|
46 |
+
'total_count': total_count,
|
47 |
+
'last_used': last_used
|
48 |
+
}
|
49 |
+
except Exception as e:
|
50 |
+
st.error(f"Error getting user stats: {str(e)}")
|
51 |
+
return None
|
52 |
+
|
53 |
def update_api_usage(username):
|
54 |
+
"""Update both daily and total API usage counts"""
|
55 |
try:
|
56 |
users_list = sheet.col_values(1)
|
57 |
row_number = users_list.index(username) + 1
|
58 |
+
today = datetime.now().strftime('%Y-%m-%d')
|
59 |
+
|
60 |
+
# Get current values
|
61 |
+
stats = get_user_stats(username)
|
62 |
+
if not stats:
|
63 |
+
return False, "Error retrieving user statistics"
|
64 |
+
|
65 |
+
# Reset daily count if it's a new day
|
66 |
+
daily_count = stats['daily_count']
|
67 |
+
if stats['last_used'] != today:
|
68 |
+
daily_count = 0
|
69 |
+
|
70 |
+
# Check daily limit
|
71 |
+
if daily_count >= DAILY_API_LIMIT:
|
72 |
+
return False, f"You have reached your daily limit of {DAILY_API_LIMIT} generations. Please try again tomorrow."
|
73 |
+
|
74 |
+
# Update counts
|
75 |
+
new_daily_count = daily_count + 1
|
76 |
+
new_total_count = stats['total_count'] + 1
|
77 |
+
|
78 |
+
# Update all values in sheet
|
79 |
+
sheet.update_cell(row_number, 2, new_daily_count) # Update DailyAPICount
|
80 |
+
sheet.update_cell(row_number, 3, new_total_count) # Update TotalAPICount
|
81 |
+
sheet.update_cell(row_number, 4, today) # Update LastUsedDate
|
82 |
+
|
83 |
+
return True, None
|
84 |
+
|
85 |
except Exception as e:
|
86 |
+
return False, f"Error updating API usage: {str(e)}"
|
87 |
|
88 |
def extract_text_from_pdf(pdf_file):
|
89 |
"""Simple PDF text extraction with word limit check"""
|
|
|
101 |
return None, f"Error processing PDF: {str(e)}"
|
102 |
|
103 |
def generate_questions_with_retry(knowledge_material, question_type, cognitive_level, extra_instructions, case_based, num_choices=None, max_retries=3):
|
104 |
+
"""Generate questions and update API usage"""
|
105 |
+
|
106 |
+
# Check and update API usage before generating
|
107 |
+
can_generate, error_message = update_api_usage(username)
|
108 |
+
if not can_generate:
|
109 |
+
st.error(error_message)
|
110 |
+
return None
|
111 |
+
|
112 |
# Adjust number of questions based on type
|
113 |
if question_type == "Multiple Choice":
|
114 |
num_questions = 3
|
|
|
225 |
if username_input:
|
226 |
if check_user_in_sheet(username_input):
|
227 |
st.session_state['username'] = username_input
|
228 |
+
|
229 |
+
# Show user stats on login
|
230 |
+
stats = get_user_stats(username_input)
|
231 |
+
if stats:
|
232 |
+
st.success(f"Welcome, {username_input}!")
|
233 |
+
st.info(f"""
|
234 |
+
π Your API Usage Statistics:
|
235 |
+
- Today's Usage: {stats['daily_count']}/{DAILY_API_LIMIT} generations
|
236 |
+
- Total All-Time Usage: {stats['total_count']} generations
|
237 |
+
""")
|
238 |
else:
|
239 |
st.warning("Username not found. Please try again.")
|
240 |
else:
|
|
|
242 |
else:
|
243 |
st.title(f"Welcome, {st.session_state['username']}! Generate your exam questions")
|
244 |
|
245 |
+
# Show current usage stats
|
246 |
+
stats = get_user_stats(st.session_state['username'])
|
247 |
+
if stats:
|
248 |
+
remaining = DAILY_API_LIMIT - stats['daily_count']
|
249 |
+
st.info(f"""
|
250 |
+
π Usage Statistics:
|
251 |
+
- Daily Generations Remaining: {remaining}/{DAILY_API_LIMIT}
|
252 |
+
- Total All-Time Generations: {stats['total_count']}
|
253 |
+
""")
|
254 |
+
|
255 |
# Create tabs for input methods
|
256 |
tab1, tab2 = st.tabs(["Text Input", "PDF Upload"])
|
257 |
|
|
|
298 |
if st.button("Generate Questions"):
|
299 |
if 'knowledge_material' in locals() and knowledge_material.strip():
|
300 |
with st.spinner("Generating questions..."):
|
|
|
301 |
questions = generate_questions_with_retry(
|
302 |
+
st.session_state['username'],
|
303 |
knowledge_material,
|
304 |
question_type,
|
305 |
cognitive_level,
|
|
|
312 |
st.write("### Generated Exam Questions:")
|
313 |
st.write(questions)
|
314 |
|
315 |
+
# Update displayed stats after generation
|
316 |
+
new_stats = get_user_stats(st.session_state['username'])
|
317 |
+
if new_stats:
|
318 |
+
remaining = DAILY_API_LIMIT - new_stats['daily_count']
|
319 |
+
st.info(f"""
|
320 |
+
π Updated Usage Statistics:
|
321 |
+
- Daily Generations Remaining: {remaining}/{DAILY_API_LIMIT}
|
322 |
+
- Total All-Time Generations: {new_stats['total_count']}
|
323 |
+
""")
|
324 |
+
|
325 |
# Download button
|
326 |
st.download_button(
|
327 |
label="Download Questions",
|