536 lines
10 KiB
Markdown
536 lines
10 KiB
Markdown
|
|
# Tikker API Documentation
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
|
||
|
|
Tikker API is a distributed microservices architecture providing enterprise-grade keystroke analytics. The system consists of three main services:
|
||
|
|
|
||
|
|
1. **Main API** - Integrates C tools for keystroke analysis
|
||
|
|
2. **AI Service** - Provides AI-powered text analysis
|
||
|
|
3. **Visualization Service** - Generates charts and reports
|
||
|
|
|
||
|
|
## Architecture
|
||
|
|
|
||
|
|
```
|
||
|
|
┌─────────────────────────────────────────────────┐
|
||
|
|
│ Client Applications │
|
||
|
|
└────────────┬────────────────────────────────────┘
|
||
|
|
│
|
||
|
|
├──────────────┬──────────────┬──────────────┐
|
||
|
|
▼ ▼ ▼ ▼
|
||
|
|
┌────────┐ ┌────────┐ ┌────────┐ ┌─────────┐
|
||
|
|
│ Main │ │ AI │ │ Viz │ │Database │
|
||
|
|
│ API │ │Service │ │Service │ │(SQLite) │
|
||
|
|
│:8000 │ │:8001 │ │:8002 │ │ │
|
||
|
|
└────┬───┘ └────────┘ └────────┘ └─────────┘
|
||
|
|
│
|
||
|
|
└──────────────┬──────────────┐
|
||
|
|
▼ ▼
|
||
|
|
┌────────────┐ ┌─────────────┐
|
||
|
|
│ C Tools │ │ Logs Dir │
|
||
|
|
│(libtikker) │ │ │
|
||
|
|
└────────────┘ └─────────────┘
|
||
|
|
```
|
||
|
|
|
||
|
|
## Main API Service
|
||
|
|
|
||
|
|
### Endpoints
|
||
|
|
|
||
|
|
#### Health Check
|
||
|
|
```
|
||
|
|
GET /health
|
||
|
|
```
|
||
|
|
Returns health status of API and C tools.
|
||
|
|
|
||
|
|
Response:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"status": "healthy",
|
||
|
|
"tools": {
|
||
|
|
"tikker-decoder": "ok",
|
||
|
|
"tikker-indexer": "ok",
|
||
|
|
"tikker-aggregator": "ok",
|
||
|
|
"tikker-report": "ok"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Root Endpoint
|
||
|
|
```
|
||
|
|
GET /
|
||
|
|
```
|
||
|
|
Returns service information and available endpoints.
|
||
|
|
|
||
|
|
Response:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"name": "Tikker API",
|
||
|
|
"version": "2.0.0",
|
||
|
|
"status": "running",
|
||
|
|
"backend": "C tools (libtikker)",
|
||
|
|
"endpoints": {
|
||
|
|
"health": "/health",
|
||
|
|
"stats": "/api/stats/daily, /api/stats/hourly, /api/stats/weekly, /api/stats/weekday",
|
||
|
|
"words": "/api/words/top, /api/words/find",
|
||
|
|
"operations": "/api/index, /api/decode, /api/report"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Statistics Endpoints
|
||
|
|
|
||
|
|
#### Daily Statistics
|
||
|
|
```
|
||
|
|
GET /api/stats/daily
|
||
|
|
```
|
||
|
|
Get daily keystroke statistics.
|
||
|
|
|
||
|
|
Response:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"presses": 5234,
|
||
|
|
"releases": 5234,
|
||
|
|
"repeats": 128,
|
||
|
|
"total": 10596
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Hourly Statistics
|
||
|
|
```
|
||
|
|
GET /api/stats/hourly?date=YYYY-MM-DD
|
||
|
|
```
|
||
|
|
Get hourly breakdown for specific date.
|
||
|
|
|
||
|
|
Parameters:
|
||
|
|
- `date` (required): Date in YYYY-MM-DD format
|
||
|
|
|
||
|
|
Response:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"date": "2024-01-15",
|
||
|
|
"output": "Hour 0: 120 presses\nHour 1: 245 presses\n...",
|
||
|
|
"status": "success"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Weekly Statistics
|
||
|
|
```
|
||
|
|
GET /api/stats/weekly
|
||
|
|
```
|
||
|
|
Get weekly keystroke statistics.
|
||
|
|
|
||
|
|
Response:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"period": "weekly",
|
||
|
|
"output": "Monday: 1200\nTuesday: 1450\n...",
|
||
|
|
"status": "success"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Weekday Statistics
|
||
|
|
```
|
||
|
|
GET /api/stats/weekday
|
||
|
|
```
|
||
|
|
Get comparison statistics by day of week.
|
||
|
|
|
||
|
|
Response:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"period": "weekday",
|
||
|
|
"output": "Weekdays: 1250 avg\nWeekends: 950 avg\n...",
|
||
|
|
"status": "success"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Word Analysis Endpoints
|
||
|
|
|
||
|
|
#### Top Words
|
||
|
|
```
|
||
|
|
GET /api/words/top?limit=10
|
||
|
|
```
|
||
|
|
Get most frequent words.
|
||
|
|
|
||
|
|
Parameters:
|
||
|
|
- `limit` (optional, default=10, max=100): Number of words to return
|
||
|
|
|
||
|
|
Response:
|
||
|
|
```json
|
||
|
|
[
|
||
|
|
{
|
||
|
|
"rank": 1,
|
||
|
|
"word": "the",
|
||
|
|
"count": 523,
|
||
|
|
"percentage": 15.2
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"rank": 2,
|
||
|
|
"word": "and",
|
||
|
|
"count": 412,
|
||
|
|
"percentage": 12.0
|
||
|
|
}
|
||
|
|
]
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Find Word
|
||
|
|
```
|
||
|
|
GET /api/words/find?word=searchterm
|
||
|
|
```
|
||
|
|
Find statistics for specific word.
|
||
|
|
|
||
|
|
Parameters:
|
||
|
|
- `word` (required): Word to search for
|
||
|
|
|
||
|
|
Response:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"word": "searchterm",
|
||
|
|
"rank": 5,
|
||
|
|
"frequency": 234,
|
||
|
|
"percentage": 6.8
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Operation Endpoints
|
||
|
|
|
||
|
|
#### Index Directory
|
||
|
|
```
|
||
|
|
POST /api/index?dir_path=logs_plain
|
||
|
|
```
|
||
|
|
Build word index from text files.
|
||
|
|
|
||
|
|
Parameters:
|
||
|
|
- `dir_path` (optional, default=logs_plain): Directory to index
|
||
|
|
|
||
|
|
Response:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"status": "success",
|
||
|
|
"directory": "logs_plain",
|
||
|
|
"database": "tikker.db",
|
||
|
|
"unique_words": 2341,
|
||
|
|
"total_words": 34521
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Decode File
|
||
|
|
```
|
||
|
|
POST /api/decode
|
||
|
|
```
|
||
|
|
Decode keystroke token file to readable text.
|
||
|
|
|
||
|
|
Request Body:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"input_file": "keystroke_log.bin",
|
||
|
|
"output_file": "decoded.txt",
|
||
|
|
"verbose": false
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
Response:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"status": "success",
|
||
|
|
"input": "keystroke_log.bin",
|
||
|
|
"output": "decoded.txt",
|
||
|
|
"message": "File decoded successfully"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Generate Report
|
||
|
|
```
|
||
|
|
POST /api/report
|
||
|
|
```
|
||
|
|
Generate HTML activity report.
|
||
|
|
|
||
|
|
Request Body:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"output_file": "report.html",
|
||
|
|
"input_dir": "logs_plain",
|
||
|
|
"title": "Daily Activity Report"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
Response:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"status": "success",
|
||
|
|
"output": "report.html",
|
||
|
|
"title": "Daily Activity Report",
|
||
|
|
"message": "Report generated successfully"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Download Report
|
||
|
|
```
|
||
|
|
GET /api/report/{filename}
|
||
|
|
```
|
||
|
|
Download generated report file.
|
||
|
|
|
||
|
|
Parameters:
|
||
|
|
- `filename`: Report filename (without path)
|
||
|
|
|
||
|
|
Response: HTML file download
|
||
|
|
|
||
|
|
## AI Service
|
||
|
|
|
||
|
|
### Health Check
|
||
|
|
```
|
||
|
|
GET /health
|
||
|
|
```
|
||
|
|
|
||
|
|
Response:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"status": "healthy",
|
||
|
|
"ai_available": true,
|
||
|
|
"api_version": "1.0.0"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Text Analysis
|
||
|
|
```
|
||
|
|
POST /analyze
|
||
|
|
```
|
||
|
|
|
||
|
|
Request Body:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"text": "Text to analyze",
|
||
|
|
"analysis_type": "general|activity|productivity"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
Response:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"text": "Text to analyze",
|
||
|
|
"analysis_type": "general",
|
||
|
|
"summary": "Summary of analysis",
|
||
|
|
"keywords": ["keyword1", "keyword2"],
|
||
|
|
"sentiment": "positive|neutral|negative",
|
||
|
|
"insights": ["insight1", "insight2"]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Visualization Service
|
||
|
|
|
||
|
|
### Health Check
|
||
|
|
```
|
||
|
|
GET /health
|
||
|
|
```
|
||
|
|
|
||
|
|
Response:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"status": "healthy",
|
||
|
|
"viz_available": true,
|
||
|
|
"api_version": "1.0.0"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Generate Chart
|
||
|
|
```
|
||
|
|
POST /chart
|
||
|
|
```
|
||
|
|
|
||
|
|
Request Body:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"title": "Chart Title",
|
||
|
|
"data": {
|
||
|
|
"Category1": 100,
|
||
|
|
"Category2": 150,
|
||
|
|
"Category3": 120
|
||
|
|
},
|
||
|
|
"chart_type": "bar|line|pie",
|
||
|
|
"width": 10,
|
||
|
|
"height": 6
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
Response:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"status": "success",
|
||
|
|
"image_base64": "iVBORw0KGgoAAAANS...",
|
||
|
|
"chart_type": "bar",
|
||
|
|
"title": "Chart Title"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Download Chart
|
||
|
|
```
|
||
|
|
POST /chart/download
|
||
|
|
```
|
||
|
|
|
||
|
|
Same request body as `/chart`, returns PNG file.
|
||
|
|
|
||
|
|
## Usage Examples
|
||
|
|
|
||
|
|
### Get Daily Statistics
|
||
|
|
```bash
|
||
|
|
curl -X GET http://localhost:8000/api/stats/daily
|
||
|
|
```
|
||
|
|
|
||
|
|
### Search for Word
|
||
|
|
```bash
|
||
|
|
curl -X GET "http://localhost:8000/api/words/find?word=python"
|
||
|
|
```
|
||
|
|
|
||
|
|
### Analyze Text with AI
|
||
|
|
```bash
|
||
|
|
curl -X POST http://localhost:8001/analyze \
|
||
|
|
-H "Content-Type: application/json" \
|
||
|
|
-d '{
|
||
|
|
"text": "writing code in python",
|
||
|
|
"analysis_type": "activity"
|
||
|
|
}'
|
||
|
|
```
|
||
|
|
|
||
|
|
### Generate Bar Chart
|
||
|
|
```bash
|
||
|
|
curl -X POST http://localhost:8002/chart \
|
||
|
|
-H "Content-Type: application/json" \
|
||
|
|
-d '{
|
||
|
|
"title": "Daily Activity",
|
||
|
|
"data": {
|
||
|
|
"Monday": 1200,
|
||
|
|
"Tuesday": 1450,
|
||
|
|
"Wednesday": 1380
|
||
|
|
},
|
||
|
|
"chart_type": "bar"
|
||
|
|
}'
|
||
|
|
```
|
||
|
|
|
||
|
|
### Decode Keystroke File
|
||
|
|
```bash
|
||
|
|
curl -X POST http://localhost:8000/api/decode \
|
||
|
|
-H "Content-Type: application/json" \
|
||
|
|
-d '{
|
||
|
|
"input_file": "keystroke.bin",
|
||
|
|
"output_file": "output.txt",
|
||
|
|
"verbose": true
|
||
|
|
}'
|
||
|
|
```
|
||
|
|
|
||
|
|
## Deployment
|
||
|
|
|
||
|
|
### Docker Compose
|
||
|
|
|
||
|
|
```bash
|
||
|
|
docker-compose up
|
||
|
|
```
|
||
|
|
|
||
|
|
All services start on their respective ports:
|
||
|
|
- Main API: 8000
|
||
|
|
- AI Service: 8001
|
||
|
|
- Visualization Service: 8002
|
||
|
|
- Database Viewer (dev): 8080
|
||
|
|
|
||
|
|
### Environment Variables
|
||
|
|
|
||
|
|
Main API:
|
||
|
|
- `TOOLS_DIR`: Path to compiled C tools (default: `/app/build/bin`)
|
||
|
|
- `DB_PATH`: Path to SQLite database (default: `/app/tikker.db`)
|
||
|
|
- `LOG_LEVEL`: Logging level (default: `INFO`)
|
||
|
|
- `AI_SERVICE_URL`: AI service URL (default: `http://ai_service:8001`)
|
||
|
|
- `VIZ_SERVICE_URL`: Visualization service URL (default: `http://viz_service:8002`)
|
||
|
|
|
||
|
|
AI Service:
|
||
|
|
- `OPENAI_API_KEY`: OpenAI API key (required for AI features)
|
||
|
|
- `LOG_LEVEL`: Logging level (default: `INFO`)
|
||
|
|
|
||
|
|
Visualization Service:
|
||
|
|
- `DB_PATH`: Path to SQLite database
|
||
|
|
- `LOG_LEVEL`: Logging level (default: `INFO`)
|
||
|
|
|
||
|
|
## Error Handling
|
||
|
|
|
||
|
|
All endpoints return appropriate HTTP status codes:
|
||
|
|
|
||
|
|
- `200 OK`: Request successful
|
||
|
|
- `400 Bad Request`: Invalid input
|
||
|
|
- `404 Not Found`: Resource not found
|
||
|
|
- `500 Internal Server Error`: Server error
|
||
|
|
- `503 Service Unavailable`: Service not available
|
||
|
|
|
||
|
|
Error Response:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"detail": "Error description"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Performance
|
||
|
|
|
||
|
|
Typical response times:
|
||
|
|
- Daily stats: <100ms
|
||
|
|
- Top words (limit=10): <200ms
|
||
|
|
- Word search: <150ms
|
||
|
|
- File decoding: <1s (depends on file size)
|
||
|
|
- Report generation: <500ms
|
||
|
|
- Chart generation: <300ms
|
||
|
|
|
||
|
|
## Security
|
||
|
|
|
||
|
|
- File path validation prevents directory traversal
|
||
|
|
- Input validation on all endpoints
|
||
|
|
- Database queries use prepared statements
|
||
|
|
- Environment variables for sensitive configuration
|
||
|
|
- Health checks monitor service availability
|
||
|
|
|
||
|
|
## Testing
|
||
|
|
|
||
|
|
Run integration tests:
|
||
|
|
```bash
|
||
|
|
pytest tests/test_services.py -v
|
||
|
|
```
|
||
|
|
|
||
|
|
Run specific test class:
|
||
|
|
```bash
|
||
|
|
pytest tests/test_services.py::TestMainAPIService -v
|
||
|
|
```
|
||
|
|
|
||
|
|
Run specific test:
|
||
|
|
```bash
|
||
|
|
pytest tests/test_services.py::TestMainAPIService::test_api_health_check -v
|
||
|
|
```
|
||
|
|
|
||
|
|
## Troubleshooting
|
||
|
|
|
||
|
|
### C Tools Not Found
|
||
|
|
If you see "Tool not found" error:
|
||
|
|
1. Verify C tools are built: `ls build/bin/tikker-*`
|
||
|
|
2. Check TOOLS_DIR environment variable
|
||
|
|
3. Rebuild tools: `cd src/tools && make clean && make`
|
||
|
|
|
||
|
|
### Database Locked
|
||
|
|
If you see database lock errors:
|
||
|
|
1. Ensure only one service writes to database
|
||
|
|
2. Check file permissions on tikker.db
|
||
|
|
3. Close any open connections to database
|
||
|
|
|
||
|
|
### AI Service Timeout
|
||
|
|
If AI service requests timeout:
|
||
|
|
1. Check OpenAI API connectivity
|
||
|
|
2. Verify API key is correct
|
||
|
|
3. Check service logs: `docker logs tikker-ai`
|
||
|
|
|
||
|
|
### Visualization Issues
|
||
|
|
If charts don't generate:
|
||
|
|
1. Verify matplotlib is installed
|
||
|
|
2. Check system has required graphics libraries
|
||
|
|
3. Ensure chart data is valid
|
||
|
|
|
||
|
|
## API Backwards Compatibility
|
||
|
|
|
||
|
|
The Tikker API maintains 100% backwards compatibility with the original Python implementation. All endpoints, request/response formats, and behaviors are identical to the previous version.
|
||
|
|
|
||
|
|
Migration path:
|
||
|
|
1. Python implementation → C tools wrapper
|
||
|
|
2. Same HTTP endpoints and JSON responses
|
||
|
|
3. No client code changes required
|
||
|
|
4. Improved performance (10-100x faster)
|