This project is a web analytics service that collects user interaction data (like page views, button clicks, and location) from a website, stores it in a database, and provides APIs to analyze the data.
web-analytics-service/ │ ├── app/ # Main application code │ ├── init.py # Flask app initialization │ ├── models.py # Database models │ ├── routes.py # API endpoints │ ├── services.py # Business logic │ └── validators.py # Request validation │ ├── scripts/ │ └── generate_events.py # Data generation script │ ├── static/ # For frontend files │ ├── index.html # Demo client │ └── service-worker.js # Service worker │ ├── tests/ # Test cases │ ├── .env # Environment variables ├── config.py # Configuration ├── requirements.txt # Dependencies └── README.md # Project documentation
- Collect user interaction events via REST API
- Store events in PostgreSQL database
- Query aggregated analytics data
- Sample frontend integration with service worker
- Language: Python 3.8+
- Framework: Flask
- Database: PostgreSQL
- Testing: Postman
- Additional Libraries:
- Flask-SQLAlchemy (ORM)
- Faker (data generation)
- python-dotenv (environment variables)
-
Clone the repository:
git clone https://github.com/yourusername/web-analytics-service.git cd web-analytics-service
-
Set up virtual environment python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate
-
Install Dependencies pip install -r requirements.txt
-
Configure environment Create a .env file with: DB_USER=postgres ` DB_PASSWORD=yourpassword DB_HOST=localhost DB_PORT=5432 DB_NAME=analytics_db FLASK_APP=app FLASK_ENV=development
-
Create PostgreSQL DB CREATE DATABASE analytics_db;
-
Generate sample data python -m app.scripts.generate_events
-
Run the app python run.py
-
Access Frontend in your Local Browser http://localhost:5000 in your browser.
- Purpose: Receive and store a new event. Request Body (example): { "user_id": "user-123", "event_type": "click", "payload": { "element_id": "btn-submit", "text": "Submit", "xpath": "//button[@id='btn-submit']" } }
Responses: 202 Accepted – Event stored successfully 400 Bad Request – Validation failure 500 Internal Server Error – DB failure or unhandled exception
Purpose: Retrieve total number of events Query Params:
- event_type – optional ("view", "click", "location")
- start_date / end_date – optional (ISO format) Response (example): { "total_events": 2089 }
Purpose: Group event counts by type Query Params:
- start_date / end_date – optional
- Response (example): { "view": 1021, "click": 789, "location": 279 }
The "events" table has the following structure: event_id: UUID (Primary Key) user_id: String (Indexed) event_type: String (Indexed) timestamp: DateTime (Indexed) payload: JSON
user_id: Indexed for quick user-specific queries event_type: Indexed for filtering by event type timestamp: Indexed for efficient date range queries
Added database indexes on: CREATE INDEX idx_event_type ON events(event_type); CREATE INDEX idx_timestamp ON events(timestamp); Used efficient GROUP BY queries for analytics.
Added dual fallback (Service Worker + direct fetch()): // Try Service Worker first if (navigator.serviceWorker?.controller) { sendViaServiceWorker(); } else { sendDirectly(); // Fallback } Added user-friendly status updates in the UI.
Authentication: Add API key or JWT authentication Rate Limiting: Prevent abuse of the API Asynchronous Processing: Use a message queue (Redis, RabbitMQ) for event ingestion Real-time Analytics: Add WebSocket support for real-time dashboards Advanced Location Queries: Implement geospatial indexing for location-based queries Caching: Add Redis caching for frequent analytics queries Monitoring: Add Prometheus metrics and health checks Containerization: Dockerize the application for easy deployment