<?xml version="1.0" encoding="UTF-8"?>
<rss  xmlns:atom="http://www.w3.org/2005/Atom" 
      xmlns:media="http://search.yahoo.com/mrss/" 
      xmlns:content="http://purl.org/rss/1.0/modules/content/" 
      xmlns:dc="http://purl.org/dc/elements/1.1/" 
      version="2.0">
<channel>
<title>Hamel&#39;s Blog</title>
<link>https://glittering-puffpuff-87102e.netlify.app/notes/fasthtml/</link>
<atom:link href="https://glittering-puffpuff-87102e.netlify.app/notes/fasthtml/index.xml" rel="self" type="application/rss+xml"/>
<description>Web development in FastHTML</description>
<image>
<url>https://user-images.githubusercontent.com/1483922/208359222-2b7e938e-27c4-4556-aacb-f5a81ce77b2d.png</url>
<title>Hamel&#39;s Blog</title>
<link>https://glittering-puffpuff-87102e.netlify.app/notes/fasthtml/</link>
</image>
<generator>quarto-1.9.38</generator>
<lastBuildDate>Thu, 29 May 2025 07:00:00 GMT</lastBuildDate>
<item>
  <title>Building Annotation Apps with FastHTML</title>
  <link>https://glittering-puffpuff-87102e.netlify.app/notes/fasthtml/annotation-apps.html</link>
  <description><![CDATA[ 

<!-- Content inserted at the beginning of body tag -->
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-PKGWQMKL" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->




<p><strong>Notes from “Building annotation apps in FastHTML” from the <a href="https://bit.ly/evals_ai">LLM evals course</a>.</strong></p>
<div class="quarto-video ratio ratio-16x9"><iframe data-external="1" src="https://www.youtube.com/embed/fA4pe9bE0LY?si=LX2GVDViNoSJjj9W" title="" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe></div>
<section id="notes" class="level2">
<h2 class="anchored" data-anchor-id="notes">Notes</h2>
<section id="how-do-i-handle-ai-coding-assistance-when-fasthtml-isnt-as-well-known-as-reactnext.js" class="level3">
<h3 class="anchored" data-anchor-id="how-do-i-handle-ai-coding-assistance-when-fasthtml-isnt-as-well-known-as-reactnext.js">How do I handle AI coding assistance when FastHTML isn’t as well-known as React/Next.js?</h3>
<blockquote class="blockquote">
<p>Developers worry about “swimming upstream” by choosing FastHTML when AI assistants like Claude and GPT-4 have much better training on mainstream frameworks.</p>
</blockquote>
<p>The solution is investing in good cursor rules and context files. Isaac shared that he uses <a href="https://github.com/ai-evals-course/isaac-fasthtml-workshop/tree/main/.cursor/rules">detailed cursor rules for FastHTML</a> that provide examples and patterns. He notes: “if you give the right context to the model…it does a lot better.” The companion repo includes these cursor rule files that help AI understand FastHTML patterns.</p>
<p>Wade from the Discord added another perspective: “Cursor + good cursor rules has proven to be a good combo for me personally.” The key is that with FastHTML, you’re working with ~80 lines of code for a functional annotation app versus hundreds more with other frameworks. This smaller codebase is easier to understand and debug when AI suggestions go wrong.</p>
<p>As Isaac put it: “I find that with pure vibe coding, I start out with super fast progress then my iteration speed slowly gets worse over time until I get really frustrated.” With FastHTML plus good context, you maintain consistent development velocity.</p>
</section>
<section id="should-i-build-a-custom-annotation-tool-or-use-something-off-the-shelf" class="level3">
<h3 class="anchored" data-anchor-id="should-i-build-a-custom-annotation-tool-or-use-something-off-the-shelf">Should I build a custom annotation tool or use something off-the-shelf?</h3>
<p>At the moment there is a narrow gap between how long it takes you to build your own labeling thing and configuring an off the shelf tool (Argilla, Prodigy, etc.). There is a non-trivial amount of things that you have to sort through to configure all the settings with an off-the-shelf tool, as well as some limitations.</p>
<p>Custom tools make sense when:</p>
<ul>
<li>You have domain-specific workflows (like the medical flashcard example Isaac showed)</li>
<li>You need tight integration with your data pipeline</li>
<li>Your annotation needs will evolve based on what you learn</li>
</ul>
<p>However, existing tools have advantages for:</p>
<ul>
<li>Large-scale team collaboration with many distributed annotators</li>
<li>When you need enterprise features like detailed access controls</li>
<li>If you have standard annotation needs that fit the tool’s paradigm</li>
</ul>
<p><a href="https://youtu.be/fA4pe9bE0LY">Isaac’s Anki flashcard annotation app</a> demonstrates when custom makes sense - they needed to handle 400+ results per query with keyboard navigation, multi-step review processes, and domain-specific evaluation criteria that would be difficult to configure in a generic tool.</p>
</section>
<section id="how-should-i-handle-disagreements-between-annotators-in-my-annotation-app" class="level3">
<h3 class="anchored" data-anchor-id="how-should-i-handle-disagreements-between-annotators-in-my-annotation-app">How should I handle disagreements between annotators in my annotation app?</h3>
<blockquote class="blockquote">
<p>Annotation disagreements are inevitable, but the workflow for resolving them depends on whether you’re refining the rubric or just collecting labels. Many teams struggle with when to show annotations to other reviewers.</p>
</blockquote>
<p><strong>Answer</strong>: The approach depends on your goals. Shreya explains: “If you truly want independent annotations from annotators, yes you might want to hide comments. But sometimes the annotators are jointly working together to review a large amount of traces…and showing the comments standardizes interpretations of good and bad between annotators.”</p>
<p>Isaac’s implementation takes a pragmatic approach: “Eventually we need to decide what score to assign to it. We could do a second round where annotators cannot peek at other comments. However, in the AnkiHub case, they found that annotator disagreements often stemed from incomplete rubrics.” This highlights a key principle - if you’re still defining what “good” looks like, facilitating discussion between annotators helps refine the rubric. Once the rubric is stable, you might want more independent annotation.</p>
<p>The FastHTML app Isaac built handles this with a “finalized” step where disagreements trigger a review process with comments, allowing annotators to explain their reasoning and reach consensus.</p>
</section>
<section id="when-should-i-use-fasthtml-vs-streamlit-for-annotation-apps" class="level3">
<h3 class="anchored" data-anchor-id="when-should-i-use-fasthtml-vs-streamlit-for-annotation-apps">When should I use FastHTML vs Streamlit for annotation apps?</h3>
<p>Isaac recommends FastHTML when you need flexibility beyond simple dashboards. Isaac elaborated that “FastHTML is more flexible and a full web app. If you feel like you have some really custom or unusual things that might be tricky to get right, maybe not streamlit.”</p>
<p>The key differentiator is state management complexity. As discussed in the Discord, “state management in streamlit is a nightmare if you have anything a bit complex.” For simple annotation interfaces with minimal state, Streamlit works fine. But once you need features like multi-step workflows, keyboard shortcuts for rapid annotation, or custom UI components, FastHTML’s flexibility becomes valuable.</p>
<p>The choice depends on your needs - start with Streamlit if it meets your requirements, but be prepared to switch to FastHTML if you hit limitations.</p>
</section>
</section>
<section id="isaacs-code-slides" class="level2">
<h2 class="anchored" data-anchor-id="isaacs-code-slides">Isaac’s Code &amp; Slides</h2>
<ol type="1">
<li><p><a href="https://github.com/ai-evals-course/isaac-fasthtml-workshop">Isaac’s Anki flashcard annotation app</a></p></li>
<li><p><a href="https://ai-evals-course.github.io/isaac-fasthtml-workshop/presentation/talk.html#/title-slide">Issac’s Slides</a></p></li>
</ol>


</section>

 ]]></description>
  <guid>https://glittering-puffpuff-87102e.netlify.app/notes/fasthtml/annotation-apps.html</guid>
  <pubDate>Thu, 29 May 2025 07:00:00 GMT</pubDate>
  <media:content url="https://glittering-puffpuff-87102e.netlify.app/notes/fasthtml/isaac.png" medium="image" type="image/png" height="81" width="144"/>
</item>
<item>
  <title>Concurrency For Starlette Apps (e.g FastAPI / FastHTML)</title>
  <link>https://glittering-puffpuff-87102e.netlify.app/notes/fasthtml/concurrency.html</link>
  <description><![CDATA[ 

<!-- Content inserted at the beginning of body tag -->
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-PKGWQMKL" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->




<p><strong>Motivation</strong>: we often want to call LLMs in Starlette based apps (<a href="https://fastht.ml/">FastHTML</a>, <a href="https://fastapi.tiangolo.com/tutorial/security/">FastAPI</a>, etc.) apps, and we don’t want to block the server on network calls to APIs.</p>
<p>This post documents my explorations of various approaches that can run tasks in the background without blocking the main process.</p>
<div class="callout callout-style-default callout-tip callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Tip
</div>
</div>
<div class="callout-body-container callout-body">
<p>You can <a href="https://github.com/hamelsmu/hamel-site/blob/master/notes/fasthtml/concurrency.ipynb">see this notebook here</a>.</p>
</div>
</div>
<section id="using-a-sql-database-as-a-queue" class="level2">
<h2 class="anchored" data-anchor-id="using-a-sql-database-as-a-queue">Using A SQL Database As A Queue</h2>
<p>We will use <a href="https://github.com/AnswerDotAI/fastlite">fastlite</a> as the interface to our SQL database.</p>
<section id="why" class="level3">
<h3 class="anchored" data-anchor-id="why">Why</h3>
<p>You are often already using a database for your web application, and if you need to process items in that database with some kind queue, its convenient to use the database itself!</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://glittering-puffpuff-87102e.netlify.app/notes/fasthtml/hn.png" class="img-fluid figure-img"></p>
<figcaption>Screenshot is from this <a href="https://news.ycombinator.com/item?id=27482402">HN Comment</a></figcaption>
</figure>
</div>
</section>
<section id="first-lets-define-our-queue-table" class="level3">
<h3 class="anchored" data-anchor-id="first-lets-define-our-queue-table">First, let’s define our queue table:</h3>
<div id="15087c2b" class="cell" data-execution_count="2">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb1-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> fastlite <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span></span>
<span id="cb1-2">Path(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'queue.db'</span>).delete()</span>
<span id="cb1-3"></span>
<span id="cb1-4">db <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Database(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'queue.db'</span>)</span>
<span id="cb1-5"></span>
<span id="cb1-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> QueueItem:</span>
<span id="cb1-7">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">id</span>: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span></span>
<span id="cb1-8">    data: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span></span>
<span id="cb1-9">    expire: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Unix timestamp</span></span>
<span id="cb1-10"></span>
<span id="cb1-11">queue <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> db.create(QueueItem, pk<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'id'</span>)</span></code></pre></div></div>
</div>
</section>
<section id="now-lets-implement-the-enqueue-operation" class="level3">
<h3 class="anchored" data-anchor-id="now-lets-implement-the-enqueue-operation">Now, let’s implement the enqueue operation:</h3>
<div id="e6449b6d" class="cell" data-execution_count="3">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb2-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> enqueue(data): <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> queue.insert(data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>data, expire<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
</div>
</section>
<section id="for-the-dequeue-operation-well-implement-the-logic-described-in-the-comment" class="level3">
<h3 class="anchored" data-anchor-id="for-the-dequeue-operation-well-implement-the-logic-described-in-the-comment">For the dequeue operation, we’ll implement the logic described in the comment:</h3>
<div id="ff185083" class="cell" data-execution_count="4">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb3-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> time</span>
<span id="cb3-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> dequeue():</span>
<span id="cb3-3">    available_items <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> queue(where<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"expire = 0"</span>, limit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb3-4">    </span>
<span id="cb3-5">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> available_items: <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Queue is empty</span></span>
<span id="cb3-6">    </span>
<span id="cb3-7">    item <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> available_items[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]</span>
<span id="cb3-8">    future_time <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>(time.time()) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">300</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 5 minutes from now</span></span>
<span id="cb3-9">    </span>
<span id="cb3-10">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Step 2: UPDATE SET expire = future_time WHERE id = item.id AND expire = 0</span></span>
<span id="cb3-11">    updated_item <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> queue.update(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">id</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>item.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">id</span>, expire<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>future_time)</span>
<span id="cb3-12">    </span>
<span id="cb3-13">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> updated_item.expire <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> future_time: <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> updated_item</span>
<span id="cb3-14">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>: <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> dequeue()</span></code></pre></div></div>
</div>
</section>
<section id="lets-see-it-in-action" class="level3">
<h3 class="anchored" data-anchor-id="lets-see-it-in-action">Let’s See It In Action!</h3>
<div id="b2c077ea" class="cell" data-execution_count="5">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb4-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Enqueue some items</span></span>
<span id="cb4-2">enqueue(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Task 1"</span>)</span>
<span id="cb4-3">enqueue(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Task 2"</span>)</span>
<span id="cb4-4">enqueue(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Task 3"</span>)</span>
<span id="cb4-5"></span>
<span id="cb4-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Dequeue and process items</span></span>
<span id="cb4-7"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">while</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>:</span>
<span id="cb4-8">    item <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> dequeue()</span>
<span id="cb4-9">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> item <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">is</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>:</span>
<span id="cb4-10">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Queue is empty"</span>)</span>
<span id="cb4-11">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">break</span></span>
<span id="cb4-12">    </span>
<span id="cb4-13">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Processing </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>item<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Processing Task 1
Processing Task 2
Processing Task 3
Queue is empty</code></pre>
</div>
</div>
</section>
</section>
<section id="using-threads-to-run-tasks-in-background" class="level2">
<h2 class="anchored" data-anchor-id="using-threads-to-run-tasks-in-background">Using Threads To Run Tasks In Background</h2>
<p>Next, we want perform proceessing on items from the queue, but do so in the background. We can use the <code>ThreadPoolExecutor</code> from Python’s <code>concurrent.futures</code> module to process items in a thread pool without blocking the main process. Here’s how we can modify our implementation to achieve this:</p>
<div id="fdce3dce" class="cell" data-execution_count="6">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb6-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> concurrent.futures <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> ThreadPoolExecutor</span>
<span id="cb6-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> time</span>
<span id="cb6-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> threading</span></code></pre></div></div>
</div>
<div id="7e61d557" class="cell" data-execution_count="7">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb7-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> proc_item(item): <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Simulate some work</span></span>
<span id="cb7-2">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Processing </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>item<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb7-3">    time.sleep(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span>
<span id="cb7-4">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Finished processing </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>item<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb7-5"></span>
<span id="cb7-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> worker():</span>
<span id="cb7-7">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">while</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>:</span>
<span id="cb7-8">        item <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> dequeue()</span>
<span id="cb7-9">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> item <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">is</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>: <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">break</span></span>
<span id="cb7-10">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">yield</span> item</span>
<span id="cb7-11"></span>
<span id="cb7-12"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> run_queue_processor_background(n_workers<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>):</span>
<span id="cb7-13">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> background_task():</span>
<span id="cb7-14">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">with</span> ThreadPoolExecutor(n_workers) <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> ex: ex.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">map</span>(proc_item, worker())</span>
<span id="cb7-15">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Queue processing completed"</span>)</span>
<span id="cb7-16">        </span>
<span id="cb7-17">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Start the background thread</span></span>
<span id="cb7-18">    thread <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> threading.Thread(target<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>background_task)</span>
<span id="cb7-19">    thread.start()</span>
<span id="cb7-20">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> thread  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Return the thread object in case we want to join it later</span></span></code></pre></div></div>
</div>
<div id="72d18aff" class="cell" data-execution_count="8">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb8-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> i <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>): enqueue(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Task </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>) <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Enqueue some items</span></span></code></pre></div></div>
</div>
<div id="33144308" class="cell" data-execution_count="9">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb9-1">processor_thread <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> run_queue_processor_background()</span>
<span id="cb9-2"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Main process continues..."</span>) <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Main process can continue immediately</span></span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Main process continues...
Processing Task 1
Processing Task 2
Processing Task 3
Finished processing Task 2Finished processing Task 1
Processing Task 4

Processing Task 5
Finished processing Task 3
Finished processing Task 4Finished processing Task 5

Queue processing completed</code></pre>
</div>
</div>
</section>
<section id="async-processing" class="level2">
<h2 class="anchored" data-anchor-id="async-processing">Async Processing</h2>
<p>On a completely separate note, we can use async processing, which is very similar to threads. The main benefit of async over threads is that async is easier to debug (stacktrace, breakpoints, etc).</p>
<p>In the code below, we are calling openai library with asyncio. You will see that async is faster than sync in this case, because the majority of the work involves waiting for the response, which is perfect for async</p>
<div id="197bd0a8" class="cell" data-execution_count="10">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb11-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> asyncio</span>
<span id="cb11-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> time</span>
<span id="cb11-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> openai <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> AsyncOpenAI, OpenAI</span>
<span id="cb11-4"></span>
<span id="cb11-5">prompts <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Tell me a joke"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"What's the capital of France?"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Explain quantum computing"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"How many planets are in the solar system?"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"What is the meaning of life?"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"How many bytes are in a kilobyte?"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"When was the first iPhone released?"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"What is the capital of Canada?"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"What is the capital of Australia?"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"What is the capital of the United Kingdom?"</span>]</span></code></pre></div></div>
</div>
<div id="cc1988c4" class="cell" data-execution_count="11">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb12-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">async</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> async_process_prompt(client, prompt):</span>
<span id="cb12-2">    response <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> client.chat.completions.create(</span>
<span id="cb12-3">        model<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gpt-3.5-turbo"</span>,</span>
<span id="cb12-4">        messages<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[{<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"role"</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"user"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"content"</span>: prompt}]</span>
<span id="cb12-5">    )</span>
<span id="cb12-6">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> response.choices[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].message.content</span>
<span id="cb12-7"></span>
<span id="cb12-8"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> sync_process_prompt(client, prompt):</span>
<span id="cb12-9">    response <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> client.chat.completions.create(</span>
<span id="cb12-10">        model<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gpt-3.5-turbo"</span>,</span>
<span id="cb12-11">        messages<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[{<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"role"</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"user"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"content"</span>: prompt}]</span>
<span id="cb12-12">    )</span>
<span id="cb12-13">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> response.choices[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].message.content</span>
<span id="cb12-14"></span>
<span id="cb12-15"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">async</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> async_main():</span>
<span id="cb12-16">    client <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> AsyncOpenAI()</span>
<span id="cb12-17">    start_time <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> time.time()</span>
<span id="cb12-18">    tasks <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [async_process_prompt(client, prompt) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> prompt <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> prompts]</span>
<span id="cb12-19">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># you can modify this code (see below) if you wish to just run this completely in the background.</span></span>
<span id="cb12-20">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> asyncio.gather(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>tasks) </span>
<span id="cb12-21">    end_time <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> time.time()</span>
<span id="cb12-22">    async_time <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> end_time <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> start_time</span>
<span id="cb12-23">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Async processing time: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>async_time<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.2f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> seconds"</span>)</span>
<span id="cb12-24">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> async_time</span>
<span id="cb12-25"></span>
<span id="cb12-26"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> sync_main():</span>
<span id="cb12-27">    client <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> OpenAI()</span>
<span id="cb12-28">    start_time <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> time.time()</span>
<span id="cb12-29">    results <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [sync_process_prompt(client, prompt) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> prompt <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> prompts]</span>
<span id="cb12-30">    end_time <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> time.time()</span>
<span id="cb12-31">    sync_time <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> end_time <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> start_time</span>
<span id="cb12-32">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Sync processing time: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>sync_time<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.2f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> seconds"</span>)</span>
<span id="cb12-33">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> sync_time</span>
<span id="cb12-34"></span>
<span id="cb12-35">sync_time <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sync_main()</span>
<span id="cb12-36">async_time <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> async_main()</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Sync processing time: 9.15 seconds
Async processing time: 3.99 seconds</code></pre>
</div>
</div>
<div id="4bf27e57" class="cell" data-execution_count="12">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb14-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Compare execution times</span></span>
<span id="cb14-2"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">Synchronous execution time: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>sync_time<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.2f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> seconds"</span>)</span>
<span id="cb14-3"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Asynchronous execution time: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>async_time<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.2f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> seconds"</span>)</span>
<span id="cb14-4"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Time saved with async: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>sync_time <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> async_time<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.2f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> seconds"</span>)</span>
<span id="cb14-5"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Speedup factor: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>sync_time <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> async_time<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.2f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">x"</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>
Synchronous execution time: 9.15 seconds
Asynchronous execution time: 3.99 seconds
Time saved with async: 5.16 seconds
Speedup factor: 2.29x</code></pre>
</div>
</div>
<p>In the code above, async is only as slow as the slowest single task. calling <code>await asyncio.gather(*tasks)</code> waits until all tasks are finished. <strong>However, if you just want to run tasks in the background, you can make the following change:</strong>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode diff code-with-copy"><code class="sourceCode diff"><span id="cb16-1"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">- tasks = [async_process_prompt(client, prompt) for prompt in prompts]</span></span>
<span id="cb16-2"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">- await asyncio.gather(*tasks)</span></span>
<span id="cb16-3"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">+ tasks = [asyncio.create_task(async_process_prompt(client, prompt)) for prompt in prompts]</span></span></code></pre></div></div>
<section id="limiting-async-tasks" class="level3">
<h3 class="anchored" data-anchor-id="limiting-async-tasks">Limiting Async Tasks</h3>
<p>To limit the number of tasks that can be running concurrently, we can use a <code>asyncio.Semaphore</code>. A semaphore allows us to control access to a shared resource, in this case, the number of concurrent tasks. <sup>1</sup> Here’s how it works:</p>
<div id="3c09596d" class="cell" data-execution_count="14">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb17-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> asyncio</span>
<span id="cb17-2"></span>
<span id="cb17-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Create a semaphore with the maximum number of concurrent tasks</span></span>
<span id="cb17-4">max_concurrent_tasks <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span></span>
<span id="cb17-5">semaphore <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> asyncio.Semaphore(max_concurrent_tasks)</span>
<span id="cb17-6"></span>
<span id="cb17-7"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">async</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> limited_task(task_id):</span>
<span id="cb17-8">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">async</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">with</span> semaphore:</span>
<span id="cb17-9">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Starting task </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>task_id<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb17-10">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> asyncio.sleep(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Simulate some work</span></span>
<span id="cb17-11">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Finished task </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>task_id<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb17-12"></span>
<span id="cb17-13"></span>
<span id="cb17-14">tasks <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [limited_task(i) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> i <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>)]</span>
<span id="cb17-15">_ <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> asyncio.gather(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>tasks)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Starting task 0
Starting task 1
Starting task 2
Starting task 3
Starting task 4
Finished task 0
Finished task 1
Finished task 2
Finished task 3
Finished task 4</code></pre>
</div>
</div>
</section>
</section>
<section id="fasthtml-app-with-async" class="level2">
<h2 class="anchored" data-anchor-id="fasthtml-app-with-async">FastHTML App With Async</h2>
<p>Here’s a minimal FastHTML app that incorporates async. You have to run this in a notebook to try it!</p>
<div class="callout callout-style-default callout-tip callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Tip
</div>
</div>
<div class="callout-body-container callout-body">
<p>You can run FastHTML webapps in a Jupyter notebook! This is nice for learning, interactive development, and writing documentation (like we are doing here)! See <a href="https://docs.fastht.ml/tutorials/jupyter_and_fasthtml.html">these docs</a> for more info.</p>
</div>
</div>
<div id="4fbd4395" class="cell" data-execution_count="15">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb19" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb19-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> fasthtml.common <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span></span>
<span id="cb19-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> fasthtml.jupyter <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span></span>
<span id="cb19-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> fastcore.utils <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span></span>
<span id="cb19-4"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> asyncio</span></code></pre></div></div>
</div>
<section id="define-the-server" class="level3">
<h3 class="anchored" data-anchor-id="define-the-server">Define the server</h3>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>The “I’m done” messages will be printed after this cell, because all of the console output is printed where the server is defined in a Jupyter notebook.</p>
</div>
</div>
<div id="d47e2b0a" class="cell" data-execution_count="14">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb20" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb20-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#The "I'm done" messages will be printed after this cell</span></span>
<span id="cb20-2"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> IN_JUPYTER:</span>
<span id="cb20-3">    <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> fasthtml.jupyter <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> JupyUvi, jupy_app, HTMX</span>
<span id="cb20-4">    app, rt <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> jupy_app()</span>
<span id="cb20-5">    server <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> JupyUvi(app) </span>
<span id="cb20-6"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb20-7">    app,rt <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> fast_app()</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>I'm done
I'm done</code></pre>
</div>
</div>
<div id="e32cc679" class="cell" data-execution_count="15">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb22" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb22-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">async</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> long_running_task():</span>
<span id="cb22-2">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> asyncio.sleep(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>)  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Simulate a long-running task</span></span>
<span id="cb22-3">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"I'm done"</span>)</span>
<span id="cb22-4"></span>
<span id="cb22-5"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">@rt</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"/"</span>)</span>
<span id="cb22-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> get():</span>
<span id="cb22-7">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> P(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Async Task Demo"</span>,</span>
<span id="cb22-8">        Div(</span>
<span id="cb22-9">            Button(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Start Task"</span>, hx_post<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"/start-task"</span>, hx_swap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"outerHTML"</span>),</span>
<span id="cb22-10">            <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">id</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"task-button"</span></span>
<span id="cb22-11">        )</span>
<span id="cb22-12">    )</span>
<span id="cb22-13"></span>
<span id="cb22-14"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">@rt</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"/start-task"</span>)</span>
<span id="cb22-15"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">async</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> post():</span>
<span id="cb22-16">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># These will run in the background since we aren't calling await.</span></span>
<span id="cb22-17">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># There are multiple tasks, and asyncio.gather is one way of kicking them off</span></span>
<span id="cb22-18">    asyncio.gather(long_running_task(), long_running_task())</span>
<span id="cb22-19">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> Div(</span>
<span id="cb22-20">        P(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Task started! Check your console in 5 seconds."</span>),</span>
<span id="cb22-21">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">id</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"task-button"</span></span>
<span id="cb22-22">    )</span></code></pre></div></div>
</div>
<div id="8d1fe8a0" class="cell" data-execution_count="17">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb23" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb23-1">HTMX()</span></code></pre></div></div>
</div>
<p><img src="https://glittering-puffpuff-87102e.netlify.app/notes/fasthtml/ex_1.png" class="img-fluid"></p>
<div id="f365184b" class="cell" data-execution_count="18">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb24" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb24-1">server.stop()</span></code></pre></div></div>
</div>
</section>
</section>
<section id="async-openai" class="level2">
<h2 class="anchored" data-anchor-id="async-openai">Async OpenAI</h2>
<p>Let’s show a more realistic example by using OpenAI instead of the sleep. We’ll use the OpenAI API to generate a response, and then print it when it’s done. Here’s the updated code:</p>
<div id="ad60f9f7" class="cell" data-execution_count="16">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb25" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb25-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> fasthtml.common <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span></span>
<span id="cb25-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> fasthtml.jupyter <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span></span>
<span id="cb25-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> asyncio</span>
<span id="cb25-4"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> openai <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> AsyncOpenAI</span></code></pre></div></div>
</div>
<div id="b2e6454d" class="cell" data-execution_count="17">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb26" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb26-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">## The console output (from the background task) will be printed after this cell</span></span>
<span id="cb26-2"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> IN_JUPYTER:</span>
<span id="cb26-3">    <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> fasthtml.jupyter <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> JupyUvi, jupy_app, HTMX</span>
<span id="cb26-4">    app, rt <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> jupy_app()</span>
<span id="cb26-5">    server <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> JupyUvi(app) </span>
<span id="cb26-6"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb26-7">    app,rt <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> fast_app()</span>
<span id="cb26-8"></span>
<span id="cb26-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Initialize the AsyncOpenAI client</span></span>
<span id="cb26-10">client <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> AsyncOpenAI()</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>OpenAI response: Why don't skeletons fight each other? They don't have the guts.</code></pre>
</div>
</div>
<div id="99c1eb2e" class="cell" data-execution_count="18">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb28" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb28-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">async</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> openai_task():</span>
<span id="cb28-2">    response <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> client.chat.completions.create(</span>
<span id="cb28-3">        model<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gpt-4o"</span>,</span>
<span id="cb28-4">        messages<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[{<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"role"</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"user"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"content"</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Tell me a short joke"</span>}]</span>
<span id="cb28-5">    )</span>
<span id="cb28-6">    joke <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> response.choices[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].message.content</span>
<span id="cb28-7">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"OpenAI response: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>joke<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb28-8"></span>
<span id="cb28-9"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">@rt</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"/"</span>)</span>
<span id="cb28-10"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> get():</span>
<span id="cb28-11">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> P(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Async OpenAI Demo"</span>,</span>
<span id="cb28-12">        Div(</span>
<span id="cb28-13">            Button(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Get a Joke"</span>, hx_post<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"/get-joke"</span>, hx_swap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"outerHTML"</span>),</span>
<span id="cb28-14">            <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">id</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"joke-button"</span></span>
<span id="cb28-15">        )</span>
<span id="cb28-16">    )</span>
<span id="cb28-17"></span>
<span id="cb28-18"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">@rt</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"/get-joke"</span>)</span>
<span id="cb28-19"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">async</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> post():</span>
<span id="cb28-20">    asyncio.create_task(openai_task())</span>
<span id="cb28-21">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> Div(</span>
<span id="cb28-22">        P(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Joke request sent! Check your console in a minute."</span>),</span>
<span id="cb28-23">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">id</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"joke-button"</span></span>
<span id="cb28-24">    )</span></code></pre></div></div>
</div>
<div id="8972e2c1" class="cell" data-execution_count="22">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb29" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb29-1">HTMX()</span></code></pre></div></div>
</div>
<p><img src="https://glittering-puffpuff-87102e.netlify.app/notes/fasthtml/ex_2.png" class="img-fluid"></p>
<div id="88d8a9e1" class="cell" data-execution_count="23">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb30" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb30-1">server.stop()</span></code></pre></div></div>
</div>
</section>
<section id="threads-processes" class="level2">
<h2 class="anchored" data-anchor-id="threads-processes">Threads &amp; Processes</h2>
<p>Note: Async tasks can be started in the background with threads or processes. You can also spawn threads or processes from other threads or processes as well.</p>
<p>Let’s see the basic functionality of threads and processes in python.</p>
<div id="996f9dba" class="cell" data-execution_count="24">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb31" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb31-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> time</span>
<span id="cb31-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> fastcore.parallel <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> parallel</span>
<span id="cb31-3"></span>
<span id="cb31-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> f(x): time.sleep(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(x)</span>
<span id="cb31-5">a <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>,<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>,<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>,<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>,<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>,<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>,<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>,<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>]</span>
<span id="cb31-6"></span>
<span id="cb31-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># parallel starts a new thread when threadpool=True.</span></span>
<span id="cb31-8"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> g(): parallel(f, a, threadpool<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>)</span></code></pre></div></div>
</div>
<section id="run-with-a-process" class="level3">
<h3 class="anchored" data-anchor-id="run-with-a-process">Run with a process</h3>
<p>We are starting a thread inside a new process so it runs in the background. Remember, <code>parallel</code> will execute <code>f</code> in a new thread.</p>
<p>It will print kinda wierd because of the threading and things completing at the same time.</p>
<div id="95e9c8b5" class="cell" data-execution_count="25">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb32" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb32-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> multiprocess <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> Process</span>
<span id="cb32-2">p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Process(target<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>g)</span>
<span id="cb32-3">p.start()</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>154832
76





</code></pre>
</div>
</div>
</section>
<section id="run-with-a-thread" class="level3">
<h3 class="anchored" data-anchor-id="run-with-a-thread">Run with a thread</h3>
<p>Instaed of starting a thread in the background with a process, we can also start it with another thread.</p>
<div id="cdc9e371" class="cell" data-execution_count="26">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb34" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb34-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> threading <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> Thread</span>
<span id="cb34-2">t <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Thread(target<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>g)</span>
<span id="cb34-3">t.start()</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>51
8
7
6

4
2
3</code></pre>
</div>
</div>
</section>
<section id="how-to-choose-threads-vs.-processes" class="level3">
<h3 class="anchored" data-anchor-id="how-to-choose-threads-vs.-processes">How to choose Threads vs.&nbsp;Processes</h3>
<p>See <a href="https://python.hamel.dev/concurrency/">my blog post</a>.</p>
<p>If your tasks involves network calls, consider using threads. For CPU intensive tasks, use processes.</p>
</section>
</section>
<section id="fastcore" class="level2">
<h2 class="anchored" data-anchor-id="fastcore">Fastcore</h2>
<p>Fastcore has goodies for threads and processes</p>
<section id="threaded-decorator" class="level3">
<h3 class="anchored" data-anchor-id="threaded-decorator"><code>@threaded</code> decorator</h3>
<p>This will make functions run in the background in a new thread or process.</p>
<div id="34c071a7" class="cell" data-execution_count="27">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb36" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb36-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> fastcore.parallel <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> threaded</span>
<span id="cb36-2"></span>
<span id="cb36-3"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">@threaded</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># casuses g to be threaded</span></span>
<span id="cb36-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> g(): parallel(f, a, threadpool<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>)</span>
<span id="cb36-5">    </span>
<span id="cb36-6">    </span>
<span id="cb36-7"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">@threaded</span>(process<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>) <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># casuses h to be run in a process</span></span>
<span id="cb36-8"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> h(): parallel(f, a, threadpool<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>)</span></code></pre></div></div>
</div>
<div id="5cec8579" class="cell" data-execution_count="28">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb37" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb37-1">g()</span></code></pre></div></div>
<div class="cell-output cell-output-display" data-execution_count="28">
<pre><code>&lt;Thread(Thread-9 (g), started 6248116224)&gt;</code></pre>
</div>
<div class="cell-output cell-output-stdout">
<pre><code>12
4
6
3
5
7
8
</code></pre>
</div>
</div>
<div id="865e155f" class="cell" data-execution_count="29">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb40" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb40-1">h()</span></code></pre></div></div>
<div class="cell-output cell-output-display" data-execution_count="29">
<pre><code>&lt;Process name='Process-3' pid=40899 parent=40147 started&gt;</code></pre>
</div>
<div class="cell-output cell-output-stdout">
<pre><code>42538761






</code></pre>
</div>
</div>
</section>
<section id="startthread" class="level3">
<h3 class="anchored" data-anchor-id="startthread"><code>startthread</code></h3>
<p>We can also start a thread by calling the <code>startthread</code> function.</p>
<div id="f6ec36a2" class="cell" data-execution_count="30">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb43" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb43-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> fastcore.parallel <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> startthread</span>
<span id="cb43-2"></span>
<span id="cb43-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> g(): parallel(f, a, threadpool<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>)</span>
<span id="cb43-4">startthread(g)</span>
<span id="cb43-5"></span>
<span id="cb43-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># this will run right away in the main process, since the other code is running in the background</span></span>
<span id="cb43-7"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'hello'</span>) </span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>hello
12
3
4
5
6
7
8
</code></pre>
</div>
</div>


</section>
</section>


<div id="quarto-appendix" class="default"><section id="footnotes" class="footnotes footnotes-end-of-document"><h2 class="anchored quarto-appendix-heading">Footnotes</h2>

<ol>
<li id="fn1"><p>Thanks to Krisztian for the <a href="https://x.com/kk1694/status/1844336706058846496">suggestion</a>.↩︎</p></li>
</ol>
</section></div> ]]></description>
  <guid>https://glittering-puffpuff-87102e.netlify.app/notes/fasthtml/concurrency.html</guid>
  <pubDate>Fri, 11 Oct 2024 07:00:00 GMT</pubDate>
  <media:content url="https://glittering-puffpuff-87102e.netlify.app/notes/fasthtml/edison_async.png" medium="image" type="image/png" height="81" width="144"/>
</item>
</channel>
</rss>
