joshuarauh's picture
Add initial app.py with math test generator
bfc1cf6 verified
raw
history blame
4.57 kB
# app.py
import os
import gradio as gr
from anthropic import Anthropic
from datetime import datetime, timedelta
from collections import deque
# Initialize Anthropic client - will use the secret key from HuggingFace
anthropic = Anthropic(
api_key=os.environ.get('ANTHROPIC_API_KEY')
)
# Request tracking
MAX_REQUESTS_PER_DAY = 25 # Conservative limit to start
request_history = deque(maxlen=1000)
def check_api_key():
"""Verify API key is configured"""
if not os.environ.get('ANTHROPIC_API_KEY'):
raise ValueError("Anthropic API key not found. Please configure it in HuggingFace Spaces settings.")
def check_rate_limit():
"""Check if we're within rate limits"""
now = datetime.now()
# Remove requests older than 24 hours
while request_history and (now - request_history[0]) > timedelta(days=1):
request_history.popleft()
return len(request_history) < MAX_REQUESTS_PER_DAY
def clean_latex(text):
"""Simple LaTeX cleaning"""
text = text.replace('\n', '\n\n')
return text
def generate_test(subject):
"""Generate a math test with error handling and rate limiting"""
try:
# Check API key
check_api_key()
# Check rate limit
if not check_rate_limit():
return "Daily request limit reached. Please try again tomorrow."
# Record request
request_history.append(datetime.now())
system_prompt = """You will write math exam questions. Follow these requirements EXACTLY:
1. Write exactly 3 challenging university-level questions
2. For LaTeX math formatting:
- Use $ for simple inline math
- For equations and solution steps, use $$ on separate lines
- For multi-step solutions, put each step on its own line in $$ $$
- DO NOT use \\begin{aligned} or any other environments
3. Number each question as 1), 2), 3)
4. Include solutions after each question
5. Keep formatting simple and clear"""
message = anthropic.messages.create(
model="claude-3-opus-20240229",
max_tokens=1500,
temperature=0.7,
messages=[{
"role": "user",
"content": f"{system_prompt}\n\nWrite an exam for {subject}."
}]
)
# Extract usage information
input_tokens = message.usage.input_tokens
output_tokens = message.usage.output_tokens
input_cost = (input_tokens / 1000) * 0.015
output_cost = (output_tokens / 1000) * 0.075
total_cost = input_cost + output_cost
usage_stats = f"""
\n---\nUsage Statistics:
• Input Tokens: {input_tokens:,}
• Output Tokens: {output_tokens:,}
• Total Tokens: {input_tokens + output_tokens:,}
Cost Breakdown:
• Input Cost: ${input_cost:.4f}
• Output Cost: ${output_cost:.4f}
• Total Cost: ${total_cost:.4f}
"""
if hasattr(message, 'content') and len(message.content) > 0:
response_text = message.content[0].text
formatted_response = clean_latex(response_text) + usage_stats
return formatted_response
else:
return "Error: No content in response"
except ValueError as e:
return f"Configuration Error: {str(e)}"
except Exception as e:
return f"Error: {str(e)}"
# Subject choices
subjects = [
"Single Variable Calculus",
"Multivariable Calculus",
"Linear Algebra",
"Differential Equations",
"Real Analysis",
"Complex Analysis",
"Abstract Algebra",
"Probability Theory",
"Numerical Analysis",
"Topology"
]
# Create Gradio interface
interface = gr.Interface(
fn=generate_test,
inputs=gr.Dropdown(
choices=subjects,
label="Select Mathematics Subject",
info="Choose a subject for the exam questions"
),
outputs=gr.Markdown(
label="Generated Test",
latex_delimiters=[
{"left": "$$", "right": "$$", "display": True"},
{"left": "$", "right": "$", "display": False}
]
),
title="Advanced Mathematics Test Generator",
description="""Generates university-level mathematics exam questions with solutions using Claude 3 Opus.
Limited to 25 requests per day. Please use responsibly.""",
theme="default",
allow_flagging="never"
)
# Launch the interface
if __name__ == "__main__":
interface.launch()