File size: 9,617 Bytes
a8f56ca
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f70897f
a8f56ca
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e66ab7a
a8f56ca
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
# Technical Documentation - Stock Monitoring API

This document provides comprehensive technical information about the Stock Monitoring API, including detailed setup instructions, API reference, testing procedures, and deployment guidelines.

## Table of Contents

- [Installation & Configuration](#installation--configuration)
- [Authentication](#authentication)
- [API Reference](#api-reference)
- [Testing](#testing)
- [Database](#database)
- [Contributing](#contributing)
- [Development Status](#development-status)

---

## Installation & Configuration

### Prerequisites

- Python 3.8 or higher
- MySQL database server
- Virtual environment (recommended)

### Detailed Setup

1. **Clone the repository:**
    ```bash
    git clone https://github.com/dromerosm/stock-monitoring.git
    cd stock-monitoring
    ```

2. **Set up virtual environment (recommended):**
    ```bash
    python -m venv .venv
    source .venv/bin/activate  # On Windows: .venv\Scripts\activate
    ```

3. **Install dependencies:**
    ```bash
    pip install -r requirements.txt
    ```

4. **Environment Configuration:**
    Create a `.env` file in the project root with the following variables:
    ```env
    # Database Configuration
    MYSQL_USER=youruser
    MYSQL_PASSWORD=yourpassword
    MYSQL_HOST=localhost
    MYSQL_PORT=3306
    MYSQL_DB=stockdb
    
    # API Security - Generate a secure API key
    API_KEY=your_secure_api_key_here
    
    # Optional: Server Configuration
    PORT=7860
    ```

5. **Database Setup:**
    - Ensure MySQL server is running
    - Create the database specified in `MYSQL_DB`
    - Tables (`tickers` and `tasks`) will be created automatically on first run

6. **Start the API:**
    ```bash
    python api/index.py
    # Alternative with Uvicorn
    uvicorn api.index:app --host 0.0.0.0 --port 8000
    ```

---

## Authentication

### API Key Security

πŸ”’ The API uses Bearer token authentication for protected endpoints. Include the API key in the Authorization header:

```bash
Authorization: Bearer your_api_key_here
```

### Endpoint Classification

**Protected Endpoints** (require API key):
- `POST /tickers/update` - Manual ticker updates
- `POST /tickers/update-async` - Asynchronous ticker updates
- `GET /tasks` - List all background tasks
- `GET /tasks/{task_id}` - Get specific task details
- `DELETE /tasks/old` - Clean up old tasks

**Public Endpoints** (no authentication required):
- `GET /` - Health check and system status
- `GET /tickers` - Read-only ticker data access

---

## API Reference

### Health Check Endpoint

#### `GET /`

Returns comprehensive system health information including database connectivity, versions, and performance metrics.

**Response Example:**
```json
{
  "status": "healthy",
  "timestamp": "2025-07-19T17:38:26+00:00",
  "versions": {
    "python": "3.12.0",
    "uvicorn": "0.24.0",
    "fastapi": "0.110.0",
    "sqlalchemy": "2.0.30",
    "pandas": "2.2.2"
  },
  "database": {
    "connected": true,
    "tickers_table": true,
    "tasks_table": true
  },
  "db_check_seconds": 0.0123
}
```

### Ticker Endpoints

#### `GET /tickers`

Retrieve ticker data with optional filtering.

**Query Parameters:**
- `is_sp500` (boolean): Filter by S&P 500 membership
- `is_nasdaq` (boolean): Filter by Nasdaq 100 membership  
- `limit` (integer): Maximum number of results

**Example:**
```bash
curl 'http://localhost:8000/tickers?is_sp500=true&limit=10'
```

#### `POST /tickers/update` πŸ”’

Performs synchronous ticker data update from Wikipedia sources.

**Request Body:**
```json
{
  "force_refresh": true  // Optional: bypass cache and force update
}
```

**Example:**
```bash
curl -X POST 'http://localhost:8000/tickers/update' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer your_api_key_here' \
  -d '{"force_refresh": true}'
```

#### `POST /tickers/update-async` πŸ”’

Launches asynchronous background task for ticker updates.

**Request Body:**
```json
{
  "force_refresh": false  // Optional: bypass cache and force update
}
```

**Response:**
```json
{
  "task_id": "uuid-string",
  "status": "pending",
  "message": "Background update task started"
}
```

**Example:**
```bash
curl -X POST 'http://localhost:8000/tickers/update-async' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer your_api_key_here' \
  -d '{"force_refresh": false}'
```

### Task Management Endpoints

#### `GET /tasks` πŸ”’

List all background tasks with their current status and results.

#### `GET /tasks/{task_id}` πŸ”’

Get detailed information about a specific background task.

**Path Parameters:**
- `task_id` (string): UUID of the task

#### `DELETE /tasks/old` πŸ”’

Remove completed tasks older than 1 hour (3600 seconds) to maintain database performance.

---

## Testing

### Automated Test Suite

The project includes a comprehensive testing framework that validates API functionality, security, and data integrity.

### Test Setup and Execution

1. **Start the API server:**
   ```bash
   source .venv/bin/activate  # if using virtual environment
   python api/index.py
   ```

2. **Run the test suite:**
   ```bash
   cd tests
   chmod +x run_tests.sh  # First time only
   ./run_tests.sh
   ```

### Test Coverage

The test suite validates the following areas:

- βœ… **Authentication Security**: Verifies that protected endpoints properly reject unauthorized requests
- βœ… **Public Access**: Confirms public endpoints function without authentication
- βœ… **SQL Injection Protection**: Tests input sanitization and parameterized queries
- βœ… **Complete Workflow**: End-to-end testing of task creation, monitoring, and cleanup
- βœ… **Error Handling**: Validates proper HTTP status codes and error responses
- βœ… **Data Integrity**: Ensures ticker data accuracy and consistency

### Test Files Structure

- `tests/test_api.py` - Main test script with comprehensive coverage
- `tests/run_tests.sh` - Test runner with prerequisite checks

### Example Test Output

```
πŸ§ͺ Starting Stock Monitoring API Tests
πŸ”— Base URL: http://localhost:8000
πŸ”‘ API Key: Vsb5Zkujk2...

============================================================
πŸ§ͺ Health Check (Public Endpoint)
============================================================
βœ… GET /
   Expected: 200, Got: 200
   πŸ“Š Status: healthy
   πŸ• Timestamp: 2025-07-30T15:25:49+02:00
   πŸ’Ύ DB Connected: True

============================================================
πŸ§ͺ Authentication Tests
============================================================
βœ… POST /tickers/update (No Auth)
   Expected: 401/403, Got: 403
βœ… GET /tasks (No Auth)
   Expected: 401/403, Got: 403

============================================================
πŸ§ͺ SQL Injection Tests
============================================================
βœ… GET /tickers?limit='; DROP TABLE tickers; --
   Expected: 422, Got: 422
   πŸ”’ SQL injection attempt blocked

πŸŽ‰ ALL TESTS PASSED! βœ…
```

---

## Database

### Architecture

The application uses MySQL with SQLAlchemy ORM for database operations, providing:

- **Async Operations**: Non-blocking database interactions using `aiomysql`
- **Connection Pooling**: Efficient connection management
- **Auto Schema Creation**: Tables created automatically on startup

### Database Schema

#### `tickers` Table
Stores stock ticker information for S&P 500 and Nasdaq 100 indices.

#### `tasks` Table  
Tracks background task execution status and results.

### Database Configuration

Configure database connection via environment variables:
```env
MYSQL_USER=youruser
MYSQL_PASSWORD=yourpassword
MYSQL_HOST=localhost
MYSQL_PORT=3306
MYSQL_DB=stockdb
```

---

## Static Files

The API no longer serves static files. Static file serving functionality has been removed to simplify the deployment.

---

## Contributing

### Development Workflow

1. **Fork the repository**
2. **Create a feature branch:**
   ```bash
   git checkout -b feature/my-new-feature
   ```
3. **Make your changes and add tests**
4. **Run the test suite to ensure everything works**
5. **Commit your changes:**
   ```bash
   git commit -m 'Add new feature: description'
   ```
6. **Push to your fork:**
   ```bash
   git push origin feature/my-new-feature
   ```
7. **Open a pull request**

### Code Standards

- Follow PEP 8 Python style guide
- Include docstrings for all functions and classes
- Add appropriate error handling
- Write tests for new functionality
- Ensure all tests pass before submitting

---

## Development Status

### Recently Completed βœ…

- βœ… **Security Implementation** - API key authentication for protected endpoints
- βœ… **SQL Injection Prevention** - Replaced unsafe `text()` operations with parameterized queries
- βœ… **UTC Timezone Standardization** - All timestamps now use UTC for consistency
- βœ… **Enhanced Logging** - Added comprehensive logging in TaskManager for database operations

### Pending Tasks

- **Apple Touch Icons**: Implement missing `/apple-touch-icon-precomposed.png` and `/apple-touch-icon.png` endpoints
- **Enhanced Request Logging**: Add detailed request/response logging for improved debugging and monitoring
- **Rate Limiting**: Implement API rate limiting for production use
- **Docker Support**: Add containerization for easier deployment

### Architecture Improvements Under Consideration

- **Caching Layer**: Redis integration for improved performance
- **Message Queue**: Background task processing with Celery
- **API Versioning**: Implement versioned API endpoints for backward compatibility
- **Metrics Collection**: Prometheus metrics for monitoring and alerting