{"id":24732561,"url":"https://github.com/gonzalo123/flaskws","last_synced_at":"2026-05-06T21:33:11.386Z","repository":{"id":240502674,"uuid":"802805180","full_name":"gonzalo123/flaskws","owner":"gonzalo123","description":"Creating a Real-Time Flask Application with Flask-SocketIO and Redis","archived":false,"fork":false,"pushed_at":"2024-05-21T13:47:48.000Z","size":51,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-22T16:16:08.672Z","etag":null,"topics":["flask","python","websockets"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gonzalo123.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-05-19T10:17:15.000Z","updated_at":"2025-03-01T14:05:34.000Z","dependencies_parsed_at":"2024-05-21T14:48:11.492Z","dependency_job_id":"94b0d3eb-5551-4244-be58-7bf3ab0f182b","html_url":"https://github.com/gonzalo123/flaskws","commit_stats":null,"previous_names":["gonzalo123/flaskws"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/gonzalo123/flaskws","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gonzalo123%2Fflaskws","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gonzalo123%2Fflaskws/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gonzalo123%2Fflaskws/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gonzalo123%2Fflaskws/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gonzalo123","download_url":"https://codeload.github.com/gonzalo123/flaskws/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gonzalo123%2Fflaskws/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32712756,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-06T19:35:05.142Z","status":"ssl_error","status_checked_at":"2026-05-06T19:35:03.996Z","response_time":117,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["flask","python","websockets"],"created_at":"2025-01-27T17:52:46.850Z","updated_at":"2026-05-06T21:33:11.370Z","avatar_url":"https://github.com/gonzalo123.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Creating a Real-Time Flask Application with Flask-SocketIO and Redis\n\nToday, we're going to create a simple Flask application with real-time communication using websockets and the \nSocketIO library. We'll leverage the [Flask-SocketIO](https://flask-socketio.readthedocs.io/) extension for integration.\n\nHere's the plan: while websockets support bidirectional communication, we'll use them exclusively for server-to-client messages. For client-to-server interactions, we'll stick with traditional HTTP communication.\n\nOur application will include session-based authentication. To simulate login, we've created a route called /login that establishes a session. This session-based authentication will also apply to our websocket connections.\n\nA key objective of this tutorial is to enable sending websocket messages from outside the web application. For instance, you might want to send messages from a cron job or an external service. To achieve this, we'll use a message queue to facilitate communication between the SocketIO server and the client application. We'll utilize Redis as our message queue.\n\nThat's the main application\n\n```python\nfrom flask import Flask, render_template, session, request\n\nfrom lib.ws import register_ws, emit_event, EmitWebsocketRequest\nfrom settings import REDIS_HOST, WS_PATH\n\napp = Flask(__name__)\napp.config['SECRET_KEY'] = 'your_secret_key'\n\nregister_ws(app=app, socketio_path=WS_PATH, redis_host=REDIS_HOST)\n\n\n@app.route('/')\ndef index():\n    return render_template('index.html')\n\n\n@app.route('/login')\ndef login():\n    session['user'] = 'Gonzalo'\n    return dict(name=session['user'])\n\n\n@app.post('/api/')\ndef api():\n    data = EmitWebsocketRequest(**request.json)\n    emit_event(data.channel, data.body)\n\n    return dict(status=True)\n```\n\nThat's the html template\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"en\"\u003e\n\u003chead\u003e\n    \u003cmeta charset=\"UTF-8\"\u003e\n    \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"\u003e\n    \u003ctitle\u003eFlask-SocketIO Websocket Example\u003c/title\u003e\n    \u003cscript src=\"//cdn.socket.io/4.0.0/socket.io.min.js\"\u003e\u003c/script\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n\n\u003ch1\u003eFlask-SocketIO Websocket Example\u003c/h1\u003e\n\u003clabel for=\"message\"\u003eMessage:\u003c/label\u003e\n\u003cinput type=\"text\" id=\"message\" placeholder=\"type a message...\"\u003e\n\n\u003cbutton onclick=\"sendMessage()\"\u003eSend\u003c/button\u003e\n\u003cul id=\"messages\"\u003e\u003c/ul\u003e\n\n\u003cscript\u003e\n    document.addEventListener(\"DOMContentLoaded\", function () {\n        let host = location.protocol + '//' + location.hostname + ':' + location.port\n        let socket = io.connect(host, {\n            path: '/ws/socket.io',\n            reconnection: true,\n            reconnectionDelayMax: 5000,\n            reconnectionDelay: 1000\n        });\n\n        socket.on('connect', function () {\n            console.log('Connected to ws');\n        });\n\n        socket.on('disconnect', function () {\n            console.log('Disconnected from ws');\n        });\n\n        socket.on('message', function (msg) {\n            let messages = document.getElementById('messages');\n            let messageItem = document.createElement('li');\n            messageItem.textContent = msg;\n            messages.appendChild(messageItem);\n        });\n\n        window.sendMessage = async function () {\n            const url = '/api/';\n            const payload = {\"channel\": \"message\", \"body\": this.message.value};\n\n            try {\n                const response = await fetch(url, {\n                    method: 'POST',\n                    headers: {'Content-Type': 'application/json'},\n                    body: JSON.stringify(payload)\n                });\n\n                if (!response.ok) {\n                    console.error('Error: ' + response.statusText);\n                }\n\n                await response.json();\n            } catch (error) {\n                console.error('Error:', error);\n            }\n        };\n    });\n\u003c/script\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\nThe register_ws function binds SocketIO to our Flask server. To enable sending messages from outside our Flask application, we need to instantiate SocketIO in two different ways. For this purpose, I've created a ws.py file. Note: I'm using Pydantic to validate the HTTP requests.\n\n```python\nimport logging\nfrom typing import Dict, Any, Union\n\nfrom flask import session\nfrom flask_socketio import SocketIO\nfrom pydantic import BaseModel\n\nlogger = logging.getLogger(__name__)\n\n\nclass Conf:\n    def __init__(self, socketio=None):\n        self._socketio = socketio\n\n    @property\n    def socketio(self):\n        return self._socketio\n\n    @socketio.setter\n    def socketio(self, value):\n        self._socketio = value\n\n\nconf = Conf()\n\n\ndef emit_event(channel, body):\n    conf.socketio.emit(channel, body)\n\n\nclass EmitWebsocketRequest(BaseModel):\n    channel: str\n    body: Union[Dict[str, Any], str]\n\n\ndef setup_ws(redis_host, redis_port=6379):\n    conf.socketio = SocketIO(message_queue=f'redis://{redis_host}:{redis_port}')\n\n\ndef register_ws(\n        app,\n        redis_host,\n        socketio_path='/ws/socket.io',\n        redis_port=6379\n):\n    redis_url = f'redis://{redis_host}:{redis_port}' if redis_host else None\n    conf.socketio = SocketIO(app, path=socketio_path, message_queue=redis_url)\n\n    @conf.socketio.on('connect')\n    def handle_connect():\n        if not session.get(\"user\"):\n            raise ConnectionRefusedError('unauthorized!')\n        logger.debug(f'Client connected: {session[\"user\"]}')\n\n    @conf.socketio.on('disconnect')\n    def handle_disconnect():\n        logger.debug('Client disconnected')\n\n    return conf.socketio\n```\n\nNow, we can emit an event from outside the Flask application.\n\n```python\nfrom lib.ws import emit_event, setup_ws\nfrom settings import REDIS_HOST\n\nsetup_ws(redis_host=REDIS_HOST)\nemit_event('message', 'Hi')\n```\nThe application needs a Redis server. I set up the server using docker.\n\n```yaml\nservices:\n  redis:\n    image: redis:latest\n    ports:\n      - \"6379:6379\"\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgonzalo123%2Fflaskws","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgonzalo123%2Fflaskws","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgonzalo123%2Fflaskws/lists"}