A real-time cryptocurrency dashboard built with Django, Django Channels, WebSockets, Celery Beat, Redis, and Vue.js.
The application periodically fetches cryptocurrency market data from the CoinGecko API, processes it in the background with Celery, and broadcasts live updates to connected browser clients using Django Channels and WebSockets.
This project demonstrates a real-time data broadcasting architecture.
Instead of requiring users to manually refresh the page, the backend fetches updated cryptocurrency prices on a schedule and broadcast the new data to all connected clients automatically.
Celery Beat
↓
Scheduled API Request
↓
Celery Worker
↓
CoinGecko API
↓
Django Channels
↓
WebSocket Broadcast
↓
Vue.js Frontend
↓
Live Crypto Dashboard
- Real-time cryptocurrency price updates
- Scheduled API polling with Celery Beat
- Background task processing with Celery
- Redis message broker
- WebSocket communication with Django Channels
- Live broadcasting to all connected clients
- Vue.js frontend rendering
- Price movement indicators
- Django backend architecture
- Docker-based Redis setup for local development
- Python
- Django
- Django Channels
- Daphne
- WebSockets
- Celery
- Celery Beat
- Redis
- Docker
- Vue.js
- JavaScript
- Bootstrap
- CoinGecko API
- SQLite
The project uses the CoinGecko API to fetch cryptocurrency market data.
Endpoint used:
GET https://api.coingecko.com/api/v3/coins/markets
Example query parameters:
vs_currency=usd
order=market_cap_desc
per_page=7
page=1
sparkline=false
The response includes cryptocurrency data such as:
- coin ID
- coin image
- current price
- market data
The backend compares the latest price with the previously saved price and marks each coin state as:
raise
fall
same
These states are used by the frontend to visually indicate price movement.
External Crypto API
↑
│
Celery Beat triggers scheduled task
│
↓
Celery Worker fetches crypto data
│
↓
Redis broker coordinates background tasks
│
↓
Django Channels sends data to WebSocket group
│
↓
Connected clients receive live updates
│
↓
Vue.js updates the dashboard UI
Django is used as the main backend framework and handles the web application structure.
Daphne provides ASGI support for Django Channels and allows WebSocket connections to work with the Django development server setup.
Django Channels adds asynchronous support and WebSocket handling to Django.
WebSockets allow the backend to push live crypto updates to the browser without a page refresh.
Celery runs background tasks outside the normal request-response cycle.
Celery Beat schedules the periodic task that fetches cryptocurrency data from the API.
Redis is used as the message broker for Celery and supports the real-time architecture.
Vue.js is used on the frontend to update the crypto dashboard when new WebSocket data arrives.
real-time-crypto-dashboard/
├── coins/
├── setari/
├── static/
├── templates/
├── manage.py
├── requirements.txt
├── README.md
└── .gitignore
Clone the repository:
git clone https://github.com/chrispsk/real-time-crypto-dashboard.git
cd real-time-crypto-dashboardCreate and activate a virtual environment:
python -m venv venvOn Windows:
venv\Scripts\activateOn macOS/Linux:
source venv/bin/activateInstall dependencies:
pip install -r requirements.txtRecommended requirements.txt:
Django==4.2.17
daphne==4.2.2
channels==4.2.0
channels-redis==4.2.1
celery==5.4.0
redis==5.2.1
requests==2.32.3
gevent==24.11.1
Redis must be running before starting Celery and the Django application.
Create and start a Redis container:
docker run --name crypto-redis -p 6379:6379 -d redis:7If the container already exists, start it with:
docker start crypto-redisCheck that Redis is running:
docker psYou should see a container named:
crypto-redis
with port mapping:
0.0.0.0:6379->6379/tcp
Run migrations:
python manage.py migrateThis will create a local SQLite database:
db.sqlite3
This project needs four running processes:
1. Redis
2. Django development server
3. Celery worker
4. Celery Beat
Using Docker:
docker start crypto-redisIf the Redis container does not exist yet:
docker run --name crypto-redis -p 6379:6379 -d redis:7In a new terminal, activate the virtual environment and run:
python manage.py runserverThe project uses Django Channels and Daphne for ASGI/WebSocket support.
Open the app in your browser:
http://127.0.0.1:8000/
At this point, the page should load and connect to the WebSocket, but live data will only appear after the Celery worker and Celery Beat are running.
Open another terminal, activate the virtual environment, and run:
On Windows:
celery -A setari worker -l info -P geventOn macOS/Linux:
celery -A setari worker -l infoThe worker should connect to Redis and show that it is ready.
Open another terminal, activate the virtual environment, and run:
celery -A setari beat -l infoCelery Beat will periodically trigger the crypto price fetching task.
When everything is running:
- The browser opens the dashboard.
- Vue.js creates a WebSocket connection.
- Django Channels accepts the connection.
- Celery Beat triggers the scheduled crypto task.
- Celery Worker fetches data from CoinGecko.
- The backend updates coin data and sends it to the WebSocket group.
- The browser receives the update.
- Vue.js updates the dashboard without refreshing the page.
The frontend connects to:
ws://127.0.0.1:8000/ws/some_url/
In production over HTTPS, this should use:
wss://
instead of:
ws://
When the page first loads:
Connected. Waiting for live crypto data...
After Celery Beat and the worker send data:
Live data received.
The dashboard then displays the latest cryptocurrency data.
The backend sends data similar to:
[
{
"id": "bitcoin",
"name": "bitcoin",
"image": "https://...",
"price": 104500,
"state": "raise"
},
{
"id": "ethereum",
"name": "ethereum",
"image": "https://...",
"price": 2500,
"state": "fall"
}
]The frontend uses state to apply styling:
raise → green price
fall → red price
same → normal price
For local development, the current setup can use Redis directly:
redis://localhost:6379
For production, these values should be moved to environment variables:
SECRET_KEY=your-secret-key
DEBUG=False
ALLOWED_HOSTS=your-domain.com
REDIS_URL=redis://your-redis-urlIf the browser console or server log shows:
GET /ws/some_url/ HTTP/1.1 404
then the app is not running through ASGI/Channels correctly.
Make sure daphne is installed and added to INSTALLED_APPS.
Example:
INSTALLED_APPS = [
"daphne",
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"channels",
"coins",
]Also make sure:
ASGI_APPLICATION = "setari.asgi.application"Make sure all four processes are running:
Redis
Django server
Celery worker
Celery Beat
If Celery Beat is not running, the scheduled task will not be sent.
If the Celery worker is not running, the scheduled task will not be executed.
Make sure the Redis Docker container is running:
docker psIf it is stopped:
docker start crypto-redisCoinGecko may rate-limit frequent requests.
For production, consider:
- using an API key;
- increasing the polling interval;
- caching responses;
- handling
429 Too Many Requests.
