File size: 8,054 Bytes
0c4a5ea
3010238
 
 
 
0c4a5ea
 
 
3010238
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0c4a5ea
3010238
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24780ab
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3010238
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
---

title: IITM LLM Quiz Solver
emoji: 🧠
colorFrom: green
colorTo: blue
sdk: docker
sdk_version: "0"
app_file: app/main.py
pinned: false
---



A complete Python project with FastAPI that acts as an API endpoint to automatically solve dynamic quiz tasks using a headless browser and optional LLM reasoning.

## Features

- πŸš€ FastAPI-based REST API
- 🌐 Playwright for headless browser automation
- πŸ€– OpenAI GPT integration for complex reasoning
- πŸ“Š Data processing (CSV, JSON, PDF, etc.)
- πŸ”„ Recursive quiz solving
- ⚑ Async/await for performance
- 🐳 Docker support for easy deployment

## Project Structure

```

/app

  - main.py              # FastAPI server

  - solver.py            # All quiz solving logic (browser, LLM, calculations, handlers - consolidated)

/Dockerfile

/requirements.txt

/README.md

/LICENSE

```

## Installation

### Local Development

1. Clone the repository:
```bash

git clone <repository-url>

cd IITMTdsPrj2

```

2. Install Python dependencies:
```bash

pip install -r requirements.txt

```

3. Install Playwright browsers:
```bash

playwright install chromium

```

4. Set environment variables:

   **Quick Setup (Windows PowerShell):**
   ```powershell

   .\setup_env.ps1

   ```

   **Quick Setup (Linux/Mac):**
   ```bash

   source setup_env.sh

   ```

   **Manual Setup (choose whichever LLM provider you prefer):**
   ```bash

   # Windows PowerShell

   $env:QUIZ_SECRET = "your_secret_key"

   $env:OPENAI_API_KEY = "sk-your-openai-api-key"      # Optional - OpenAI

   $env:OPENROUTER_API_KEY = "sk-or-your-openrouter"   # Optional - OpenRouter GPT-5-nano

   

   # Linux/Mac

   export QUIZ_SECRET="your_secret_key"

   export OPENAI_API_KEY="sk-your-openai-api-key"        # Optional

   export OPENROUTER_API_KEY="sk-or-your-openrouter"     # Optional

   ```

   **Or use .env file:**
   - Copy `.env.example` to `.env` (if available)
   - Fill in your values
   - The app will automatically load it

   πŸ“– **See [ENV_SETUP.md](ENV_SETUP.md) for detailed instructions**

5. Run the server:
```bash

python -m app.main

# or

uvicorn app.main:app --host 0.0.0.0 --port 8000

```

## API Endpoints

### POST /solve

Main endpoint to solve a quiz.

**Request Body:**
```json

{

  "email": "user@example.com",

  "secret": "your_secret",

  "url": "https://example.com/quiz"

}

```

**Response:**
- `200 OK`: Quiz solved successfully
- `400 Bad Request`: Invalid request format
- `403 Forbidden`: Invalid secret
- `500 Internal Server Error`: Server error
- `504 Gateway Timeout`: Request timeout (>3 minutes)

### POST /demo

Demo endpoint for testing (same as `/solve` but with more lenient error handling).

**Request Body:** Same as `/solve`

### GET /health

Health check endpoint.

**Response:**
```json

{

  "status": "healthy"

}

```

## Deployment on Hugging Face Spaces

### Method 1: Using Dockerfile (Recommended)

1. **Create a new Space on Hugging Face:**
   - Go to https://huggingface.co/spaces
   - Create a new Space
   - Select "Docker" as the SDK

2. **Upload your files:**
   - Upload all project files to your Space
   - Ensure `Dockerfile` is in the root directory

3. **Set Environment Variables:**
   - Go to Space Settings β†’ Variables and secrets
   - Add the following:
     - `QUIZ_SECRET`: Your secret key for authentication
     - `OPENAI_API_KEY`: Your OpenAI API key (optional)
     - `OPENROUTER_API_KEY`: Your OpenRouter key (e.g., GPT-5-nano)
     - `PORT`: 8000 (usually set automatically)

4. **Deploy:**
   - Hugging Face will automatically build and deploy your Docker container
   - The API will be available at: `https://<your-username>-<space-name>.hf.space`

### Method 2: Using Docker Compose (Alternative)

If you need more control, you can use `docker-compose.yml`:

```yaml

version: '3.8'

services:

  app:

    build: .

    ports:

      - "8000:8000"

    environment:

      - QUIZ_SECRET=${QUIZ_SECRET}

      - OPENAI_API_KEY=${OPENAI_API_KEY}

```

## Environment Variables

| Variable | Description | Required | Default |
|----------|-------------|----------|---------|
| `QUIZ_SECRET` | Secret key for API authentication | Yes | `default_secret_change_me` |
| `OPENAI_API_KEY` | OpenAI API key for LLM features | No | - |
| `OPENROUTER_API_KEY` | OpenRouter key (e.g., GPT-5-nano) | No | - |
| `OPENROUTER_MODEL` | Override OpenRouter model (default gpt-5-nano) | No | `gpt-5-nano` |
| `PORT` | Server port | No | `8000` |

## Testing

### Test with curl:

```bash

curl -X POST "https://tds-llm-analysis.s-anand.net/demo" \

  -H "Content-Type: application/json" \

  -d '{

    "email": "test@example.com",

    "secret": "your_secret",

    "url": "https://example.com/quiz"

  }'

```

### Test with Python:

```python

import requests



response = requests.post(

    "https://tds-llm-analysis.s-anand.net/demo",

    json={

        "email": "test@example.com",

        "secret": "your_secret",

        "url": "https://example.com/quiz"

    }

)



print(response.json())

```

### Test with PowerShell:

```powershell

# Fix SSL certificate validation (for development/testing)

add-type @"

    using System.Net;

    using System.Security.Cryptography.X509Certificates;

    public class TrustAllCertsPolicy : ICertificatePolicy {

        public bool CheckValidationResult(

            ServicePoint srvPoint, X509Certificate certificate,

            WebRequest request, int certificateProblem) {

            return true;

        }

    }

"@

[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy

[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12



$body = @{

    email = "test@example.com"

    secret = "your_secret"

    url = "https://example.com/quiz"

} | ConvertTo-Json



Invoke-RestMethod -Uri "https://tds-llm-analysis.s-anand.net/demo" `

    -Method POST `

    -ContentType "application/json" `

    -Body $body

```

Or use the provided `test_api.ps1` script:
```powershell

.\test_api.ps1

```

## How It Works

1. **Request Validation**: Validates email, secret, and URL format
2. **Secret Authentication**: Checks secret against expected value (403 if wrong)
3. **Page Loading**: Uses Playwright to load and render the quiz page
4. **Content Extraction**: Extracts all text, HTML, links, and images
5. **Submit URL Detection**: Automatically finds the submit URL from page content
6. **Question Solving**: 
   - Extracts question text
   - Tries multiple strategies:
     - Check if answer is in page
     - Download and process data files (CSV, JSON, PDF)
     - Use LLM for complex reasoning
7. **Answer Submission**: Submits answer to detected submit URL
8. **Recursive Solving**: If response contains next URL, solves recursively
9. **Response**: Returns final result

## Solver Strategies

The solver uses multiple strategies in order:

1. **Direct Answer Extraction**: Checks if answer is already in page
2. **Data File Processing**: Downloads and processes CSV, JSON, PDF files
3. **LLM Reasoning**: Uses GPT-4o-mini (OpenAI) or GPT-5-nano (OpenRouter) for complex questions
4. **Fallback**: Returns question analysis if all else fails

## Error Handling

- Invalid JSON β†’ 400 Bad Request
- Wrong secret β†’ 403 Forbidden
- Page load errors β†’ 500 with error details
- Timeout (>3 min) β†’ 504 Gateway Timeout
- All errors are logged for debugging

## Limitations

- Maximum recursion depth: 10 quizzes
- Timeout: 3 minutes per request
- Requires internet connection for external URLs
- OpenAI API key needed for LLM features (optional)

## License

MIT License - see LICENSE file for details.

## Contributing

1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Submit a pull request

## Support

For issues and questions, please open an issue on the repository.