{"id":13502368,"url":"https://github.com/DazWorrall/flask-sse","last_synced_at":"2025-03-29T10:32:56.427Z","repository":{"id":5117549,"uuid":"6281916","full_name":"DazWorrall/flask-sse","owner":"DazWorrall","description":null,"archived":false,"fork":false,"pushed_at":"2016-04-10T21:37:22.000Z","size":12,"stargazers_count":120,"open_issues_count":0,"forks_count":23,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-16T07:11:23.894Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"kohana/core","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DazWorrall.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-10-18T16:33:20.000Z","updated_at":"2025-01-20T10:21:50.000Z","dependencies_parsed_at":"2022-09-01T13:10:41.194Z","dependency_job_id":null,"html_url":"https://github.com/DazWorrall/flask-sse","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DazWorrall%2Fflask-sse","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DazWorrall%2Fflask-sse/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DazWorrall%2Fflask-sse/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DazWorrall%2Fflask-sse/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DazWorrall","download_url":"https://codeload.github.com/DazWorrall/flask-sse/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246174207,"owners_count":20735406,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-07-31T22:02:11.731Z","updated_at":"2025-03-29T10:32:56.097Z","avatar_url":"https://github.com/DazWorrall.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"Flask-Sse\n=========\n\nA simple [Flask][0] extension for HTML5 [server-sent events][1] support, powered by [Redis][2]\n\nThe extension provides 2 things - a blueprint with a single route for streaming events, and a helper function to send messages to subscribers:\n\n    from flask import Flask, json\n    from flask.ext.sse import sse, send_event\n    \n    app = Flask(__name__)\n    app.register_blueprint(sse, url_prefix='/stream')\n    \n    @app.route('/send')\n    def send_message():\n        send_event('myevent', json.dumps({\"message\": \"Hello!\"}))\n        \nYou can then subscribe to these events in a supported browser:\n\n    \u003c!DOCTYPE html\u003e\n    \u003chtml\u003e\n    \u003chead\u003e\n      \u003cmeta charset=\"utf-8\" /\u003e\n    \u003c/head\u003e\n    \u003cbody\u003e\n      \u003cscript\u003e\n        var source = new EventSource(\"{{ url_for('sse.stream') }}\");\n        source.addEventListener('myevent', function(e) {\n            var data = JSON.parse(e.data);\n            // handle event\n        }, false);\n      \u003c/script\u003e\n    \u003c/body\u003e\n    \u003c/html\u003e\n\nThe source comes with a basic example\n\nClients can subscribe to different channels by setting 'channel' on the query string, which defaults to 'sse'. These correspond to redis channels.\n\n    def send_message():\n        send_event('myevent', json.dumps({\"line\": \"Something happened\"}), channel='logs')\n    \n    #######\n        \n    var source = new EventSource(\"{{ url_for('sse.stream', channel='logs') }}\")    \n    \nBeing a blueprint, you can attach a before_request handler to handle things like access control:\n\n\n    @sse.before_request\n    def check_access():\n        if request.args.get('channel') == 'firehose' and not g.user.is_admin():\n            abort(403)\n\n\n\nConfiguration\n=============\n\nRedis connection details are read from the applications config using the following keys (defaults in [])\n\n* SSE_REDIS_HOST [localhost]\n* SSE_REDIS_PORT [6379]\n* SSE_REDIS_DB \\[0\\]\n\n\nCaveats\n=======\n\nSubscribers will connect and block for a long time, so you should seriously consider running under an asynchronous WSGI server, such as gunicorn+gevent (like the example)\n\nI should also say I'm not really maintaining this beyond accepting the odd pull request - it was built as an experiment but I'm not using it in anger on anything production. I wont be publishing it on PyPi myself for the same reasons - if I start using it properly then it will go on PyPi and have some tests put around it.\n\nCredits\n=======\nInspired by [django-sse](https://github.com/niwibe/django-sse)\n\n\n[0]:http://flask.pocoo.org\n[1]:http://en.wikipedia.org/wiki/Server-sent_events\n[2]:http://redis.io/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDazWorrall%2Fflask-sse","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FDazWorrall%2Fflask-sse","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDazWorrall%2Fflask-sse/lists"}