
    
        
        
        
                
        
        
        
                
        
        
        
            
{"version":"https:\/\/jsonfeed.org\/version\/1","title":"mathspp.com feed","home_page_url":"https:\/\/mathspp.com\/blog\/tags\/web-development","feed_url":"https:\/\/mathspp.com\/blog\/tags\/web-development.json","description":"Stay up-to-date with the articles on mathematics and programming that get published to mathspp.com.","author":{"name":"Rodrigo Gir\u00e3o Serr\u00e3o"},"items":[{"title":"Streaming data from Flask to HTMX using Server-Side Events (SSE)","date_published":"2023-03-23T00:00:00+01:00","id":"https:\/\/mathspp.com\/blog\/streaming-data-from-flask-to-htmx-using-server-side-events","url":"https:\/\/mathspp.com\/blog\/streaming-data-from-flask-to-htmx-using-server-side-events","content_html":"<p>This short reference article shows how to stream data from a Flask web app to HTMX using server-side events (SSE).<\/p>\n\n<p><img alt=\"\" src=\"\/images\/6\/6\/e\/2\/3\/66e235c3d20efa9b095321369d9b8d05136d760a-thumbnail.webp\"><\/p>\n<h2 id=\"introduction\">Introduction<a href=\"#introduction\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>I have been trying to create a web app with <a href=\"https:\/\/flask.palletsprojects.com\/en\/2.2.x\/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">Flask<\/a> and <a href=\"https:\/\/htmx.org\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">HTMX<\/a> that updates the page periodically with data streamed from the Flask backend.\nThe <a href=\"https:\/\/flask.palletsprojects.com\/en\/2.1.x\/patterns\/streaming\/#basic-usage\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">Flask documentation suggests that this should be possible<\/a> if the response wraps a generator function and they show this example:<\/p>\n<pre><code class=\"language-py\">@app.route('\/large.csv')\ndef generate_large_csv():\n    def generate():\n        for row in iter_all_rows():\n            yield f\"{','.join(row)}\\n\"\n    return app.response_class(generate(), mimetype='text\/csv')<\/code><\/pre>\n<p>However, this doesn't work with an HTMX request.<\/p>\n<p>I joined the HTMX Discord and I was told this is because HTMX buffers the complete response.<\/p>\n<p>So, I went looking for other options and I found server-side events.<\/p>\n<h2 id=\"how-to-stream-data-from-flask-to-htmx-in-real-time\">How to stream data from Flask to HTMX in real-time<a href=\"#how-to-stream-data-from-flask-to-htmx-in-real-time\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>To be able to stream data back to HTMX and have it update in real-time, the original request needs to connect to SSE with the appropriate HTMX tags.<\/p>\n<p>Then, the Flask backend must return a response with a generator, and the generator itself must return messages that follow the SSE specification.<\/p>\n<p>The following example works with Flask 2.2.3, HTMX 1.8.6, and the SSE extension from HTMX:<\/p>\n<ul><li>\n<code>templates\/index.html<\/code>:<\/li>\n<\/ul><pre><code class=\"language-html\">&lt;!DOCTYPE html5&gt;\n&lt;head&gt;\n    &lt;script src=\"https:\/\/unpkg.com\/htmx.org@1.8.6\"&gt;&lt;\/script&gt;\n    &lt;script src=\"https:\/\/unpkg.com\/htmx.org\/dist\/ext\/sse.js\"&gt;&lt;\/script&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n    &lt;p&gt;Here.&lt;\/p&gt;\n    &lt;div hx-ext=\"sse\" sse-connect=\"\/connect\" sse-swap=\"message\"&gt;\n        Contents of this box will be updated in real time\n        with every SSE message received from the chatroom.\n    &lt;\/div&gt;\n    &lt;button hx-post=\"\/pong\" hx-swap=\"outerHTML\"&gt;Pong&lt;\/button&gt;\n&lt;\/body&gt;<\/code><\/pre>\n<ul><li>\n<code>main.py<\/code>:<\/li>\n<\/ul><pre><code class=\"language-py\">import itertools\nimport time\n\nfrom flask import Flask, render_template, Response\n\napp = Flask(__name__)\n\n@app.route(\"\/\")\ndef index():\n    return render_template(\"index.html\")\n\n@app.route(\"\/connect\")\ndef publish_hello():\n    def stream():\n        for idx in itertools.count():\n            msg = f\"data: &lt;p&gt;This is {idx}.&lt;\/p&gt;\\n\\n\"\n            yield msg\n            time.sleep(1)\n\n    return Response(stream(), mimetype=\"text\/event-stream\")\n\n@app.post(\"\/ping\")\ndef route_clicked():\n    return \"\"\"&lt;button hx-post=\"\/pong\" hx-swap=\"outerHTML\"&gt;Pong&lt;\/button&gt;\"\"\"\n\n@app.post(\"\/pong\")\ndef route_pong():\n    return \"\"\"&lt;button hx-post=\"\/ping\" hx-swap=\"outerHTML\"&gt;Ping&lt;\/button&gt;\"\"\"\n\nif __name__ == \"__main__\":\n    app.run(debug=True)<\/code><\/pre>\n<p>If you run your Flask app and open it in your browser, you should see something like this:<\/p>\n<figure class=\"image-caption\"><img title=\"HTMX web page that updates with real-time data from Flask.\" alt=\"Screenshot of a simple web page that uses HTMX to fetch data from Flask and that uses server-side events (SSE) to stream data back from Flask.\" src=\"\/user\/pages\/02.blog\/streaming-data-from-flask-to-htmx-using-server-side-events\/_demo_screenshot.webp\"><figcaption class=\"\">HTMX web page that updates with real-time data from Flask.<\/figcaption><\/figure><p>The second paragraph should update every second with an increasing counter.<\/p>\n<p>The button &ldquo;Pong&rdquo; below is to show that the Flask app still works and clicking the Ping \/ Pong buttons should POST a request to Flask that returns the other button.<\/p>\n<h2 id=\"start-streaming-on-request\">Start streaming on request<a href=\"#start-streaming-on-request\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>The example below connects as soon as the page loads but you may want to use SSE to stream data back from a specific request, instead of on page load.<\/p>\n<p>To do that, what you can do is return the HTML that connects to SSE when <em>that<\/em> event is triggered.\nThe example below shows another simple page with a button that says &ldquo;Connect&rdquo;.\nWhen you click that button, we return the HTML that establishes the SSE connection with Flask and then we start streaming the data:<\/p>\n<ul><li>\n<code>index.html<\/code>:<\/li>\n<\/ul><pre><code class=\"language-html\">&lt;!DOCTYPE html5&gt;\n&lt;head&gt;\n    &lt;script src=\"https:\/\/unpkg.com\/htmx.org@1.8.6\"&gt;&lt;\/script&gt;\n    &lt;script src=\"https:\/\/unpkg.com\/htmx.org\/dist\/ext\/sse.js\"&gt;&lt;\/script&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n    &lt;p&gt;Here.&lt;\/p&gt;\n    &lt;button hx-post=\"\/start-connection\" hx-swap=\"outerHTML\"&gt;Connect&lt;\/button&gt;\n    &lt;button hx-post=\"\/pong\" hx-swap=\"outerHTML\"&gt;Pong&lt;\/button&gt;\n&lt;\/body&gt;<\/code><\/pre>\n<ul><li>\n<code>main.py<\/code>:<\/li>\n<\/ul><pre><code class=\"language-py\">import itertools\nimport time\n\nfrom flask import Flask, render_template, Response\n\napp = Flask(__name__)\n\n@app.route(\"\/\")\ndef index():\n    return render_template(\"index.html\")\n\n@app.post(\"\/start-connection\")\ndef start_connection():\n    return \"\"\"&lt;div hx-ext=\"sse\" sse-connect=\"\/connect\" sse-swap=\"message\"&gt;...<\/code><\/pre>","summary":"This short reference article shows how to stream data from a Flask web app to HTMX.","date_modified":"2025-11-22T09:33:35+01:00","tags":["flask","programming","python","web development"],"image":"\/user\/pages\/02.blog\/streaming-data-from-flask-to-htmx-using-server-side-events\/thumbnail.webp"},{"title":"TIL #045 \u2013 using JavaScript functions in PyScript","date_published":"2022-05-01T00:00:00+02:00","id":"https:\/\/mathspp.com\/blog\/til\/045","url":"https:\/\/mathspp.com\/blog\/til\/045","content_html":"<p>Today I learned how to use JavaScript functions in PyScript.<\/p>\n\n<script async src=\"https:\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script>\n<script defer src=\"\/user\/themes\/myquark\/js\/pyscript_alpha.min.js\"><\/script>\n<py-script>\nimport datetime\n\nfrom js import setInterval\nfrom pyodide import to_js\n\ndef update_timestamp(elem):\n    elem.write(\n        format(datetime.datetime.now(), \"%H:%M:%S, %A, %d %B %Y\")\n    )\n\nelem = Element(\"timestamp_updater\")\n_ = setInterval(\n    to_js(lambda: update_timestamp(elem)),\n    1000  # Update every 1000 ms\n)\n<\/py-script>\n<h2 id=\"what-is-pyscript\">What is PyScript?<a href=\"#what-is-pyscript\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>In case you missed, yesterday I learned about <a href=\"\/blog\/til\/pyscript\">PyScript<\/a>,\na tool that allows you to use Python inside your HTML!\nIn other words, PyScript enables you to run Python on the client side.<\/p>\n<h2 id=\"how-to-use-javascript-functions-in-pyscript\">How to use JavaScript functions in PyScript?<a href=\"#how-to-use-javascript-functions-in-pyscript\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>In order to use JavaScript functions in PyScript, you can import them from the available <code>js<\/code> module.\nFor example, to use <code>console.log<\/code> from within PyScript, you just type <code>from js import console<\/code> in your PyScript tag.\nThen, you can call <code>console.log<\/code> regularly:<\/p>\n<pre><code class=\"language-html\">&lt;py-script&gt;\nfrom js import console\n\nconsole.log(\"Hey there, from 'console.log' inside PyScript!\")\n&lt;\/py-script&gt;<\/code><\/pre>\n<p>If you include that in one of your pages and then check the console,\nyou will find the message <code>Hey there, from 'console.log' inside PyScript!<\/code> in there.<\/p>\n<p>Let me show another example that is slightly more involved.<\/p>\n<h2 id=\"running-a-python-function-periodically-with-setinterval\">Running a Python function periodically with <code>setInterval<\/code><a href=\"#running-a-python-function-periodically-with-setinterval\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>JavaScript has a function <code>setInterval<\/code> that lets you run a function periodically.\nIf we write <code>from js import setInterval<\/code>, that function becomes available to us.\nThat is what is being used to update the timestamp in the next paragraph.<\/p>\n<div class=\"notices blue\">\n<p>It is now <span id=\"timestamp_updater\"><\/span>.<\/p>\n<\/div>\n<p>(If the paragraph above doesn't contain a timestamp that updates every second,\nsomething is broken!\nRight now, PyScript is in alpha, so that might be it...\nBut it may be my fault as well \ud83d\ude43)<\/p>\n<p>What code did I use to get that to run?\nNot much!\nIn this blog post, I just had to link to the PyScript JavaScript file,\nand then I added the following HTML\/Python code:<\/p>\n<pre><code class=\"language-html\">&lt;py-script&gt;\nimport datetime\n\nfrom js import setInterval\nfrom pyodide import to_js\n\ndef update_timestamp(elem):\n    elem.write(\n        format(datetime.datetime.now(), \"%H:%M:%S, %A, %d %B %Y\")\n    )\n\nelem = Element(\"timestamp_updater\")\n_ = setInterval(\n    to_js(lambda: update_timestamp(elem)),\n    1000  # Update every 1000 ms\n)\n&lt;\/py-script&gt;<\/code><\/pre>\n<p>Pretty cool, right?<\/p>\n<p>I learned this by reading a thread that was published on Twitter:<\/p>\n<blockquote class=\"twitter-tweet\"><p lang=\"en\" dir=\"ltr\">Going to be tweeting the session on <a href=\"https:\/\/twitter.com\/pyodide?ref_src=twsrc%5Etfw\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">@pyodide<\/a> now. This is the app on top of which PyScript is built. Speakers are Hood Chatham and <a href=\"https:\/\/twitter.com\/RomanYurchak?ref_src=twsrc%5Etfw\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">@RomanYurchak<\/a> <a href=\"https:\/\/twitter.com\/hashtag\/PyConUS2022?src=hash&amp;ref_src=twsrc%5Etfw\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">#PyConUS2022<\/a><\/p>\u2014 Playful Python (@playfulpython) <a href=\"https:\/\/twitter.com\/playfulpython\/status\/1520763819152519168?ref_src=twsrc%5Etfw\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">May 1, 2022<\/a><\/blockquote>\n<p>That's it for now! <a href=\"\/subscribe\">Stay tuned<\/a> and I'll see you around!<\/p>","summary":"Today I learned how to use JavaScript functions in PyScript.","date_modified":"2025-07-23T16:49:02+02:00","tags":["javascript","programming","python","web development"],"image":"\/user\/pages\/02.blog\/04.til\/045.using-javascript-functions-in-pyscript\/thumbnail.webp"},{"title":"TIL #044 \u2013 PyScript","date_published":"2022-04-30T00:00:00+02:00","id":"https:\/\/mathspp.com\/blog\/til\/044","url":"https:\/\/mathspp.com\/blog\/til\/044","content_html":"<p>Today I learned about PyScript, a tool that lets you run Python in your HTML!<\/p>\n\n<script async src=\"https:\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script>\n<script defer src=\"\/user\/themes\/myquark\/js\/pyscript_alpha.min.js\"><\/script>\n<py-script>\nimport datetime\n\noutput = Element(\"py-script-target\")\nnow = format(datetime.datetime.now(), \"%H:%M, %A, %d %B %Y.\")\noutput.write(now)\n<\/py-script>\n<h2 id=\"pyscript\">PyScript<a href=\"#pyscript\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<h3 id=\"run-python-in-your-html\">Run Python in Your HTML<a href=\"#run-python-in-your-html\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h3>\n<p>Today I learned about <a href=\"https:\/\/pyscript.net\/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">PyScript<\/a>, a tool that lets you run Python from within your HTML!<\/p>\n<p>I got so excited when I found out about this tool\n(which was presented to the world today, if I am not mistaken!)\nthat I had to give it a try right away!<\/p>\n<p>For example, you opened this page, it loaded, and then it inserted a timestamp here: <span id=\"py-script-target\"><\/span><\/p>\n<p>(If the timestamp doesn't show right away, wait a couple of seconds.\nIf it still doesn't show, take into account that the PyScript version I am using here has only been tested on Chrome.)<\/p>\n<p>This timestamp, which corresponds roughly to when the page finished loading,\nwas put there by Python.\nI just had to write some code in the HTML of this page:<\/p>\n<pre><code class=\"language-html\">&lt;py-script&gt;\nimport datetime\n\noutput = Element(\"py-script-target\")\nnow = format(datetime.datetime.now(), \"%H:%M, %A, %d %B %Y.\")\noutput.write(now)\n&lt;\/py-script&gt;<\/code><\/pre>\n<p>The <code>output = Element(\"py-script-target\")<\/code> assigns a <code>&lt;span&gt;<\/code> tag I have in the source of the page to the variable <code>output<\/code>.\nThen, I use standard Python to format the current date (<code>datetime.datetime.now()<\/code>) into a format I like.\nFinally, I write that string to the <code>&lt;span&gt;<\/code> element from before!<\/p>\n<p>I am very excited to see what people build with this tool!\nJust bear in mind that it is still in its early stages of development.<\/p>\n<p>By the way, I found out about PyScript from a tweet:<\/p>\n<blockquote class=\"twitter-tweet\"><p lang=\"en\" dir=\"ltr\"><a href=\"https:\/\/twitter.com\/hashtag\/PyConUS2022?src=hash&amp;ref_src=twsrc%5Etfw\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">#PyConUS2022<\/a> <a href=\"https:\/\/twitter.com\/pwang?ref_src=twsrc%5Etfw\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">@pwang<\/a> Keynote: Announcing Py-script!!!<br>It's Python! inside HTML!!! \ud83e\udd2f <a href=\"https:\/\/t.co\/paDsibNQtt\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">pic.twitter.com\/paDsibNQtt<\/a><\/p>\u2014 Mariatta \ud83e\udd26 (@mariatta) <a href=\"https:\/\/twitter.com\/mariatta\/status\/1520432987359399936?ref_src=twsrc%5Etfw\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">April 30, 2022<\/a><\/blockquote>\n<p>That's it for now! <a href=\"\/subscribe\">Stay tuned<\/a> and I'll see you around!<\/p>","summary":"Today I learned about PyScript, a tool that lets you run Python in your HTML!","date_modified":"2025-07-23T16:49:02+02:00","tags":["programming","python","web development"],"image":"\/user\/pages\/02.blog\/04.til\/044.pyscript\/thumbnail.webp"}]}
