<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>FastAPI on NoRaincheck</title><link>https://noraincheck.github.io/tags/fastapi/</link><description>Recent content in FastAPI on NoRaincheck</description><generator>Hugo</generator><language>en-US</language><copyright>NoRaincheck</copyright><lastBuildDate>Wed, 15 Jul 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://noraincheck.github.io/tags/fastapi/index.xml" rel="self" type="application/rss+xml"/><item><title>Beating FastAPI</title><link>https://noraincheck.github.io/posts/beating-fastapi/</link><pubDate>Wed, 15 Jul 2026 00:00:00 +0000</pubDate><guid>https://noraincheck.github.io/posts/beating-fastapi/</guid><description>&lt;p&gt;One thing which Go does a lot better than Python is single binary deployments. As an &lt;a href="https://github.com/NoRaincheck/gofre"&gt;experiment&lt;/a&gt; I thought, why not have a way to package up Go as part of a Python package, similar to &lt;a href="https://www.maturin.rs/"&gt;maturin&lt;/a&gt; - and also have a way to spin up a Python webserver that is packaged as a Go binary.&lt;/p&gt;&#10;&lt;p&gt;The results were definitely interesting:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Go binary had 9x more throughput than stdlib Python&amp;rsquo;s http library, and ~5x more throughput than FastAPI&lt;/li&gt;&#10;&lt;li&gt;Idle memroy usage was `3x higher for FastAPI, and the peak memory usage was ~2x higher than Go binary&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;Of course the pocket python restriction may be too much for more complex applications.&lt;/p&gt;</description></item><item><title>A look at Campfire for self-hosted Slack alternative</title><link>https://noraincheck.github.io/posts/a-look-at-campfire-for-self-hosted-slack-alternative/</link><pubDate>Sun, 01 Mar 2026 00:00:00 +0000</pubDate><guid>https://noraincheck.github.io/posts/a-look-at-campfire-for-self-hosted-slack-alternative/</guid><description>&lt;h2 id="a-look-at-campfire-for-self-hosted-slack-alternative"&gt;A look at Campfire for self-hosted Slack alternative&lt;/h2&gt;&#10;&lt;p&gt;&lt;em&gt;March 2026&lt;/em&gt;&lt;/p&gt;&#10;&lt;p&gt;Campfire is not really a commonly suggested alternative to Slack/Discord.&#10;Afterall its missing various features including voice chat, threads or other&#10;features. It makes up for it by being incredibly easy to self-host and easy to&#10;write a bot that can interact in such an interface.&lt;/p&gt;&#10;&lt;p&gt;Campfire can be hosted from a single Dockerfile using sqlite as its database.&#10;For majority of low-numbered user-count situations this is more than sufficient.&lt;/p&gt;</description></item><item><title>Python MCP - Mounting to an Existing FastAPI ASGI Server</title><link>https://noraincheck.github.io/posts/python-mcp-mounting-to-an-existing-fastapi-asgi-server/</link><pubDate>Tue, 01 Apr 2025 00:00:00 +0000</pubDate><guid>https://noraincheck.github.io/posts/python-mcp-mounting-to-an-existing-fastapi-asgi-server/</guid><description>&lt;h2 id="python-mcp---mounting-to-an-existing-fastapi-asgi-server"&gt;Python MCP - Mounting to an Existing FastAPI ASGI Server&lt;/h2&gt;&#10;&lt;p&gt;&lt;em&gt;April 2025&lt;/em&gt;&lt;/p&gt;&#10;&lt;p&gt;You can mount the SSE server to an existing FastAPI ASGI server dynamically. The&#10;way I&amp;rsquo;ve made it work is as follows:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;sse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SseServerTransport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;...&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;routes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sse&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;handle_post_message&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@app.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/sse&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;handle_mcp_connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;sse&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;receive&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;read_stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;write_stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;):&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;mcp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_mcp_server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;read_stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;write_stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;mcp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_mcp_server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_initialization_options&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This seemed to work pretty well, along with having Redis as an intermediary&#10;broker for dealing with state.&lt;/p&gt;</description></item><item><title>Dependency Injection via SQLModels isn't worth it</title><link>https://noraincheck.github.io/posts/dependency-injection-via-sqlmodels-isn-t-worth-it/</link><pubDate>Sat, 01 Feb 2025 00:00:00 +0000</pubDate><guid>https://noraincheck.github.io/posts/dependency-injection-via-sqlmodels-isn-t-worth-it/</guid><description>&lt;h2 id="dependency-injection-via-sqlmodels-isnt-worth-it"&gt;Dependency Injection via SQLModels isn&amp;rsquo;t worth it&lt;/h2&gt;&#10;&lt;p&gt;&lt;em&gt;February 2025&lt;/em&gt;&lt;/p&gt;&#10;&lt;p&gt;It&amp;rsquo;s been something I&amp;rsquo;ve been mulling over for a while now. I&amp;rsquo;m not convinced&#10;using &lt;code&gt;Session&lt;/code&gt; with&#10;&lt;a href="https://sqlmodel.tiangolo.com/tutorial/fastapi/session-with-dependency/?h=depend"&gt;Dependency Injection is worth it&lt;/a&gt;.&#10;The abstraction is nice, visually, but the lack of context makes things really&#10;hard to reason with, especially if you&amp;rsquo;re doing something beyond a simple&#10;getter/setter. This happens if you&amp;rsquo;re building an application that performs a&#10;flow or some business logic rather than a pure CRUD, then you may need to do&#10;multiple commits in a single query which may &lt;em&gt;not&lt;/em&gt; need to all be rolled back.&#10;This of course breaks some kind of assumption to do with &amp;ldquo;a single unit of&#10;work&amp;rdquo;.&lt;/p&gt;</description></item><item><title>Python &amp; TypeScript - in Review (2024)</title><link>https://noraincheck.github.io/posts/python-typescript-in-review-2024/</link><pubDate>Sun, 01 Dec 2024 00:00:00 +0000</pubDate><guid>https://noraincheck.github.io/posts/python-typescript-in-review-2024/</guid><description>&lt;h2 id="python--typescript---in-review-2024"&gt;Python &amp;amp; TypeScript - in Review (2024)&lt;/h2&gt;&#10;&lt;p&gt;&lt;em&gt;December 2024&lt;/em&gt;&lt;/p&gt;&#10;&lt;p&gt;One thing that I like to stress is the importance of &lt;em&gt;tooling&lt;/em&gt; and&#10;&lt;a href="https://en.wikipedia.org/wiki/Convention_over_configuration"&gt;relying on defaults&lt;/a&gt;.&#10;By being able to speak consistently within ones own projects or using commonly&#10;seen patterns reduces the mental overhead. These could be folder structures or&#10;idioms, especially things which permeate across different programming languages&#10;or frameworks.&lt;/p&gt;&#10;&lt;p&gt;Here are some of my thoughts on Python and TypeScript; coming from someone who&#10;is predominantly a Python developer and does minimal front-end work.&lt;/p&gt;</description></item></channel></rss>