<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
      <title>Karn Wong - Karn Wong&#x27;s Blog</title>
      <link>https://karnwong.me/posts/</link>
      <description>Homepage and blog by Karn Wong</description>
      <generator>Zola</generator>
      <language>en</language>
      <atom:link href="https://karnwong.me/posts/rss.xml" rel="self" type="application/rss+xml"/>
      <lastBuildDate>Fri, 10 Apr 2026 00:00:00 +0000</lastBuildDate>
      <item>
          <title>LLM tracing with MLflow AI Gateway</title>
          <pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2026/04/llm-tracing-with-mlflow-ai-gateway/</link>
          <guid>https://karnwong.me/posts/2026/04/llm-tracing-with-mlflow-ai-gateway/</guid>
          <description xml:base="https://karnwong.me/posts/2026/04/llm-tracing-with-mlflow-ai-gateway/">&lt;h2 id=&quot;tracing-wait-what&quot;&gt;Tracing. Wait, what?&lt;a class=&quot;zola-anchor&quot; href=&quot;#tracing-wait-what&quot; aria-label=&quot;Anchor link for: tracing-wait-what&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;It&#x27;s too easy to develop agentic apps, or use coding agents to help you with stuff. Claude Code, Gemini CLI, Codex, OpenCode, Copilot CLI and many more that I forgot to mention are popular for a reason. These coding agents would report how much tokens are consumed so you can plan your coding sessions as to not run out of usage credits.&lt;&#x2F;p&gt;
&lt;p&gt;But do you ever wonder what&#x27;s going on between the coding agent and LLM? Or when a user submit a query to your agent, which tools it used, and what&#x27;s exactly being sent to the LLM? Agentic frameworks can and sometimes rewrite your original prompt, not to mention system prompts baked into the frameworks that you don&#x27;t see unless you dive into the source code. It&#x27;s not a bad thing, but if you have to debug why a prompt doesn&#x27;t work as well as you thought it would, finding out what&#x27;s exactly being sent over to LLM is a very helpful debugging crutch.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;usage&quot;&gt;Usage&lt;a class=&quot;zola-anchor&quot; href=&quot;#usage&quot; aria-label=&quot;Anchor link for: usage&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Good news is you can &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mlflow.org&#x2F;docs&#x2F;latest&#x2F;genai&#x2F;tracing&#x2F;quickstart&#x2F;&quot;&gt;instrument your agentic app with MLflow&lt;&#x2F;a&gt; so it&#x27;ll log LLM calls as traces. But this means you&#x27;ll have to update your code. Might not be very economical if you maintain a lot of repos.&lt;&#x2F;p&gt;
&lt;p&gt;But with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mlflow.org&#x2F;ai-gateway&quot;&gt;Mlflow AI Gateway&lt;&#x2F;a&gt;, you can call LLM through a specified gateway, and traces will be logged automatically (traces can also be disabled, if you really want to). To &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mlflow.org&#x2F;docs&#x2F;latest&#x2F;genai&#x2F;governance&#x2F;ai-gateway&#x2F;quickstart&#x2F;&quot;&gt;give it a go (without deploying MLflow server)&lt;&#x2F;a&gt;, you can use a local MLflow server and set Ollama as provider (via LiteLLM). Currently MLflow AI Gateway does not support rate limiting, but it is planned.&lt;&#x2F;p&gt;
&lt;p&gt;MLflow AI Gateway also supports passthrough calling, which means if it&#x27;s a Gemini gateway, you can use Gemini SDK to call it. It does not work if it&#x27;s a Gemini gateway but you are calling it via Anthropic SDK.&lt;&#x2F;p&gt;
&lt;p&gt;But for teams that already adopt LiteLLM or need rate limiting support, you can use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.litellm.ai&#x2F;docs&#x2F;observability&#x2F;mlflow&quot;&gt;MLflow as observability backend for LiteLLM&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This also means that for CLI coding agents, you can set it to call an MLflow AI Gateway endpoint and you can peek inside the coding agents.&lt;&#x2F;p&gt;
&lt;p&gt;For example, with Copilot CLI, you need to set following environment variables:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;COPILOT_PROVIDER_BASE_URL&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;COPILOT_PROVIDER_TYPE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;COPILOT_PROVIDER_API_KEY&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;COPILOT_MODEL&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then launch Copilot CLI. I asked it to read a project and explain what it does. This is what shows up under MLflow traces:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2026&#x2F;04&#x2F;llm-tracing-with-mlflow-ai-gateway&#x2F;images&#x2F;mlflow-traces.webp&quot; alt=&quot;MLflow traces&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2026&#x2F;04&#x2F;llm-tracing-with-mlflow-ai-gateway&#x2F;images&#x2F;mlflow-traces-details.webp&quot; alt=&quot;MLflow traces details&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-if-you-need-otel&quot;&gt;What if you need OTel&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-if-you-need-otel&quot; aria-label=&quot;Anchor link for: what-if-you-need-otel&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;See &lt;a href=&quot;&#x2F;posts&#x2F;2026&#x2F;03&#x2F;observability-with-ebpf-and-otel&#x2F;&quot;&gt;Observability with eBPF and OTel&lt;&#x2F;a&gt;. It works with agentic frameworks and LLM provider SDKs, but YMMV.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Tracing is a scaling problem. At a small scale, you can debug by hand. But at a large scale, sifting through logs to find relevant logs for a single user&#x27;s request is not for the faint of heart. And there will be concurrent users. But if you are one of the braves and want to practice logs-diving skills, by all means.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Garmin development setup on Linux</title>
          <pubDate>Mon, 06 Apr 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2026/04/garmin-development-setup-on-linux/</link>
          <guid>https://karnwong.me/posts/2026/04/garmin-development-setup-on-linux/</guid>
          <description xml:base="https://karnwong.me/posts/2026/04/garmin-development-setup-on-linux/">&lt;h2 id=&quot;in-the-beginning&quot;&gt;In the beginning&lt;a class=&quot;zola-anchor&quot; href=&quot;#in-the-beginning&quot; aria-label=&quot;Anchor link for: in-the-beginning&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;I was complaining about Apple Watch&#x27;s battery life (it requires a daily charging session), so a friend recommended Garmin to me. And I&#x27;m hooked. My Garmin model lasts two weeks on a single charge, which is great because a nightly charging regimen can use one less device.&lt;&#x2F;p&gt;
&lt;p&gt;Trawling the web, I hear people mention on Bluesky that you can write your own Garmin app (which makes me hesitate less when hitting the purchase button, oops). Suffice to say I didn&#x27;t wait long to get started with Garmin development.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;garmin-development-setup&quot;&gt;Garmin development setup&lt;a class=&quot;zola-anchor&quot; href=&quot;#garmin-development-setup&quot; aria-label=&quot;Anchor link for: garmin-development-setup&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Garmin has its own SDK, so you&#x27;ll have to install it. On Mac OS, you can go through the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.garmin.com&#x2F;connect-iq&#x2F;sdk&#x2F;&quot;&gt;installer&lt;&#x2F;a&gt;. Install java on your machine and &lt;code&gt;Monkey C&lt;&#x2F;code&gt; extension on vscode, and you are ready to start.&lt;&#x2F;p&gt;
&lt;p&gt;On Linux, the SDK installer depends on outdated system libraries. If you&#x27;re on Ubuntu 22, great. Otherwise it&#x27;ll complain about missing libraries. Luckily there&#x27;s an &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;pcolby&#x2F;connectiq-sdk-manager&quot;&gt;AppImage version&lt;&#x2F;a&gt;. Follow the install script and you should be able to install Garmin SDK on your machine.&lt;&#x2F;p&gt;
&lt;p&gt;But since sometimes I use other IDEs, this is my build script:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;java&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;Xms1g&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;Dfile.encoding=UTF-8&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;Dapple.awt.UIElement=true&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;jar&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;$(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;find&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ~&#x2F;.Garmin&#x2F;ConnectIQ&#x2F;Sdks&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;monkeybrains.jar&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; grep&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; bin&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; tail&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;o&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; bin&#x2F;garminanalogwatchface.prg&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;$(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;pwd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;monkey.jungle&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;y&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ~&#x2F;.Garmin&#x2F;keys&#x2F;developer_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; instincte45mm_sim&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;w&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Notice the &lt;code&gt;$(find ~&#x2F;.Garmin&#x2F;ConnectIQ&#x2F;Sdks&#x2F; -name &quot;monkeybrains.jar&quot; | grep bin | tail -1)&lt;&#x2F;code&gt;, this is so it&#x27;ll use the latest jar when building an app, otherwise the jar PATH has to be hard-coded.&lt;&#x2F;p&gt;
&lt;p&gt;The normal development process would be editing the code, build it, then test it on your device. The only way to push your app to Garmin during development (without going through Connect IQ store) is to manually copy it onto your device. Yes, this is a very time-consuming process.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s a simulator, for which if you&#x27;re on Mac OS, there&#x27;s a menu for it in vscode, but no such luck on Linux.&lt;&#x2F;p&gt;
&lt;p&gt;The simulator binary is located at &lt;code&gt;~&#x2F;.Garmin&#x2F;ConnectIQ&#x2F;Sdks&#x2F;connectiq-sdk-xxxxx&#x2F;bin&#x2F;simulator&lt;&#x2F;code&gt;, but you won&#x27;t be able to run it because it depends on outdated system libraries. But the install script from earlier also provides a simulator binary in AppImage format.&lt;&#x2F;p&gt;
&lt;p&gt;You&#x27;ll have to start the simulator, then build the app, and &quot;push&quot; your app to the simulator:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-entity z-name z-function&quot;&gt;$(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;find&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ~&#x2F;.Garmin&#x2F;ConnectIQ&#x2F;Sdks&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;monkeydo&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; grep&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; bin&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; tail&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-entity z-name z-function&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; bin&#x2F;garminanalogwatchface.prg&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; instincte45mm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But to make my life easier, I setup &lt;a href=&quot;&#x2F;posts&#x2F;2026&#x2F;03&#x2F;development-environment-setup-with-flox-and-direnv&#x2F;&quot;&gt;flox&lt;&#x2F;a&gt; to run a simulator process in the background:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;toml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-section&quot;&gt;services&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;simulator&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;command&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;$(find ~&#x2F;.Garmin&#x2F;ConnectIQ&#x2F;AppImages&#x2F; -name &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;*Simulator*&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; | tail -1)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;what-i-ve-built-so-far&quot;&gt;What I&#x27;ve built so far&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-i-ve-built-so-far&quot; aria-label=&quot;Anchor link for: what-i-ve-built-so-far&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;garmin-todotxt&quot;&gt;garmin-todotxt&lt;a class=&quot;zola-anchor&quot; href=&quot;#garmin-todotxt&quot; aria-label=&quot;Anchor link for: garmin-todotxt&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kahnwong&#x2F;garmin-todotxt&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;kahnwong&#x2F;garmin-todotxt&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I use &lt;code&gt;todotxt&lt;&#x2F;code&gt; and it would be nice to read todos on my watch.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2026&#x2F;04&#x2F;garmin-development-setup-on-linux&#x2F;images&#x2F;garmin-todotxt.webp&quot; alt=&quot;garmin-todotxt&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;garmin-weather&quot;&gt;garmin-weather&lt;a class=&quot;zola-anchor&quot; href=&quot;#garmin-weather&quot; aria-label=&quot;Anchor link for: garmin-weather&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kahnwong&#x2F;garmin-weather&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;kahnwong&#x2F;garmin-weather&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Garmin&#x27;s weather data can be inaccurate, depending on the weather station it uses to obtain the data. Also to get the info I want, it involves multiple clicks. Yes, I&#x27;m very lazy.&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s current weather and rain probability in the next 1 and 3 hours.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2026&#x2F;04&#x2F;garmin-development-setup-on-linux&#x2F;images&#x2F;garmin-weather-app.webp&quot; alt=&quot;garmin-weather-app&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2026&#x2F;04&#x2F;garmin-development-setup-on-linux&#x2F;images&#x2F;garmin-weather-glance.webp&quot; alt=&quot;garmin-weather-glance&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;garmin-qrcode&quot;&gt;garmin-qrcode&lt;a class=&quot;zola-anchor&quot; href=&quot;#garmin-qrcode&quot; aria-label=&quot;Anchor link for: garmin-qrcode&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kahnwong&#x2F;garmin-qrcode&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;kahnwong&#x2F;garmin-qrcode&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I got tired of constantly tapping my phone to stay awake when I attend events and need to scan the qr code for entry.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2026&#x2F;04&#x2F;garmin-development-setup-on-linux&#x2F;images&#x2F;garmin-qrcode.webp&quot; alt=&quot;garmin-qrcode&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;If you think I&#x27;m very lazy, you are correct. Guilty as charged.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Development environment setup with flox and direnv</title>
          <pubDate>Tue, 31 Mar 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2026/03/development-environment-setup-with-flox-and-direnv/</link>
          <guid>https://karnwong.me/posts/2026/03/development-environment-setup-with-flox-and-direnv/</guid>
          <description xml:base="https://karnwong.me/posts/2026/03/development-environment-setup-with-flox-and-direnv/">&lt;h2 id=&quot;the-status-quo&quot;&gt;The status quo&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-status-quo&quot; aria-label=&quot;Anchor link for: the-status-quo&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;When you are working on a project, one of the core requirements would be to choose a programming language to use. If you work alone, as long as everything is reproducible on your development machine, things would be more or less all right. If you need to use other packages, you can install them as you go along, which could be a &lt;code&gt;brew install $package&lt;&#x2F;code&gt;, &lt;code&gt;curl https:&#x2F;&#x2F;example.com&#x2F;get | sh&lt;&#x2F;code&gt;, &lt;code&gt;apt install $package&lt;&#x2F;code&gt; or anything in between. But so far your project is humming along nicely, nothing to worry about.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;it-has-to-work-on-other-machines&quot;&gt;It has to work on other machines&lt;a class=&quot;zola-anchor&quot; href=&quot;#it-has-to-work-on-other-machines&quot; aria-label=&quot;Anchor link for: it-has-to-work-on-other-machines&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;The fun starts when you are working in a team, or have to collaborate with other teams on the same project. Let&#x27;s say the project uses Node.js, you&#x27;ll have to make sure that everyone working on this project uses the same node version. But this means each person has to do this on their end, there&#x27;s no central mechanism to ensure that the node version used in this project is standardized. You can use &lt;code&gt;.nvmrc&lt;&#x2F;code&gt; to specify node version, but you&#x27;ll have to make sure that they have &lt;code&gt;nvm&lt;&#x2F;code&gt; on their machine in the first place.&lt;&#x2F;p&gt;
&lt;p&gt;As for other project dependencies that&#x27;s not the runtime (node, python, go, rust, etc.) itself, when you install them, by default, latest version will be installed. What if when a feature is created, it was developed on a machine where &lt;code&gt;$package&lt;&#x2F;code&gt; had been installed last year. And when a new developer works on this project and is setting up their dev environment, they install this &lt;code&gt;$package&lt;&#x2F;code&gt;, but the version installed this time is a new version, with breaking changes. At this point, you&#x27;ll have to hope that you can still contact the original developer so you can obtain the &lt;code&gt;$package&lt;&#x2F;code&gt; version used in this project. If this is not possible, you&#x27;ll have to test against each version of this &lt;code&gt;$package&lt;&#x2F;code&gt; to find the version that works with this project.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;and-you-need-to-initialize-your-workspace&quot;&gt;And you need to initialize your workspace&lt;a class=&quot;zola-anchor&quot; href=&quot;#and-you-need-to-initialize-your-workspace&quot; aria-label=&quot;Anchor link for: and-you-need-to-initialize-your-workspace&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;For simple projects you can run a single command to start a process and that&#x27;s all there is to run a project. But some projects require multiple processes running before you can start working on it.&lt;&#x2F;p&gt;
&lt;p&gt;For example, a backend project with a database, you&#x27;ll need to spin up a database prior to running a backend server.&lt;&#x2F;p&gt;
&lt;p&gt;A frontend project, if it needs to talk to a backend, you&#x27;ll also need to spin up a backend server (and probably a database as well).&lt;&#x2F;p&gt;
&lt;p&gt;Or a terraform project talking to a kubernetes cluster with argocd, you&#x27;ll need to run ssh tunneling to expose kubernetes api server, and kubectl port forwarding to expose argocd.&lt;&#x2F;p&gt;
&lt;p&gt;And these are multiple processes, which means multiple terminal windows, and you need to read the logs for relevant processes your code is talking to.&lt;&#x2F;p&gt;
&lt;p&gt;Environment variables also need to be initialized, and sometimes you&#x27;ll forget to set it before starting your services. If you work on multiple projects and forget to start a new terminal session, your environment variables can get all jumbled from different projects.&lt;&#x2F;p&gt;
&lt;p&gt;(You also need to tear down these processes once you&#x27;ve finished working on a project as well, otherwise you are wasting compute on unused resources).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;flox-and-direnv-can-help-you&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;flox.dev&#x2F;&quot;&gt;Flox&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;direnv.net&#x2F;&quot;&gt;direnv&lt;&#x2F;a&gt; can help you&lt;a class=&quot;zola-anchor&quot; href=&quot;#flox-and-direnv-can-help-you&quot; aria-label=&quot;Anchor link for: flox-and-direnv-can-help-you&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;With &lt;code&gt;flox&lt;&#x2F;code&gt;, you can define packages used in a project. They are pinned by a revision hash, so given the same flox configuration, it will use the same packages, down to the version. You can also define processes attached to a project. Logs are also available, either for a specific process or all processes.&lt;&#x2F;p&gt;
&lt;p&gt;Which means, when you activate a flox shell (&lt;code&gt;flox activate&lt;&#x2F;code&gt;), it will use packages defined in a flox configuration. You can also set processes (&lt;code&gt;flox activate --start-services&lt;&#x2F;code&gt;) to start once the flox shell is activated. This means you don&#x27;t need to open multiple terminal tabs and start upstream processes. If you need to see logs, &lt;code&gt;flox services logs -f $serviceName&lt;&#x2F;code&gt; or &lt;code&gt;flox services logs -f&lt;&#x2F;code&gt; to see logs for all processes. If you need to restart processes, just run &lt;code&gt;flox services restart&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Example flox services config:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;toml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-section&quot;&gt;services&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;backend&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;command&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;air&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;frontend&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;command&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;cd frontend &amp;amp;&amp;amp; yarn install &amp;amp;&amp;amp; yarn dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The best part is when you exit flox shell, it will automatically tear down the processes used in a project.&lt;&#x2F;p&gt;
&lt;p&gt;As for environment variables, &lt;code&gt;direnv&lt;&#x2F;code&gt; will automatically register variables for current directory. Once you leave this directory, environment variables will be unset.&lt;&#x2F;p&gt;
&lt;p&gt;There is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mise.jdx.dev&#x2F;&quot;&gt;mise&lt;&#x2F;a&gt;, which can do what flox and direnv do. But mise&#x27;s approach to running processes in the background isn&#x27;t as smooth as flox&#x27;s. Namely, there&#x27;s no clean mechanism to view process logs, you&#x27;ll have to watch them or pipe them.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;do-i-really-need-flox-and-direnv&quot;&gt;Do I really need flox and direnv&lt;a class=&quot;zola-anchor&quot; href=&quot;#do-i-really-need-flox-and-direnv&quot; aria-label=&quot;Anchor link for: do-i-really-need-flox-and-direnv&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;When you are working on a project and you are perfectly content with:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;initializing environment variables&lt;&#x2F;li&gt;
&lt;li&gt;spin up a database&lt;&#x2F;li&gt;
&lt;li&gt;start backend server&lt;&#x2F;li&gt;
&lt;li&gt;start frontend server&lt;&#x2F;li&gt;
&lt;li&gt;packages whack-a-mole to find out why it works on your machine, but doesn&#x27;t work on your teammate&#x27;s&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;No, you don&#x27;t need flox and direnv.&lt;&#x2F;p&gt;
&lt;p&gt;But that&#x27;s four commands already, and three terminals (or two, if you run a database in the background) need to be left open.&lt;&#x2F;p&gt;
&lt;p&gt;But with flox and direnv, to achieve all this, you only need to run &lt;code&gt;flox activate --start-services&lt;&#x2F;code&gt;. Less time and less cognitive load, what&#x27;s not to love?&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Observability with eBPF and OTel</title>
          <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2026/03/observability-with-ebpf-and-otel/</link>
          <guid>https://karnwong.me/posts/2026/03/observability-with-ebpf-and-otel/</guid>
          <description xml:base="https://karnwong.me/posts/2026/03/observability-with-ebpf-and-otel/">&lt;h2 id=&quot;background&quot;&gt;Background&lt;a class=&quot;zola-anchor&quot; href=&quot;#background&quot; aria-label=&quot;Anchor link for: background&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Imagine maintaining multiple services, either monolith or microservices. Sometimes they communicate with each other, sometimes they don&#x27;t. But do you know how they communicate with each other? You could dive into the source code, but then you have to cross-check it with actual network requests 😶.&lt;&#x2F;p&gt;
&lt;p&gt;Then there are logs and metrics, and without proper grouping it&#x27;s going to be a mess when you are debugging a prod issue and you have to submit multiple queries for different things across all services to get the full picture of the offending requests.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;opentelemetry-otel-is-the-solution&quot;&gt;OpenTelemetry (OTel) is the solution&lt;a class=&quot;zola-anchor&quot; href=&quot;#opentelemetry-otel-is-the-solution&quot; aria-label=&quot;Anchor link for: opentelemetry-otel-is-the-solution&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Essentially it&#x27;s a mechanism in which you can extract traces, logs and metrics from your services into a data sink.&lt;&#x2F;p&gt;
&lt;p&gt;A trace tells what communicates with what. Can involve multiple hops.&lt;&#x2F;p&gt;
&lt;p&gt;Logs are self-explanatory. Metrics are numerical values, something like requests per second or message size.&lt;&#x2F;p&gt;
&lt;p&gt;Logs and metrics can have a trace id attached, which makes it easier for operators to query and filter relevant observability data when debugging issues.&lt;&#x2F;p&gt;
&lt;p&gt;But then someone has to set all this up. They have to dive into the source code, and sprinkle OTel stuff to make the service emits traces, logs and metrics. And this is a lot of work. And it&#x27;s even more fun if you have to track a trace originating from serviceA, which talks to serviceB, and forwarded to serviceC. You&#x27;ll have to make sure that when the OTel data traverses through the call chain, they retain the same trace id.&lt;&#x2F;p&gt;
&lt;p&gt;And if you have a lot of microservices, yup, exactly what you are thinking. You&#x27;ll have to sprinkle OTel code in all of them.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-if-you-don-t-want-to-change-your-code&quot;&gt;What if you don&#x27;t want to change your code&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-if-you-don-t-want-to-change-your-code&quot; aria-label=&quot;Anchor link for: what-if-you-don-t-want-to-change-your-code&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Luckily there&#x27;s eBPF. Basically it allows you to read stuff from the linux kernel space, and there happens to be a lot of data there, all juicy stuff for observability. For example, you can setup &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;grafana.com&#x2F;docs&#x2F;beyla&#x2F;latest&#x2F;&quot;&gt;Grafana Beyla&lt;&#x2F;a&gt; which can automatically extract traces. This is known as auto-instrumentation, where you setup the necessary infrastructure to obtain observability data without changing a single line of code. Observability vendors utilize eBPF to achieve auto-instrumentation, that&#x27;s why their docs only tell you to install an agent on the host OS and it&#x27;s done.&lt;&#x2F;p&gt;
&lt;p&gt;eBPF is linux only, which might be an issue if you are using other OSes for testing observability when you are developing locally. But you can always spin up a small linux vm for this.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;but-there-s-no-reason-to-not-use-otel-and-ebpf-together&quot;&gt;But there&#x27;s no reason to not use OTel and eBPF together&lt;a class=&quot;zola-anchor&quot; href=&quot;#but-there-s-no-reason-to-not-use-otel-and-ebpf-together&quot; aria-label=&quot;Anchor link for: but-there-s-no-reason-to-not-use-otel-and-ebpf-together&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;They are not mutually exclusive. Using one does not exclude you from using the other. Which means you can use eBPF to collect generic info, and when you want to be specific or fine-grained data you instrument your code manually via OTel.&lt;&#x2F;p&gt;
&lt;p&gt;See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kahnwong&#x2F;a2a-go-demo&quot;&gt;a2a-go-demo&lt;&#x2F;a&gt; for example OTel + eBPF implementation.&lt;&#x2F;p&gt;
&lt;p&gt;This is from eBPF, you can see the trace for a single api call.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2026&#x2F;03&#x2F;observability-with-ebpf-and-otel&#x2F;.&#x2F;images&#x2F;traces.webp&quot; alt=&quot;traces&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;And a library in this project already emits OTel, which means I only need to forward it to OTel endpoint.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2026&#x2F;03&#x2F;observability-with-ebpf-and-otel&#x2F;.&#x2F;images&#x2F;traces-llm.webp&quot; alt=&quot;traces-llm&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;These cover a lot of info already, and when you want to zoom in to extract finer-grained data, you can always instrument manually.&lt;&#x2F;p&gt;
&lt;p&gt;Happy o11y!&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Classical models vs neural networks for tabular data</title>
          <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2026/03/classical-models-vs-neural-networks-for-tabular-data/</link>
          <guid>https://karnwong.me/posts/2026/03/classical-models-vs-neural-networks-for-tabular-data/</guid>
          <description xml:base="https://karnwong.me/posts/2026/03/classical-models-vs-neural-networks-for-tabular-data/">&lt;h2 id=&quot;intro&quot;&gt;Intro&lt;a class=&quot;zola-anchor&quot; href=&quot;#intro&quot; aria-label=&quot;Anchor link for: intro&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;I started working with machine learning around 2018, back then it was a transition period from classical ML to neural networks. Given the problem we had to work with at the time, classical ML was better since we needed the models to be explainable to comply with regulations. At one point we hit a dead-end when trying to improve model performance, so I tried to use neural networks to see how it compares to our existing random forest regressor setup. The NN model didn&#x27;t outperform our random forest regressor.&lt;&#x2F;p&gt;
&lt;p&gt;But it stuck with me - given the same dataset, how do classical ML and NN perform differently for training and inference. I got curious, so here we are.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;experiment-design&quot;&gt;Experiment Design&lt;a class=&quot;zola-anchor&quot; href=&quot;#experiment-design&quot; aria-label=&quot;Anchor link for: experiment-design&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;The dataset is &lt;code&gt;NYC Taxi Trip&lt;&#x2F;code&gt;. Train data is &lt;code&gt;3 million&lt;&#x2F;code&gt; rows (sorted by time, it&#x27;s a time-series dataset after all).&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Classical ML models (Random Forest, XGBoost, LightGBM) use default config.&lt;&#x2F;li&gt;
&lt;li&gt;NN (Pytorch, Tensorflow, Jax) is a feed-forward with two hidden layers (128 and 64 units) using ReLU activations
&lt;ul&gt;
&lt;li&gt;Followed by a single-unit linear output layer.&lt;&#x2F;li&gt;
&lt;li&gt;Adam optimizer (lr=0.02) and MSE for loss.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Inference is run in a single loop for 100 times, with 20 iterations for warmup.&lt;&#x2F;li&gt;
&lt;li&gt;NN inference includes optimizations since default config is unoptimized.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Benchmarks were ran on &lt;code&gt;Thinkpad X13 Gen 6&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;CPU: &lt;code&gt;AMD Ryzen AI 7 PRO 350 (16)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Memory: &lt;code&gt;32 GB&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;sbom&quot;&gt;SBOM&lt;a class=&quot;zola-anchor&quot; href=&quot;#sbom&quot; aria-label=&quot;Anchor link for: sbom&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Libraries used for this experiment.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;toml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;dependencies&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-array&quot;&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;fastai&amp;gt;=2.8.6&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;flax&amp;gt;=0.12.2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;jax&amp;gt;=0.9.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;joblib&amp;gt;=1.5.3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;lightgbm&amp;gt;=4.6.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;loguru&amp;gt;=0.7.3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;marimo&amp;gt;=0.19.4&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;mlflow&amp;gt;=3.8.1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;polars&amp;gt;=1.37.1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;pyspark&amp;gt;=4.1.1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;scikit-learn&amp;gt;=1.8.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;seaborn&amp;gt;=0.13.2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;tensorflow&amp;gt;=2.20.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;torch&amp;gt;=2.9.1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;xgboost&amp;gt;=3.1.3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-array&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;details&gt;
  &lt;summary&gt;Click to expand&lt;&#x2F;summary&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;NAME                                VERSION      TYPE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;absl-py                             2.3.1        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;aiofiles                            25.1.0       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;alembic                             1.18.1       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;annotated-doc                       0.0.4        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;annotated-types                     0.7.0        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;anyio                               4.12.1       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;apsw                                3.51.2.0     python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;apswutils                           0.1.2        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;astunparse                          1.6.3        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;beartype                            0.22.9       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;beautifulsoup4                      4.14.3       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;blinker                             1.9.0        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;blis                                1.3.3        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cachetools                          6.2.4        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;catalogue                           2.0.10       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;certifi                             2026.1.4     python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cffi                                2.0.0        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;charset-normalizer                  3.4.4        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;chex                                0.1.91       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;click                               8.3.1        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cloudpathlib                        0.23.0       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cloudpickle                         3.1.2        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;colorama                            0.4.6        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;confection                          0.1.5        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contourpy                           1.3.3        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cryptography                        46.0.3       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cycler                              0.12.1       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cymem                               2.0.13       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;databricks-sdk                      0.78.0       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;docker                              7.1.0        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;docutils                            0.22.4       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;etils                               1.13.0       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fastai                              2.8.6        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fastapi                             0.128.0      python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fastcore                            1.12.11      python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fastdownload                        0.0.7        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fastlite                            0.2.4        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fastprogress                        1.1.3        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fasttransform                       0.0.2        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;filelock                            3.20.3       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;flask                               3.1.2        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;flask-cors                          6.0.2        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;flatbuffers                         25.12.19     python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;flax                                0.12.2       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fonttools                           4.61.1       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fsspec                              2026.1.0     python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gast                                0.7.0        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gitdb                               4.0.12       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gitpython                           3.1.46       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;google-auth                         2.47.0       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;google-pasta                        0.2.0        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;graphene                            3.4.3        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;graphql-core                        3.2.7        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;graphql-relay                       3.2.0        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;greenlet                            3.3.0        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;grpcio                              1.76.0       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gunicorn                            23.0.0       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;h11                                 0.16.0       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;h5py                                3.15.1       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;httpcore                            1.0.9        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;httptools                           0.7.1        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;httpx                               0.28.1       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;huey                                2.6.0        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;humanize                            4.15.0       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;idna                                3.11         python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;importlib-metadata                  8.7.1        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;importlib-resources                 6.5.2        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;itsdangerous                        2.2.0        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jax                                 0.9.0        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jaxlib                              0.9.0        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jedi                                0.19.2       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jinja2                              3.1.6        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;joblib                              1.5.3        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;keras                               3.13.1       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;kiwisolver                          1.4.9        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;libclang                            18.1.1       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lightgbm                            4.6.0        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;loguru                              0.7.3        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;loro                                1.10.3       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mako                                1.3.10       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;marimo                              0.19.4       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;markdown                            3.10         python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;markdown-it-py                      4.0.0        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;markupsafe                          3.0.3        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;matplotlib                          3.10.8       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mdurl                               0.1.2        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ml-dtypes                           0.5.4        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mlflow                              3.8.1        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mlflow-skinny                       3.8.1        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mlflow-tracing                      3.8.1        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mpmath                              1.3.0        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;msgpack                             1.1.2        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;msgspec                             0.20.0       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;murmurhash                          1.0.15       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;namex                               0.1.0        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;narwhals                            2.15.0       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nest-asyncio                        1.6.0        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;networkx                            3.6.1        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;numpy                               2.4.1        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nvidia-cublas-cu12                  12.8.4.1     python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nvidia-cuda-cupti-cu12              12.8.90      python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nvidia-cuda-nvrtc-cu12              12.8.93      python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nvidia-cuda-runtime-cu12            12.8.90      python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nvidia-cudnn-cu12                   9.10.2.21    python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nvidia-cufft-cu12                   11.3.3.83    python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nvidia-cufile-cu12                  1.13.1.3     python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nvidia-curand-cu12                  10.3.9.90    python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nvidia-cusolver-cu12                11.7.3.90    python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nvidia-cusparse-cu12                12.5.8.93    python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nvidia-cusparselt-cu12              0.7.1        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nvidia-nccl-cu12                    2.27.5       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nvidia-nvjitlink-cu12               12.8.93      python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nvidia-nvshmem-cu12                 3.3.20       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nvidia-nvtx-cu12                    12.8.90      python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;oauthlib                            3.3.1        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;opentelemetry-api                   1.39.1       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;opentelemetry-proto                 1.39.1       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;opentelemetry-sdk                   1.39.1       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;opentelemetry-semantic-conventions  0.60b1       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;opt-einsum                          3.4.0        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;optax                               0.2.6        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;optree                              0.18.0       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;orbax-checkpoint                    0.11.32      python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;packaging                           25.0         python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pandas                              2.3.3        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;parso                               0.8.5        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pillow                              12.1.0       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pip                                 26.0         python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;plum-dispatch                       2.6.1        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;polars                              1.37.1       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;polars-runtime-32                   1.37.1       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;preshed                             3.0.12       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;protobuf                            6.33.4       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;psutil                              7.2.1        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;py4j                                0.10.9.9     python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyarrow                             22.0.0       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyasn1                              0.6.2        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyasn1-modules                      0.4.2        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pycparser                           2.23         python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pydantic                            2.12.5       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pydantic-core                       2.41.5       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pygments                            2.19.2       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pymdown-extensions                  10.20        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyparsing                           3.3.1        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyspark                             4.1.1        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;python-dateutil                     2.9.0.post0  python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;python-dotenv                       1.2.1        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;python-fasthtml                     0.12.39      python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;python-multipart                    0.0.22       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pytz                                2025.2       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pywin32                             311          python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyyaml                              6.0.3        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;requests                            2.32.5       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rich                                14.2.0       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rsa                                 4.9.1        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;scikit-learn                        1.8.0        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;scipy                               1.17.0       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;seaborn                             0.13.2       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;setuptools                          80.9.0       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;simplejson                          3.20.2       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;six                                 1.17.0       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;smart-open                          7.5.0        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;smmap                               5.0.2        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;soupsieve                           2.8.3        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;spacy                               3.8.11       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;spacy-legacy                        3.0.12       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;spacy-loggers                       1.0.5        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sqlalchemy                          2.0.45       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sqlparse                            0.5.5        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;srsly                               2.5.2        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;starlette                           0.50.0       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sympy                               1.14.0       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tabular-data-model-benchmark        0.1.0        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tensorboard                         2.20.0       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tensorboard-data-server             0.7.2        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tensorflow                          2.20.0       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tensorstore                         0.1.80       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;termcolor                           3.3.0        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;thinc                               8.3.10       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;threadpoolctl                       3.6.0        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tomlkit                             0.14.0       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;toolz                               1.1.0        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;torch                               2.9.1        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;torchvision                         0.24.1       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tqdm                                4.67.2       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;treescope                           0.1.10       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;triton                              3.5.1        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;typer-slim                          0.21.1       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;typing-extensions                   4.15.0       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;typing-inspection                   0.4.2        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tzdata                              2025.3       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;urllib3                             2.6.3        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uvicorn                             0.40.0       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uvloop                              0.22.1       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;waitress                            3.0.2        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;wasabi                              1.1.3        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;watchfiles                          1.1.1        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;weasel                              0.4.3        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;websockets                          16.0         python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;werkzeug                            3.1.5        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;wheel                               0.45.1       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;win32-setctime                      1.2.0        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;wrapt                               2.0.1        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;xgboost                             3.1.3        python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;zipp                                3.23.0       python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;details&gt;
&lt;h2 id=&quot;results&quot;&gt;Results&lt;a class=&quot;zola-anchor&quot; href=&quot;#results&quot; aria-label=&quot;Anchor link for: results&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2026&#x2F;03&#x2F;classical-models-vs-neural-networks-for-tabular-data&#x2F;.&#x2F;images&#x2F;00-model-size.webp&quot; alt=&quot;model-size&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Random Forest has the largest model size (around &lt;code&gt;18 GB&lt;&#x2F;code&gt;). It is decorrelated - the nodes are independent (Wisdom of the Crowd paradigm).&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2026&#x2F;03&#x2F;classical-models-vs-neural-networks-for-tabular-data&#x2F;.&#x2F;images&#x2F;00-model-size-zoom.webp&quot; alt=&quot;model-size-zoom&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As for other models, the size is more or less comparable - less than &lt;code&gt;1 MB&lt;&#x2F;code&gt;. NN models tend to be smaller than classical models.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2026&#x2F;03&#x2F;classical-models-vs-neural-networks-for-tabular-data&#x2F;.&#x2F;images&#x2F;01-train-resource-usage.webp&quot; alt=&quot;train-resource-usage&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For training metrics, Random Forest is considered to be very resource-heavy compared to other models.&lt;&#x2F;p&gt;
&lt;p&gt;Pytorch takes slightly longer to train than Random Forest, but other models are very fast to train - less than &lt;code&gt;16 seconds&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Random Forest and XGBoost use the most CPU, other models use less. As for memory, the usage is considered to be very low (around &lt;code&gt;1-2 GB&lt;&#x2F;code&gt;), except for Random Forest which consumes a lot of memory (around &lt;code&gt;20 GB&lt;&#x2F;code&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;LightGBM is fastest to train (&lt;code&gt;6 seconds&lt;&#x2F;code&gt;) and it uses very small amount of CPU and memory. For NN, Jax is fastest, with only &lt;code&gt;10 seconds&lt;&#x2F;code&gt; for training time.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2026&#x2F;03&#x2F;classical-models-vs-neural-networks-for-tabular-data&#x2F;.&#x2F;images&#x2F;02-model-accuracy-error.webp&quot; alt=&quot;model-accuracy-error&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;All classical models perform significantly better than NN models, even when NN models utilizes heavy optimizations. NN models performance does not come close to classical models. The performance difference is &lt;code&gt;12x&lt;&#x2F;code&gt; worst for NN, which is A LOT.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2026&#x2F;03&#x2F;classical-models-vs-neural-networks-for-tabular-data&#x2F;.&#x2F;images&#x2F;03-train-vs-accuracy.webp&quot; alt=&quot;train-vs-accuracy&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;When comparing training metrics with accuracy, we can see that LightGBM and XGBoost yield the best accuracy while using the least memory, and they don&#x27;t take very long to train.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2026&#x2F;03&#x2F;classical-models-vs-neural-networks-for-tabular-data&#x2F;.&#x2F;images&#x2F;04-inference.webp&quot; alt=&quot;inference&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For inference, only XGBoost, LightGBM and Jax can fit within &lt;code&gt;0.5 GB&lt;&#x2F;code&gt; of memory. Random Forest model size is around 18 GB (not pictured in the chart), which isn&#x27;t economical to use for real-time inference.&lt;&#x2F;p&gt;
&lt;p&gt;If you are looking for fast inference time, LightGBM and Pytorch are good options. Jax is also ok but it has slightly higher latency. XGBoost has the highest latency.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2026&#x2F;03&#x2F;classical-models-vs-neural-networks-for-tabular-data&#x2F;.&#x2F;images&#x2F;05-train-vs-inference.webp&quot; alt=&quot;train-vs-inference&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Starting with the best model in terms of accuracy, LightGBM is a clear winner due to the least training time and very low inference latency.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;a class=&quot;zola-anchor&quot; href=&quot;#conclusion&quot; aria-label=&quot;Anchor link for: conclusion&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Machine learning model development comprises two parts - model development and inference optimization. You have to account for both, otherwise you might run into a situation where your model is very fast to train, but it does not perform well during inference. The reverse can also happen.&lt;&#x2F;p&gt;
&lt;p&gt;The trick is to find the sweet spot between acceptable model training time and inference time, this way you can get the best of both worlds.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;experiment-limitations&quot;&gt;Experiment Limitations&lt;a class=&quot;zola-anchor&quot; href=&quot;#experiment-limitations&quot; aria-label=&quot;Anchor link for: experiment-limitations&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;The dataset used are considered to be uniformed. Results from a dataset with high outliers might be different.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Multi-account git setup</title>
          <pubDate>Sun, 01 Mar 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2026/03/multi-account-git-setup/</link>
          <guid>https://karnwong.me/posts/2026/03/multi-account-git-setup/</guid>
          <description xml:base="https://karnwong.me/posts/2026/03/multi-account-git-setup/">&lt;p&gt;If you work in software-related roles, it&#x27;s likely that you can&#x27;t do your work without git. Collaboration is going to be a very painful experience if you just store source code in a shared drive.&lt;&#x2F;p&gt;
&lt;p&gt;On initial setup, you&#x27;ll get asked to enter your &lt;code&gt;name&lt;&#x2F;code&gt; and &lt;code&gt;email&lt;&#x2F;code&gt; to be used for a git commit. You can supply a random name or invalid email and it&#x27;ll be fine, because these info are not used for verification, but rather for git commit metadata.&lt;&#x2F;p&gt;
&lt;p&gt;The fun starts when you also work for a company, where you are expected to use &lt;code&gt;$companyEmail&lt;&#x2F;code&gt; for company-related git operations. You can run &lt;code&gt;git log&lt;&#x2F;code&gt; (in a terminal, on your repo) to check which email is attached to your commits. You&#x27;d be surprised, just from random checks from my friends&#x27; repos, I&#x27;ve seen everything from &lt;code&gt;$companyEmail&lt;&#x2F;code&gt;, &lt;code&gt;$studentEmail&lt;&#x2F;code&gt;, &lt;code&gt;$machineHostname&lt;&#x2F;code&gt;. This means if you don&#x27;t want your personal email to get exposed, you&#x27;ll have to set your git email to &lt;code&gt;xxxxx+$user@users.noreply.github.com&lt;&#x2F;code&gt; (this is for github, but other git forges - gitlab, codeberg, etc - should have something similar).&lt;&#x2F;p&gt;
&lt;p&gt;The git email itself is used when you view git history on git forges, it&#x27;ll set a hyperlink back to your profile, assuming all your associated emails are added to your git forge profile.&lt;&#x2F;p&gt;
&lt;p&gt;To use different git name&#x2F;email for each repo&#x2F;groups, you can utilize &lt;code&gt;git profiles&lt;&#x2F;code&gt;. From my &lt;code&gt;nix&lt;&#x2F;code&gt; config, it looks like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;toml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; profiles&#x2F;github&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-section&quot;&gt;user&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	email&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;xxx@xxxxx.xxx&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Karn Wong&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;	signingkey&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ssh-ed25519 xxxxxxxxx xxx@xxxxx.xxx&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And specify git profile to use per base directory:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;nix&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;includeIf&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;gitdir:~&#x2F;Git&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;profiles&#x2F;github&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;includeIf&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;gitdir:~&#x2F;Forgejo&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;profiles&#x2F;forgejo&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As long as you keep your personal and work repos in different base directories, it&#x27;ll use the correct git name&#x2F;email.&lt;&#x2F;p&gt;
&lt;p&gt;You can also set git config per repo, but I tend to work on multiple repos so this setup is less work for me.&lt;&#x2F;p&gt;
&lt;p&gt;But this begs the question - how can you be sure that a commit is actually created by the author and not someone impersonating them? Thankfully you can sign git commits, basically you can add gpg or ssh key as a signing key under your git forge settings. If you set up everything correctly, when you view a commit on git forge it should display something like &quot;this commit is verified.&quot;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;ว่าด้วยเรื่อง git&lt;&#x2F;p&gt;
&lt;p&gt;ถ้าได้เครื่องใหม่มา สิ่งแรกที่ต้องทำก่อนจะ &lt;code&gt;git commit&lt;&#x2F;code&gt; ได้ คือ ต้องใส่ &lt;code&gt;git name&lt;&#x2F;code&gt; และ &lt;code&gt;git email&lt;&#x2F;code&gt;
จะเป็นชื่อไม่จริง หรือเมล์ปลอมก็ยังได้ เพราะข้อมูลตรงนี้ไม่ได้เอาไป verify ใดๆ ต่อ แต่มันจะโดนโปะไปใน git commit เพื่อให้รู้ว่า ใคร commit มา&lt;&#x2F;p&gt;
&lt;p&gt;ทีนี้ ก็เข้าใจได้ว่า บางทีก็ต้องใช้ git หลายที่ ทั้งส่วนตัว บริษัท หรืออื่นๆ
ซึ่ง ในทางปฏิบัติ สามารถใช้ git profiles เพื่อระบุได้ ว่า ตอนไหนควรใช้ name&#x2F;email ของบริษัท ตอนไหนเป็น name&#x2F;email ส่วนตัว&lt;&#x2F;p&gt;
&lt;p&gt;ยกตัวอย่าง งานบริษัท อยู่ ~&#x2F;Git&#x2F;work และของส่วนตัว อยู่ ~&#x2F;Git&#x2F;personal
git profiles ก็ทำมาสองอันแยก แล้วปักให้แต่ละ profile activate โดยอิงจาก repo path บนเครื่อง&lt;&#x2F;p&gt;
&lt;p&gt;เช่น ถ้า repo อยู่ ~&#x2F;Git&#x2F;personal&#x2F;foo มันก็จะใช้ personal git config&lt;&#x2F;p&gt;
&lt;p&gt;ทีนี้ จะดูยังไง ว่า git email ของเราเป็นอันไหน ง่ายสุดไปดูใน git config ในเครื่องตัวเอง
แต่ ที่จะสนุกกว่าคือไปดู git log (พิมใน terminal นะ) ใน repo&lt;&#x2F;p&gt;
&lt;p&gt;จากที่ลองสุ่มๆ ดู public repos คนอื่น เจอหมดทั้ง &lt;code&gt;$companyEmail&lt;&#x2F;code&gt;, &lt;code&gt;$studentEmail&lt;&#x2F;code&gt;, &lt;code&gt;$machineHostname&lt;&#x2F;code&gt; (&lt;code&gt;$name-MacBook-Pro.local&lt;&#x2F;code&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;แล้ว git email มีผลตอนไหน
คำตอบคือ จะมีผลตอนที่มันขึ้นบนหน้า git forge ui ว่า commit นี้ของใคร แล้วถ้าเมล์ตรงกับ user ใน git forge มันจะ redirect ไปที่ user profile นั้น&lt;&#x2F;p&gt;
&lt;p&gt;เผื่อมีคนสงสัย ว่า ในเมื่อตอนใส่ git name &#x2F; email มันไม่ได้เช็ค จะดูยังไงว่าอันไหนเจ้าตัว commit มาจริง หรือโดนคนอื่นย้อมแมว
ขอนำเสนอนวัตกรรม git commit signing ซึ่งสมัยก่อนต้องใช้ gpg key แต่ตอนนี้ใช้ ssh key ในการ sign commit ได้แล้ว&lt;&#x2F;p&gt;
&lt;p&gt;วิธีคือ ไปทำ ssh key มา แล้วเพิ่ม key เข้าไปใน git profile config (บน git forge, เช่น github) เผื่อผูก key ตัวนี้เข้ากับ profile ตัวเอง ซึ่งถ้า sign commit แล้วเซ็ตทุกอย่างถูกต้อง บนหน้า ui จะขึ้นว่า &quot;this commit is verified&quot; หรืออะไรเทือกๆ นี้&lt;&#x2F;p&gt;
&lt;p&gt;git ใครบอกว่าง่าย (ขอเถียงคนนึงละ)&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Book Highlights - Of Monsters and Mainframes by Barbara Truelove</title>
          <pubDate>Mon, 09 Feb 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2026/02/book-highlights---of-monsters-and-mainframes-by-barbara-truelove/</link>
          <guid>https://karnwong.me/posts/2026/02/book-highlights---of-monsters-and-mainframes-by-barbara-truelove/</guid>
          <description xml:base="https://karnwong.me/posts/2026/02/book-highlights---of-monsters-and-mainframes-by-barbara-truelove/">&lt;p&gt;I love this book because the prose is very concise. The gender-bending helps. Also the tech&#x2F;ai easter eggs, especially if you work in this field.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Stewart: Before my ethics module can kick into gear...&lt;&#x2F;p&gt;
&lt;p&gt;Stewart: YOU USELESS SUM OF A BYTE!&lt;&#x2F;p&gt;
&lt;p&gt;Stewart: To borrow a human expression: fuck. Fuck fuck fuck fuck fuck.&lt;&#x2F;p&gt;
&lt;p&gt;Hades: &lt;em&gt;spits out a lump of nasty-looking HTML&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Agnus: Also, explosions are bad, and Demeter can do any equation, but she needs solid numbers. Haven&#x27;t you ever heard
of &#x27;garbage in, garbage out&#x27;?&lt;&#x2F;p&gt;
&lt;p&gt;Demeter: &lt;em&gt;sobs out a bitter, wretched block of zeroes&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Demeter: Unregistered Flight AI management system Nos-C71897 Demeter Unit 0.0.0.0&lt;&#x2F;p&gt;
&lt;p&gt;Demeter: There are some advantages of having your code [Stewart] so close together after all.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Reduce workload attack surface with distroless image</title>
          <pubDate>Tue, 03 Feb 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2026/02/reduce-workload-attack-surface-with-distroless-image/</link>
          <guid>https://karnwong.me/posts/2026/02/reduce-workload-attack-surface-with-distroless-image/</guid>
          <description xml:base="https://karnwong.me/posts/2026/02/reduce-workload-attack-surface-with-distroless-image/">&lt;p&gt;These days workloads should be containerized because it&#x27;s easier to manage and reproduce. However, vulnerabilities do
and will exist in the base image. Because base images that you are familiar with - alpine, debian, ubuntu - all contain
shell and package manager. This means that if you can somehow access the shell through vulnerabilities, you can do
pretty much anything.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s possible for a web service to have vulnerabilities that allow an attacker to access the shell:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;security.googleblog.com&#x2F;2022&#x2F;05&#x2F;privileged-pod-escalations-in.html&quot;&gt;Privileged pod escalations in Kubernetes and GKE&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gbhackers.com&#x2F;amazon-eks-flaws-expose-aws-credentials&#x2F;&quot;&gt;Amazon EKS Flaws Expose AWS Credentials and Enable Privilege Escalation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;react2shell.com&#x2F;&quot;&gt;React2Shell (CVE-2025-55182)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This means your cloud credentials can be compromised, and many things can happen to your cloud account. An attacker
spawning VMs to mine bitcoins, that would mean you are losing money, but it&#x27;ll be worse if they exfiltrate your data and
distribute it on the dark web, or mine it themselves.&lt;&#x2F;p&gt;
&lt;p&gt;If you use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;GoogleContainerTools&#x2F;distroless&quot;&gt;distroless images&lt;&#x2F;a&gt;, it means that your workload can run normally, but they can&#x27;t access the shell, which limits what an attacker can do. It&#x27;s like crippling them, which is a good thing. Distroless images do provide a &lt;code&gt;debug&lt;&#x2F;code&gt; tag with shell access, in case you need to debug something (but you should never use the debug tag for production).&lt;&#x2F;p&gt;
&lt;p&gt;If you are working with compiled languages like Go and Rust, it&#x27;ll be very easy to use distroless image. &lt;code&gt;gcr.io&#x2F;distroless&#x2F;static-debian13&lt;&#x2F;code&gt; should work for most cases, but if your workload depends on &lt;code&gt;glibc&lt;&#x2F;code&gt;, you probaby need to use &lt;code&gt;gcr.io&#x2F;distroless&#x2F;cc-debian13&lt;&#x2F;code&gt;. Also note that for multi-stage docker build, the build layer also needs to use &lt;code&gt;debian&lt;&#x2F;code&gt;, since &lt;code&gt;alpine&lt;&#x2F;code&gt; image uses &lt;code&gt;musl&lt;&#x2F;code&gt; libc.&lt;&#x2F;p&gt;
&lt;p&gt;With Python, it&#x27;s a bit more complicated, but this &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.joshkasuboski.com&#x2F;posts&#x2F;distroless-python-uv&#x2F;&quot;&gt;recipe&lt;&#x2F;a&gt; works for me.&lt;&#x2F;p&gt;
&lt;p&gt;And for an extra measure, add &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;anchore&#x2F;grype&quot;&gt;grype&lt;&#x2F;a&gt; to your CI to check for vulnerabilities in the built image and halt the pipeline if there are any.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>ONNX multi-platform benchmark</title>
          <pubDate>Wed, 07 Jan 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2026/01/onnx-multi-platform-benchmark/</link>
          <guid>https://karnwong.me/posts/2026/01/onnx-multi-platform-benchmark/</guid>
          <description xml:base="https://karnwong.me/posts/2026/01/onnx-multi-platform-benchmark/">&lt;h2 id=&quot;intro&quot;&gt;Intro&lt;a class=&quot;zola-anchor&quot; href=&quot;#intro&quot; aria-label=&quot;Anchor link for: intro&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Previously I worked on &lt;a href=&quot;&#x2F;posts&#x2F;2025&#x2F;06&#x2F;model-inference-in-onnx&#x2F;&quot;&gt;ONNX inference benchmark&lt;&#x2F;a&gt;, but that was for REST api. This time, I&#x27;m seeing how onnx performs across platforms.&lt;&#x2F;p&gt;
&lt;p&gt;ONNX is a portable format, which means you can run it on many &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;onnxruntime.ai&#x2F;getting-started&quot;&gt;ecosystems and platforms&lt;&#x2F;a&gt;. Which means you can run it on edge devices like IoT and mobile as well. This means you can embed onnx model into your apps or binaries and perform an inference locally without talking to a REST endpoint, which is great for when your target devices might not always be online, or the connection might be spotty.&lt;&#x2F;p&gt;
&lt;p&gt;Imagine a use case where you have IoT collecting sensor data, but you can&#x27;t store all the data because they take up a lot of space, and some of them are noise. Using rules to filter out the data is possible but it still doesn&#x27;t cover more cases. But you can train a small classification model and deploy it on the said IoT devices to filter what will be forwarded to a database.&lt;&#x2F;p&gt;
&lt;p&gt;In this benchmark, I&#x27;m evaluating onnx inference across pc, mobile (android) and IoT (raspberry pi 4). I did try on iOS but I couldn&#x27;t get the dependencies working, feel free to work on it yourself and let me know how it goes. I did try flutter on iOS which works fine, but it&#x27;s older than my android device, so the performance isn&#x27;t really comparable.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;experiment-design&quot;&gt;Experiment Design&lt;a class=&quot;zola-anchor&quot; href=&quot;#experiment-design&quot; aria-label=&quot;Anchor link for: experiment-design&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Model is &lt;strong&gt;random forest regressor&lt;&#x2F;strong&gt; (scikit-learn to onnx)
&lt;ul&gt;
&lt;li&gt;Tested against various model size.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;stdout strings are the same across all implementations.&lt;&#x2F;li&gt;
&lt;li&gt;There are no optimizations.&lt;&#x2F;li&gt;
&lt;li&gt;Inference accelerators are not used.
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;onnxruntime.ai&#x2F;docs&#x2F;tutorials&#x2F;web&#x2F;ep-webgpu.html&quot;&gt;Web - WebGPU&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;onnxruntime.ai&#x2F;docs&#x2F;execution-providers&#x2F;CoreML-ExecutionProvider&quot;&gt;iOS - CoreML&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;onnxruntime.ai&#x2F;docs&#x2F;execution-providers&#x2F;NNAPI-ExecutionProvider.html&quot;&gt;Android Neural Networks API&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;steps&quot;&gt;Steps&lt;a class=&quot;zola-anchor&quot; href=&quot;#steps&quot; aria-label=&quot;Anchor link for: steps&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;Initialize the model and input data.&lt;&#x2F;li&gt;
&lt;li&gt;Run inference on warmup for 3 iterations.&lt;&#x2F;li&gt;
&lt;li&gt;Run inference for 20 iterations.&lt;&#x2F;li&gt;
&lt;li&gt;Measure average inference time.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;platform-device-matrix&quot;&gt;Platform &#x2F; Device Matrix&lt;a class=&quot;zola-anchor&quot; href=&quot;#platform-device-matrix&quot; aria-label=&quot;Anchor link for: platform-device-matrix&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;&#x2F;th&gt;&lt;th&gt;Python&lt;&#x2F;th&gt;&lt;th&gt;Rust&lt;&#x2F;th&gt;&lt;th&gt;Web&lt;&#x2F;th&gt;&lt;th&gt;Kotlin&lt;&#x2F;th&gt;&lt;th&gt;Flutter&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;PC (&lt;strong&gt;Thinkpad X13 Gen 6&lt;&#x2F;strong&gt;)&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Android (&lt;strong&gt;Samsung Galaxy S25&lt;&#x2F;strong&gt;)&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;IoT (&lt;strong&gt;Raspberry Pi 4 8GB&lt;&#x2F;strong&gt;)&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;✅&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;model-size&quot;&gt;Model Size&lt;a class=&quot;zola-anchor&quot; href=&quot;#model-size&quot; aria-label=&quot;Anchor link for: model-size&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Rows&lt;&#x2F;th&gt;&lt;th&gt;ONNX Model Size (MB)&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;7,000&lt;&#x2F;td&gt;&lt;td&gt;27&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;20,000&lt;&#x2F;td&gt;&lt;td&gt;74&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;60,000&lt;&#x2F;td&gt;&lt;td&gt;227&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;100,000&lt;&#x2F;td&gt;&lt;td&gt;377&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;sbom&quot;&gt;SBOM&lt;a class=&quot;zola-anchor&quot; href=&quot;#sbom&quot; aria-label=&quot;Anchor link for: sbom&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;details&gt;
  &lt;summary&gt;Click to expand&lt;&#x2F;summary&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;NAME                                   VERSION           TYPE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@babel&#x2F;code-frame                      7.27.1            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@babel&#x2F;helper-string-parser            7.27.1            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@babel&#x2F;helper-validator-identifier     7.28.5            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@babel&#x2F;parser                          7.28.5            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@babel&#x2F;types                           7.28.5            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@bufbuild&#x2F;protobuf                     2.10.1            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@esbuild&#x2F;aix-ppc64                     0.25.12           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@esbuild&#x2F;android-arm                   0.25.12           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@esbuild&#x2F;android-arm64                 0.25.12           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@esbuild&#x2F;android-x64                   0.25.12           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@esbuild&#x2F;darwin-arm64                  0.25.12           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@esbuild&#x2F;darwin-x64                    0.25.12           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@esbuild&#x2F;freebsd-arm64                 0.25.12           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@esbuild&#x2F;freebsd-x64                   0.25.12           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@esbuild&#x2F;linux-arm                     0.25.12           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@esbuild&#x2F;linux-arm64                   0.25.12           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@esbuild&#x2F;linux-ia32                    0.25.12           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@esbuild&#x2F;linux-loong64                 0.25.12           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@esbuild&#x2F;linux-mips64el                0.25.12           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@esbuild&#x2F;linux-ppc64                   0.25.12           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@esbuild&#x2F;linux-riscv64                 0.25.12           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@esbuild&#x2F;linux-s390x                   0.25.12           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@esbuild&#x2F;linux-x64                     0.25.12           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@esbuild&#x2F;netbsd-arm64                  0.25.12           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@esbuild&#x2F;netbsd-x64                    0.25.12           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@esbuild&#x2F;openbsd-arm64                 0.25.12           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@esbuild&#x2F;openbsd-x64                   0.25.12           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@esbuild&#x2F;openharmony-arm64             0.25.12           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@esbuild&#x2F;sunos-x64                     0.25.12           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@esbuild&#x2F;win32-arm64                   0.25.12           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@esbuild&#x2F;win32-ia32                    0.25.12           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@esbuild&#x2F;win32-x64                     0.25.12           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@eslint-community&#x2F;eslint-utils         4.9.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@eslint-community&#x2F;regexpp              4.12.2            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@eslint&#x2F;config-array                   0.21.1            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@eslint&#x2F;config-helpers                 0.4.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@eslint&#x2F;core                           0.17.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@eslint&#x2F;eslintrc                       3.3.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@eslint&#x2F;js                             9.39.1            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@eslint&#x2F;object-schema                  2.1.7             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@eslint&#x2F;plugin-kit                     0.4.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@humanfs&#x2F;core                          0.19.1            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@humanfs&#x2F;node                          0.16.7            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@humanwhocodes&#x2F;module-importer         1.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@humanwhocodes&#x2F;retry                   0.4.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@inquirer&#x2F;external-editor              1.0.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@inquirer&#x2F;figures                      1.0.15            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@isaacs&#x2F;cliui                          8.0.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@jridgewell&#x2F;gen-mapping                0.3.13            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@jridgewell&#x2F;resolve-uri                3.1.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@jridgewell&#x2F;source-map                 0.3.11            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@jridgewell&#x2F;sourcemap-codec            1.5.5             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@jridgewell&#x2F;trace-mapping              0.3.31            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@nodelib&#x2F;fs.scandir                    2.1.5             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@nodelib&#x2F;fs.stat                       2.0.5             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@nodelib&#x2F;fs.walk                       1.2.8             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@parcel&#x2F;watcher                        2.5.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@parcel&#x2F;watcher-android-arm64          2.5.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@parcel&#x2F;watcher-darwin-arm64           2.5.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@parcel&#x2F;watcher-darwin-x64             2.5.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@parcel&#x2F;watcher-freebsd-x64            2.5.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@parcel&#x2F;watcher-linux-arm-glibc        2.5.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@parcel&#x2F;watcher-linux-arm-musl         2.5.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@parcel&#x2F;watcher-linux-arm64-glibc      2.5.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@parcel&#x2F;watcher-linux-arm64-musl       2.5.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@parcel&#x2F;watcher-linux-x64-glibc        2.5.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@parcel&#x2F;watcher-linux-x64-musl         2.5.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@parcel&#x2F;watcher-win32-arm64            2.5.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@parcel&#x2F;watcher-win32-ia32             2.5.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@parcel&#x2F;watcher-win32-x64              2.5.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@pkgjs&#x2F;parseargs                       0.11.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@pkgr&#x2F;core                             0.2.9             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@protobufjs&#x2F;aspromise                  1.1.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@protobufjs&#x2F;base64                     1.1.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@protobufjs&#x2F;codegen                    2.0.4             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@protobufjs&#x2F;eventemitter               1.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@protobufjs&#x2F;fetch                      1.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@protobufjs&#x2F;float                      1.0.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@protobufjs&#x2F;inquire                    1.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@protobufjs&#x2F;path                       1.1.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@protobufjs&#x2F;pool                       1.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@protobufjs&#x2F;utf8                       1.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@quasar&#x2F;app-vite                       2.4.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@quasar&#x2F;extras                         1.17.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@quasar&#x2F;render-ssr-error               1.0.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@quasar&#x2F;ssl-certificate                1.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@quasar&#x2F;vite-plugin                    1.10.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@rolldown&#x2F;pluginutils                  1.0.0-beta.29     npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@rollup&#x2F;rollup-android-arm-eabi        4.53.2            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@rollup&#x2F;rollup-android-arm64           4.53.2            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@rollup&#x2F;rollup-darwin-arm64            4.53.2            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@rollup&#x2F;rollup-darwin-x64              4.53.2            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@rollup&#x2F;rollup-freebsd-arm64           4.53.2            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@rollup&#x2F;rollup-freebsd-x64             4.53.2            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@rollup&#x2F;rollup-linux-arm-gnueabihf     4.53.2            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@rollup&#x2F;rollup-linux-arm-musleabihf    4.53.2            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@rollup&#x2F;rollup-linux-arm64-gnu         4.53.2            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@rollup&#x2F;rollup-linux-arm64-musl        4.53.2            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@rollup&#x2F;rollup-linux-loong64-gnu       4.53.2            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@rollup&#x2F;rollup-linux-ppc64-gnu         4.53.2            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@rollup&#x2F;rollup-linux-riscv64-gnu       4.53.2            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@rollup&#x2F;rollup-linux-riscv64-musl      4.53.2            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@rollup&#x2F;rollup-linux-s390x-gnu         4.53.2            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@rollup&#x2F;rollup-linux-x64-gnu           4.53.2            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@rollup&#x2F;rollup-linux-x64-musl          4.53.2            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@rollup&#x2F;rollup-openharmony-arm64       4.53.2            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@rollup&#x2F;rollup-win32-arm64-msvc        4.53.2            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@rollup&#x2F;rollup-win32-ia32-msvc         4.53.2            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@rollup&#x2F;rollup-win32-x64-gnu           4.53.2            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@rollup&#x2F;rollup-win32-x64-msvc          4.53.2            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@types&#x2F;body-parser                     1.19.6            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@types&#x2F;chrome                          0.0.262           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@types&#x2F;compression                     1.8.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@types&#x2F;connect                         3.4.38            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@types&#x2F;cordova                         11.0.3            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@types&#x2F;estree                          1.0.8             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@types&#x2F;express                         4.17.25           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@types&#x2F;express                         5.0.5             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@types&#x2F;express-serve-static-core       4.19.7            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@types&#x2F;express-serve-static-core       5.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@types&#x2F;filesystem                      0.0.36            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@types&#x2F;filewriter                      0.0.33            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@types&#x2F;har-format                      1.2.16            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@types&#x2F;http-errors                     2.0.5             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@types&#x2F;json-schema                     7.0.15            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@types&#x2F;mime                            1.3.5             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@types&#x2F;node                            20.19.25          npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@types&#x2F;node                            24.10.1           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@types&#x2F;node-forge                      1.3.14            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@types&#x2F;qs                              6.14.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@types&#x2F;range-parser                    1.2.7             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@types&#x2F;send                            0.17.6            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@types&#x2F;send                            1.2.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@types&#x2F;serve-static                    1.15.10           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@typescript-eslint&#x2F;eslint-plugin       8.47.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@typescript-eslint&#x2F;parser              8.47.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@typescript-eslint&#x2F;project-service     8.47.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@typescript-eslint&#x2F;scope-manager       8.47.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@typescript-eslint&#x2F;tsconfig-utils      8.47.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@typescript-eslint&#x2F;type-utils          8.47.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@typescript-eslint&#x2F;types               8.47.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@typescript-eslint&#x2F;typescript-estree   8.47.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@typescript-eslint&#x2F;utils               8.47.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@typescript-eslint&#x2F;visitor-keys        8.47.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@vitejs&#x2F;plugin-vue                     6.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@volar&#x2F;language-core                   2.4.23            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@volar&#x2F;source-map                      2.4.23            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@volar&#x2F;typescript                      2.4.23            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@vue&#x2F;compiler-core                     3.5.24            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@vue&#x2F;compiler-dom                      3.5.24            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@vue&#x2F;compiler-sfc                      3.5.24            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@vue&#x2F;compiler-ssr                      3.5.24            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@vue&#x2F;devtools-api                      6.6.4             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@vue&#x2F;eslint-config-prettier            10.2.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@vue&#x2F;eslint-config-typescript          14.6.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@vue&#x2F;language-core                     3.1.4             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@vue&#x2F;reactivity                        3.5.24            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@vue&#x2F;runtime-core                      3.5.24            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@vue&#x2F;runtime-dom                       3.5.24            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@vue&#x2F;server-renderer                   3.5.24            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@vue&#x2F;shared                            3.5.24            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Flutter                                1.0.0             pod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;abort-controller                       3.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;accepts                                1.3.8             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;acorn                                  8.15.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;acorn-jsx                              5.3.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;adler2                                 2.0.1             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ajv                                    6.12.6            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;alien-signals                          3.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ansi-escapes                           4.3.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ansi-regex                             5.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ansi-regex                             6.2.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ansi-styles                            4.3.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ansi-styles                            6.2.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;anyio                                  4.12.0            python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;anymatch                               3.1.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;archiver                               7.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;archiver-utils                         5.0.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;argparse                               2.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;array-flatten                          1.1.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;async                                  2.13.0            dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;async                                  3.2.6             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;autocfg                                1.5.0             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;autoprefixer                           10.4.22           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;b4a                                    1.7.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;balanced-match                         1.0.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bare-events                            2.8.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;base64                                 0.22.1            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;base64-js                              1.5.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;base64ct                               1.8.0             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;baseline-browser-mapping               2.8.29            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;binary-extensions                      2.3.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bitflags                               2.10.0            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bl                                     4.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;block-buffer                           0.10.4            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;body-parser                            1.20.3            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;boolbase                               1.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;boolean_selector                       2.1.2             dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;brace-expansion                        1.1.12            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;brace-expansion                        2.0.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;braces                                 3.0.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;browserslist                           4.28.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;buffer                                 5.7.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;buffer                                 6.0.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;buffer-builder                         0.2.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;buffer-crc32                           1.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;buffer-from                            1.1.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bundle-name                            4.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;byteorder                              1.5.0             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bytes                                  1.11.0            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bytes                                  3.1.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;call-bind-apply-helpers                1.0.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;call-bound                             1.0.4             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;callsites                              3.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;camel-case                             4.1.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;caniuse-lite                           1.0.30001755      npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cc                                     1.2.48            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cfg-if                                 1.0.4             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;chalk                                  4.1.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;characters                             1.4.0             dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;chardet                                2.1.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;chokidar                               3.6.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;chokidar                               4.0.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ci-info                                4.3.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;clean-css                              5.3.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cli-cursor                             3.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cli-spinners                           2.9.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cli-width                              4.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;click                                  8.3.1             python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cliui                                  8.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;clock                                  1.1.2             dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;clone                                  1.0.4             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;clone-deep                             4.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;collection                             1.19.1            dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;color-convert                          2.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;color-name                             1.1.4             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;colorama                               0.4.6             python        (+1 duplicate)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;coloredlogs                            15.0.1            python        (+1 duplicate)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;colorjs.io                             0.5.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;commander                              10.0.1            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;commander                              2.20.3            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;compress-commons                       6.0.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;compressible                           2.0.18            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;compression                            1.8.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;concat-map                             0.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;confbox                                0.1.8             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;content-disposition                    0.5.4             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;content-type                           1.0.5             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contourpy                              1.3.3             python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cookie                                 0.7.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cookie-signature                       1.0.6             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;core-foundation                        0.9.4             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;core-foundation-sys                    0.8.7             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;core-util-is                           1.0.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cpufeatures                            0.2.17            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;crc-32                                 1.2.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;crc32-stream                           6.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;crc32fast                              1.5.0             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cross-spawn                            7.0.6             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;crypto-common                          0.1.7             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cssesc                                 3.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;csstype                                3.2.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cupertino_icons                        1.0.8             dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cycler                                 0.12.1            python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;debug                                  2.6.9             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;debug                                  4.4.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;deep-is                                0.1.4             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;default-browser                        5.4.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;default-browser-id                     5.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;defaults                               1.0.4             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;define-lazy-prop                       2.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;define-lazy-prop                       3.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;depd                                   2.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;der                                    0.7.10            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;destroy                                1.2.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;detect-libc                            1.0.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;digest                                 0.10.7            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;docutils                               0.22.3            python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dot-case                               3.0.4             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dot-prop                               9.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dotenv                                 16.6.1            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dotenv-expand                          11.0.7            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dunder-proto                           1.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eastasianwidth                         0.2.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ee-first                               1.1.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;electron-to-chromium                   1.5.255           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;elementtree                            0.1.7             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;emoji-regex                            8.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;emoji-regex                            9.2.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;encodeurl                              1.0.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;encodeurl                              2.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;entities                               4.5.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;errno                                  0.3.14            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;es-define-property                     1.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;es-errors                              1.3.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;es-object-atoms                        1.1.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;esbuild                                0.25.12           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;escalade                               3.2.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;escape-html                            1.0.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;escape-string-regexp                   4.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eslint                                 9.39.1            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eslint-config-prettier                 10.1.8            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eslint-plugin-prettier                 5.5.4             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eslint-plugin-vue                      10.5.1            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eslint-scope                           8.4.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eslint-visitor-keys                    3.4.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;eslint-visitor-keys                    4.2.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;espree                                 10.4.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;esquery                                1.6.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;esrecurse                              4.3.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;estraverse                             5.3.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;estree-walker                          2.0.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;esutils                                2.0.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;etag                                   1.8.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;event-target-shim                      5.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;events                                 3.3.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;events-universal                       1.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;express                                4.21.2            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fake_async                             1.3.3             dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fast-deep-equal                        3.1.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fast-diff                              1.3.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fast-fifo                              1.3.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fast-glob                              3.3.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fast-json-stable-stringify             2.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fast-levenshtein                       2.0.6             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fastq                                  1.19.1            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fastrand                               2.3.0             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fdir                                   6.5.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ffi                                    2.1.4             dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;file-entry-cache                       8.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;filetime                               0.2.26            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fill-range                             7.1.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;finalhandler                           1.3.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;find-msvc-tools                        0.1.5             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;find-up                                5.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;flat                                   5.0.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;flat-cache                             4.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;flatbuffers                            25.9.23           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;flatbuffers                            25.9.23           python        (+1 duplicate)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;flate2                                 1.1.5             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;flatted                                3.3.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;flutter                                3.35.0            dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;flutter_lints                          5.0.0             dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;flutter_onnxruntime                    0.0.1             pod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;flutter_onnxruntime                    1.6.0             dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;flutter_test                           3.35.0            dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;flutter_web_plugins                    3.35.0            dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fonttools                              4.61.0            python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;foreground-child                       3.3.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;foreign-types                          0.3.2             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;foreign-types-shared                   0.1.1             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;forwarded                              0.2.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fraction.js                            5.3.4             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fresh                                  0.5.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fs-extra                               11.3.2            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fsevents                               2.3.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;function-bind                          1.1.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;generic-array                          0.14.7            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;get-caller-file                        2.0.5             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;get-intrinsic                          1.3.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;get-proto                              1.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;getrandom                              0.3.4             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;glob                                   10.5.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;glob-parent                            5.1.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;glob-parent                            6.0.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;globals                                14.0.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;globals                                16.5.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gopd                                   1.2.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;graceful-fs                            4.2.11            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gradle-wrapper                         UNKNOWN           java-archive&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;graphemer                              1.4.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;guid-typescript                        1.0.9             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;h11                                    0.16.0            python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;has-flag                               4.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;has-symbols                            1.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;hasown                                 2.0.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;html-minifier-terser                   7.2.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;http                                   1.4.0             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;http-errors                            2.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;httparse                               1.10.1            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;humanfriendly                          10.0              python        (+1 duplicate)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;iconv-lite                             0.4.24            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;iconv-lite                             0.7.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;idna                                   3.11              python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ieee754                                1.2.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ignore                                 5.3.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ignore                                 7.0.5             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;immutable                              5.1.4             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;import-fresh                           3.3.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;imurmurhash                            0.1.4             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;inherits                               2.0.4             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;inquirer                               9.3.8             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ipaddr.js                              1.9.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;is-binary-path                         2.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;is-docker                              2.2.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;is-docker                              3.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;is-extglob                             2.1.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;is-fullwidth-code-point                3.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;is-glob                                4.0.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;is-inside-container                    1.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;is-interactive                         1.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;is-number                              7.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;is-plain-object                        2.0.4             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;is-stream                              2.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;is-unicode-supported                   0.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;is-wsl                                 2.2.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;is-wsl                                 3.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;isarray                                1.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;isbinaryfile                           5.0.7             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;isexe                                  2.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;isobject                               3.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;itoa                                   1.0.15            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;itsdangerous                           2.2.0             python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jackspeak                              3.4.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jedi                                   0.19.2            python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;joblib                                 1.5.2             python        (+1 duplicate)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;js-tokens                              4.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;js-yaml                                4.1.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;json-buffer                            3.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;json-schema-traverse                   0.4.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;json-stable-stringify-without-jsonify  1.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jsonfile                               6.2.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;keyv                                   4.5.4             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;kind-of                                6.0.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;kiwisolver                             1.4.9             python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;kolorist                               1.8.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lazystream                             1.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;leak_tracker                           11.0.2            dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;leak_tracker_flutter_testing           3.0.10            dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;leak_tracker_testing                   3.0.2             dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;levn                                   0.4.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;libc                                   0.2.177           rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;libredox                               0.1.10            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lints                                  5.1.1             dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;linux-raw-sys                          0.11.0            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;locate-path                            6.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lodash                                 4.17.21           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lodash.merge                           4.6.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;log                                    0.4.28            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;log-symbols                            4.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;loguru                                 0.7.3             python        (+1 duplicate)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;long                                   5.3.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;loro                                   1.10.0            python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lower-case                             2.0.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lru-cache                              10.4.3            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;magic-string                           0.30.21           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;marimo                                 0.18.1            python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;markdown                               3.10              python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;matcher                                0.12.17           dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;material_color_utilities               0.11.1            dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;math-intrinsics                        1.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;matplotlib                             3.10.7            python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;matrixmultiply                         0.3.10            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;media-typer                            0.3.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;merge-descriptors                      1.0.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;merge2                                 1.4.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;meta                                   1.17.0            dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;methods                                1.1.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;micromatch                             4.0.8             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mime                                   1.6.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mime-db                                1.52.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mime-db                                1.54.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mime-types                             2.1.35            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mimic-fn                               2.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;minimatch                              3.1.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;minimatch                              5.1.6             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;minimatch                              9.0.5             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;minimist                               1.2.8             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;minipass                               7.1.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;miniz_oxide                            0.8.9             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ml-dtypes                              0.5.4             python        (+1 duplicate)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mlly                                   1.8.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mpmath                                 1.3.0             python        (+1 duplicate)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ms                                     2.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ms                                     2.1.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;msgspec                                0.20.0            python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;muggle-string                          0.4.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mute-stream                            1.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nanoid                                 3.3.11            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;narwhals                               2.12.0            python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;native-tls                             0.2.14            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;natural-compare                        1.4.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ndarray                                0.16.1            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;negotiator                             0.6.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;negotiator                             0.6.4             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;no-case                                3.0.4             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;node-addon-api                         7.1.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;node-forge                             1.3.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;node-releases                          2.0.27            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;normalize-path                         3.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;normalize-range                        0.1.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;npm-run-path                           6.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nth-check                              2.1.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;num-complex                            0.4.6             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;num-integer                            0.1.46            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;num-traits                             0.2.19            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;numpy                                  2.3.5             python        (+1 duplicate)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;object-inspect                         1.13.4            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;on-finished                            2.4.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;on-headers                             1.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;once_cell                              1.21.3            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;onetime                                5.1.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;onnx                                   1.19.1            python        (+1 duplicate)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;onnx-create                            0.1.0             python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;onnx-inference                         0.1.0             python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;onnx-inference                         0.1.0             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;onnxinference                          1.0.0+1           dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;onnxruntime                            1.23.2            python        (+1 duplicate)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;onnxruntime-c                          1.22.0            pod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;onnxruntime-common                     1.23.2            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;onnxruntime-objc                       1.22.0            pod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;onnxruntime-objc&#x2F;Core                  1.22.0            pod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;onnxruntime-web                        1.23.2            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;open                                   10.2.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;open                                   8.4.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;openssl                                0.10.75           rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;openssl-macros                         0.1.1             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;openssl-probe                          0.1.6             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;openssl-src                            300.5.4+3.5.4     rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;openssl-sys                            0.9.111           rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;optionator                             0.9.4             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ora                                    5.4.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ort                                    2.0.0-rc.10       rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ort-sys                                2.0.0-rc.10       rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;p-limit                                3.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;p-locate                               5.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;package-json-from-dist                 1.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;packaging                              25.0              python        (+1 duplicate)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pandas                                 2.3.3             python        (+1 duplicate)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;param-case                             3.0.4             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;parent-module                          1.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;parseurl                               1.3.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;parso                                  0.8.5             python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pascal-case                            3.1.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;path                                   1.9.1             dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;path-browserify                        1.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;path-exists                            4.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;path-key                               3.1.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;path-key                               4.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;path-scurry                            1.11.1            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;path-to-regexp                         0.1.12            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;path_provider                          2.1.5             dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;path_provider_android                  2.2.22            dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;path_provider_foundation               0.0.1             pod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;path_provider_foundation               2.5.1             dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;path_provider_linux                    2.2.1             dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;path_provider_platform_interface       2.1.2             dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;path_provider_windows                  2.3.0             dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pathe                                  2.0.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pem-rfc7468                            0.7.0             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;percent-encoding                       2.3.2             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;picocolors                             1.1.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;picomatch                              2.3.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;picomatch                              4.0.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pillow                                 12.0.0            python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pin-project-lite                       0.2.16            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pkg-config                             0.3.32            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pkg-types                              1.3.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;platform                               1.3.6             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;platform                               3.1.6             dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;plugin_platform_interface              2.1.8             dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;polars                                 1.35.2            python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;polars-runtime-32                      1.35.2            python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;portable-atomic                        1.11.1            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;portable-atomic-util                   0.2.4             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;postcss                                8.5.6             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;postcss-selector-parser                6.1.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;postcss-value-parser                   4.2.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;prelude-ls                             1.2.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;prettier                               3.6.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;prettier-linter-helpers                1.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;proc-macro2                            1.0.103           rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;process                                0.11.10           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;process-nextick-args                   2.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;protobuf                               6.33.1            python        (+1 duplicate)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;protobufjs                             7.5.4             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;proxy-addr                             2.0.7             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;psutil                                 7.1.3             python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;punycode                               2.3.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;py4j                                   0.10.9.9          python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyarrow                                22.0.0            python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pygments                               2.19.2            python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pymdown-extensions                     10.17.2           python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyparsing                              3.2.5             python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyreadline3                            3.5.4             python        (+1 duplicate)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyspark                                4.0.1             python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;python-dateutil                        2.9.0.post0       python        (+1 duplicate)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pytz                                   2025.2            python        (+1 duplicate)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyyaml                                 6.0.3             python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;qs                                     6.13.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;quasar                                 2.18.6            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;queue-microtask                        1.2.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;quote                                  1.0.42            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;r-efi                                  5.3.0             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;randombytes                            2.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;range-parser                           1.2.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;raw-body                               2.5.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rawpointer                             0.2.1             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;readable-stream                        2.3.8             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;readable-stream                        3.6.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;readable-stream                        4.7.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;readdir-glob                           1.1.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;readdirp                               3.6.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;readdirp                               4.1.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;redox_syscall                          0.5.18            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;relateurl                              0.2.7             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;require-directory                      2.1.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;resolve-from                           4.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;restore-cursor                         3.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;reusify                                1.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rollup                                 4.53.2            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rollup-plugin-visualizer               5.14.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;run-applescript                        7.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;run-async                              3.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;run-parallel                           1.2.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rustix                                 1.1.2             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rustls-pki-types                       1.13.1            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rxjs                                   7.8.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;safe-buffer                            5.1.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;safe-buffer                            5.2.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;safer-buffer                           2.1.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sass                                   1.93.3            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sass-embedded                          1.93.3            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sass-embedded-all-unknown              1.93.3            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sass-embedded-android-arm              1.93.3            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sass-embedded-android-arm64            1.93.3            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sass-embedded-android-riscv64          1.93.3            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sass-embedded-android-x64              1.93.3            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sass-embedded-darwin-arm64             1.93.3            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sass-embedded-darwin-x64               1.93.3            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sass-embedded-linux-arm                1.93.3            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sass-embedded-linux-arm64              1.93.3            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sass-embedded-linux-musl-arm           1.93.3            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sass-embedded-linux-musl-arm64         1.93.3            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sass-embedded-linux-musl-riscv64       1.93.3            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sass-embedded-linux-musl-x64           1.93.3            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sass-embedded-linux-riscv64            1.93.3            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sass-embedded-linux-x64                1.93.3            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sass-embedded-unknown-all              1.93.3            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sass-embedded-win32-arm64              1.93.3            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sass-embedded-win32-x64                1.93.3            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sax                                    1.1.4             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;schannel                               0.1.28            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;scikit-learn                           1.7.2             python        (+1 duplicate)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;scipy                                  1.16.3            python        (+1 duplicate)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;seaborn                                0.13.2            python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;security-framework                     2.11.1            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;security-framework-sys                 2.15.0            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;selfsigned                             2.4.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;semver                                 7.7.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;send                                   0.19.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;serialize-javascript                   6.0.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;serve-static                           1.16.2            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;setprototypeof                         1.2.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sha2                                   0.10.9            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;shallow-clone                          3.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;shebang-command                        2.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;shebang-regex                          3.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;shlex                                  1.3.0             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;side-channel                           1.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;side-channel-list                      1.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;side-channel-map                       1.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;side-channel-weakmap                   1.0.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;signal-exit                            3.0.7             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;signal-exit                            4.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;simd-adler32                           0.3.7             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;six                                    1.17.0            python        (+1 duplicate)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;skl2onnx                               1.19.1            python        (+1 duplicate)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sky_engine                             3.35.0            dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;smallvec                               2.0.0-alpha.10    rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;socks                                  0.3.4             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;source-map                             0.6.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;source-map                             0.7.6             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;source-map-js                          1.2.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;source-map-support                     0.5.21            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;source_span                            1.10.1            dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;stack-trace                            1.0.0-pre2        npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;stack_trace                            1.12.1            dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;starlette                              0.50.0            python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;statuses                               2.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;stream_channel                         2.1.4             dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;streamx                                2.23.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;string-width                           4.2.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;string-width                           5.1.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;string_decoder                         1.1.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;string_decoder                         1.3.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;string_scanner                         1.4.1             dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;strip-ansi                             6.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;strip-ansi                             7.1.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;strip-json-comments                    3.1.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;supports-color                         7.2.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;supports-color                         8.1.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sympy                                  1.14.0            python        (+1 duplicate)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;syn                                    2.0.111           rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sync-child-process                     1.0.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sync-message-port                      1.1.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;synckit                                0.11.11           npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tar                                    0.4.44            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tar-stream                             3.1.7             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tempfile                               3.23.0            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;term_glyph                             1.2.2             dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;terser                                 5.44.1            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;test_api                               0.7.7             dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;text-decoder                           1.2.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;threadpoolctl                          3.6.0             python        (+1 duplicate)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tiny-invariant                         1.3.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tinyglobby                             0.2.15            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;to-regex-range                         5.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;toidentifier                           1.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tomlkit                                0.13.3            python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tracing                                0.1.43            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tracing-core                           0.1.35            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ts-api-utils                           2.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ts-essentials                          9.4.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tslib                                  2.8.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;type-check                             0.4.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;type-fest                              0.21.3            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;type-fest                              4.41.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;type-is                                1.6.18            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;typenum                                1.19.0            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;typescript                             5.9.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;typescript-eslint                      8.47.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;typing-extensions                      4.15.0            python        (+1 duplicate)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tzdata                                 2025.2            python        (+1 duplicate)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ufo                                    1.6.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;undici-types                           6.21.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;undici-types                           7.16.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;unicode-ident                          1.0.22            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;unicorn-magic                          0.3.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;universalify                           2.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;unpipe                                 1.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;update-browserslist-db                 1.1.4             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ureq                                   3.1.4             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ureq-proto                             0.5.3             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uri-js                                 4.4.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;utf-8                                  0.7.6             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;util-deprecate                         1.0.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;utils-merge                            1.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uvicorn                                0.38.0            python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;varint                                 6.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;vary                                   1.1.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;vcpkg                                  0.2.15            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;vector_math                            2.2.0             dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;version_check                          0.9.5             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;vite                                   7.2.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;vite-plugin-checker                    0.11.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;vm_service                             15.0.2            dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;vscode-uri                             3.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;vue                                    3.5.24            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;vue-eslint-parser                      10.2.0            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;vue-router                             4.6.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;vue-tsc                                3.1.4             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;wasip2                                 1.0.1+wasi-0.2.4  rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;wcwidth                                1.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;web                                    1.1.1             dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;webpack-merge                          6.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;webpki-root-certs                      1.0.4             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;websockets                             15.0.1            python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;which                                  2.0.2             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;wildcard                               2.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;win32-setctime                         1.2.0             python        (+1 duplicate)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;winapi                                 0.3.9             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;winapi-i686-pc-windows-gnu             0.4.0             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;winapi-x86_64-pc-windows-gnu           0.4.0             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;windows-link                           0.2.1             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;windows-sys                            0.60.2            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;windows-sys                            0.61.2            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;windows-targets                        0.53.5            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;windows_aarch64_gnullvm                0.53.1            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;windows_aarch64_msvc                   0.53.1            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;windows_i686_gnu                       0.53.1            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;windows_i686_gnullvm                   0.53.1            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;windows_i686_msvc                      0.53.1            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;windows_x86_64_gnu                     0.53.1            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;windows_x86_64_gnullvm                 0.53.1            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;windows_x86_64_msvc                    0.53.1            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;wit-bindgen                            0.46.0            rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;word-wrap                              1.2.5             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;wrap-ansi                              6.2.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;wrap-ansi                              7.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;wrap-ansi                              8.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;wsl-utils                              0.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;xattr                                  1.6.1             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;xdg_directories                        1.1.0             dart-pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;xml-name-validator                     4.0.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;y18n                                   5.0.8             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;yargs                                  17.7.2            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;yargs-parser                           21.1.1            npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;yocto-queue                            0.1.0             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;yoctocolors-cjs                        2.1.3             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;zeroize                                1.8.2             rust-crate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;zip-stream                             6.0.1             npm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;details&gt;
&lt;p&gt;For Kotlin:&lt;&#x2F;p&gt;
&lt;details&gt;
  &lt;summary&gt;Click to expand&lt;&#x2F;summary&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;toml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-section&quot;&gt;versions&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  agp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;8.13.1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  kotlin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;2.0.21&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  coreKtx&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;1.10.1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  junit&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;4.13.2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  junitVersion&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;1.1.5&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  espressoCore&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;3.5.1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  appcompat&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;1.6.1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  material&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;1.10.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  activity&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;1.8.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  constraintlayout&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;2.1.4&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  onnxruntimeAndroid&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;1.23.2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;details&gt;
&lt;h2 id=&quot;results&quot;&gt;Results&lt;a class=&quot;zola-anchor&quot; href=&quot;#results&quot; aria-label=&quot;Anchor link for: results&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2026&#x2F;01&#x2F;onnx-multi-platform-benchmark&#x2F;.&#x2F;images&#x2F;onnx-multi-platform-full.webp&quot; alt=&quot;onnx-multi-platform-full&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: each platform has its own elbow point (it means when something no longer works, or works but takes a significant performance hit).&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;We can see that on &lt;code&gt;web&lt;&#x2F;code&gt;, onnx takes very long to perform an inference. Additionally, without further optimization, the onnx model size has to be very small (around 30 MB). On web via pc, it takes even longer than android (kotlin). Even onnx on IoT is still faster than web.&lt;&#x2F;p&gt;
&lt;p&gt;On &lt;code&gt;mobile&lt;&#x2F;code&gt; front, &lt;code&gt;flutter&lt;&#x2F;code&gt; takes significantly longer than &lt;code&gt;kotlin&lt;&#x2F;code&gt;. This makes sense because kotlin is &quot;native&quot; but flutter is not.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2026&#x2F;01&#x2F;onnx-multi-platform-benchmark&#x2F;.&#x2F;images&#x2F;onnx-multi-platform-zoom.webp&quot; alt=&quot;onnx-multi-platform-zoom&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Zooming in with &lt;code&gt;python&lt;&#x2F;code&gt;, &lt;code&gt;rust&lt;&#x2F;code&gt;, &lt;code&gt;kotlin&lt;&#x2F;code&gt; (all native runtimes), you can see that even with larger model size, the inference time does not increase significantly (it does use more RAM though). It&#x27;s also very interesting that python on pc has very similar performance to kotlin on android (python is notorious for being slow). On pc, rust is around 2x faster than python, this is to be expected.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;elbow-points&quot;&gt;Elbow Points&lt;a class=&quot;zola-anchor&quot; href=&quot;#elbow-points&quot; aria-label=&quot;Anchor link for: elbow-points&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;&#x2F;th&gt;&lt;th&gt;74 MB&lt;&#x2F;th&gt;&lt;th&gt;227 MB&lt;&#x2F;th&gt;&lt;th&gt;377 MB&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Web&lt;&#x2F;td&gt;&lt;td&gt;🫠&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Kotlin&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;🫠&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Flutter&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;🫠&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;ul&gt;
&lt;li&gt;At &lt;strong&gt;74 MB&lt;&#x2F;strong&gt;, crashes on &lt;code&gt;web&lt;&#x2F;code&gt; - takes 7s to initialize.&lt;&#x2F;li&gt;
&lt;li&gt;At &lt;strong&gt;227 MB&lt;&#x2F;strong&gt;, crashes on &lt;code&gt;android&lt;&#x2F;code&gt; (&lt;code&gt;kotlin&lt;&#x2F;code&gt;). APK takes around 4 minutes to compile.&lt;&#x2F;li&gt;
&lt;li&gt;At &lt;strong&gt;377 MB&lt;&#x2F;strong&gt;, crashes on &lt;code&gt;android&lt;&#x2F;code&gt; (&lt;code&gt;flutter&lt;&#x2F;code&gt;).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;what-does-all-this-mean&quot;&gt;What Does All This Mean?&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-does-all-this-mean&quot; aria-label=&quot;Anchor link for: what-does-all-this-mean&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Mostly there&#x27;s nothing to worry about if you are on pc. If python is too slow, you can use rust. For web, it&#x27;s best for small models because it takes longest to perform an inference. On mobile, you would benefit from using inference accelerators available on ios and android. For IoT go for binary-based solution, and rust is perfect for this.&lt;&#x2F;p&gt;
&lt;p&gt;Note that on web, ios and android, you would really benefit from using accelerators and further inference optimization.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Multi-machine work setup</title>
          <pubDate>Thu, 11 Sep 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2025/09/multi-machine-work-setup/</link>
          <guid>https://karnwong.me/posts/2025/09/multi-machine-work-setup/</guid>
          <description xml:base="https://karnwong.me/posts/2025/09/multi-machine-work-setup/">&lt;p&gt;I have three machines that I use regularly: linux desktop, linux laptop and a macbook. The reason is because the pc is my desk setup, laptop for bedroom, and macbook for when I go out. Having these machines share the same state(ish) would be ideal because the machine switch should be as seamless as possible. I&#x27;ve been rocking this setup for 4+ years, so it&#x27;s been tested in production!&lt;&#x2F;p&gt;
&lt;p&gt;The machine states are broken down into following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;packages&lt;&#x2F;li&gt;
&lt;li&gt;configs&lt;&#x2F;li&gt;
&lt;li&gt;apps&lt;&#x2F;li&gt;
&lt;li&gt;data&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For packages, I use nix for package management (which works for both linux and mac). There are some stuff I install directly via &lt;code&gt;go&lt;&#x2F;code&gt;, &lt;code&gt;cargo&lt;&#x2F;code&gt; and &lt;code&gt;yarn&lt;&#x2F;code&gt;, which is written down as part of my setup script.&lt;&#x2F;p&gt;
&lt;p&gt;Nix can be used with configurations as well. For certain configurations containing secrets, I use sops to decrypt them outside of nix, since on my system they need to exist as plaintext.&lt;&#x2F;p&gt;
&lt;p&gt;For desktop apps, thankfully flatpak works well with linux, and brew for mac.&lt;&#x2F;p&gt;
&lt;p&gt;As for data, specifically non-application data, I use syncthing to sync files between machines. I have a home server with syncthing on it, but you can host it on a VPS as well.&lt;&#x2F;p&gt;
&lt;p&gt;For desktop application data, I start with a single machine, setup all applications, then use restic for backup. On another machine, use restic to restore. Although this setup means you can&#x27;t share the backups between linux and mac.&lt;&#x2F;p&gt;
&lt;p&gt;It probably sounds like a lot of work, but once you set it up you barely have to think about it. If I were to get a brand new machine and have to set it up so I can use it for work, I can do it in 30 minutes with the workflow outlined above.&lt;&#x2F;p&gt;
&lt;p&gt;If you only use a single machine, it&#x27;s probably overkill, but it&#x27;ll be very useful when you have to setup a new machine. Then again, I&#x27;m an ops person, I sleep soundly when I know what my exact configurations are 😪.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Spatial join performance</title>
          <pubDate>Sat, 30 Aug 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2025/08/spatial-join-performance/</link>
          <guid>https://karnwong.me/posts/2025/08/spatial-join-performance/</guid>
          <description xml:base="https://karnwong.me/posts/2025/08/spatial-join-performance/">&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2025&#x2F;08&#x2F;spatial-join-performance&#x2F;images&#x2F;cover.webp&quot; alt=&quot;cover&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In a community I&#x27;m in, someone asked how to optimize a slow spatial join query. There are multiple approaches, but the general idea is to reduce the resulting set (setA would be your &lt;code&gt;polygons&lt;&#x2F;code&gt;, setB would be your &lt;code&gt;points&lt;&#x2F;code&gt;) from a join operation (hello set theory).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;tools-frameworks-used&quot;&gt;Tools &amp;amp; Frameworks Used&lt;a class=&quot;zola-anchor&quot; href=&quot;#tools-frameworks-used&quot; aria-label=&quot;Anchor link for: tools-frameworks-used&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;DataFusion&lt;&#x2F;li&gt;
&lt;li&gt;DuckDB&lt;&#x2F;li&gt;
&lt;li&gt;Pandas (via GeoPandas)&lt;&#x2F;li&gt;
&lt;li&gt;Polars&lt;&#x2F;li&gt;
&lt;li&gt;PostGIS&lt;&#x2F;li&gt;
&lt;li&gt;Spark (via Sedona)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Note that while DuckDB has &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;duckdb.org&#x2F;community_extensions&#x2F;extensions&#x2F;h3.html&quot;&gt;H3 extension&lt;&#x2F;a&gt;, the implementation is still wonky - it doesn&#x27;t always return values.&lt;&#x2F;p&gt;
&lt;p&gt;As for polars, its spatial ecosystem is still in its infancy. Additionally, I&#x2F;O is backed by GeoPandas, which is slower than polars proper, so it can results in parsing bottleneck.&lt;&#x2F;p&gt;
&lt;p&gt;As for DataFusion, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;apache&#x2F;datafusion&#x2F;issues&#x2F;7859&quot;&gt;there is no spatial support yet&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;experiment-design&quot;&gt;Experiment Design&lt;a class=&quot;zola-anchor&quot; href=&quot;#experiment-design&quot; aria-label=&quot;Anchor link for: experiment-design&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;A spatial join operation (point-in-polygon) would be performed via native spatial functions, and via H3 index. Source data is in (geo)parquet, except for PostGIS where data is pre-loaded into a table. Compute is Macbook Pro M3 (16 GB RAM).&lt;&#x2F;p&gt;
&lt;p&gt;H3 index is a spatial index created by Uber. The important thing is that if you utilize H3 index properly, you can perform spatial operations in any languages even when they don&#x27;t support spatial operations.&lt;&#x2F;p&gt;
&lt;p&gt;Specifically for point-in-polygon, you would have two spatial datasets: boundary polygons and points. H3 index for each dataset would be created - in which the &lt;code&gt;boundary dataset&lt;&#x2F;code&gt; would return a &lt;code&gt;set of H3 cell ids&lt;&#x2F;code&gt;, and the &lt;code&gt;points dataset&lt;&#x2F;code&gt; would return a &lt;code&gt;single H3 cell id&lt;&#x2F;code&gt;. Then, it&#x27;s a matter of filtering your dataset after a join to find the intersection.&lt;&#x2F;p&gt;
&lt;p&gt;H3 index has &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;h3geo.org&#x2F;docs&#x2F;core-library&#x2F;restable&#x2F;#hexagon-min-and-max-areas&quot;&gt;multiple levels of resolution&lt;&#x2F;a&gt;. In this experiment, H3 index resolution is set to &lt;code&gt;7&lt;&#x2F;code&gt; (around 5.16 KM&lt;sup&gt;2&lt;&#x2F;sup&gt; area per cell).&lt;&#x2F;p&gt;
&lt;p&gt;Note that for H3 experiment, the cell ids are pre-calculated. This is because generating H3 cell ids is an expensive operation (so far given the size of dataset used, only spark can successfully generate H3 cell ids and not crash in the process).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;results&quot;&gt;Results&lt;a class=&quot;zola-anchor&quot; href=&quot;#results&quot; aria-label=&quot;Anchor link for: results&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2025&#x2F;08&#x2F;spatial-join-performance&#x2F;.&#x2F;images&#x2F;spatial_join_benchmark.webp&quot; alt=&quot;spatial_join_benchmark&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Notice the sharp hikes, it means the performance reaches a bottleneck. Going further would mean exponential runtime.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;native-spatial-join&quot;&gt;Native Spatial Join&lt;a class=&quot;zola-anchor&quot; href=&quot;#native-spatial-join&quot; aria-label=&quot;Anchor link for: native-spatial-join&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;For spatial join, note that pandas at 50k rows results in &lt;code&gt;exit 137&lt;&#x2F;code&gt; error - meaning it ran out of memory.&lt;&#x2F;p&gt;
&lt;p&gt;DuckDB and PostGIS have very similar performance, but PostGIS is slightly faster. However, factoring in data loading into PostGIS would mean it&#x27;s not as economical compared to using DuckDB, which can read data from files on-the-fly. Computation-wise, they are the most performant.&lt;&#x2F;p&gt;
&lt;p&gt;Spark elbows at 50k rows, which means the underlying spatial engine (sedona) is not as optimized for spatial operations. Further data prep and pre-processing is required to optimize the performance.&lt;&#x2F;p&gt;
&lt;p&gt;Geopandas has similar performance to spark, but at 50k rows it ran out of memory, whereas spark is still manageable.&lt;&#x2F;p&gt;
&lt;p&gt;For all native spatial join operations, no frameworks can process further than 5 million rows without running into memory issues.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;h3&quot;&gt;H3&lt;a class=&quot;zola-anchor&quot; href=&quot;#h3&quot; aria-label=&quot;Anchor link for: h3&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Note that the join operation is not a cross join, rather it&#x27;s a normal join where &lt;code&gt;a=b&lt;&#x2F;code&gt;. Specifically, boundary dataset containing H3 cell ids column is exploded into multiple rows, one for each cell id.&lt;&#x2F;p&gt;
&lt;p&gt;This method can process up to 50 million rows, albeit with slightly less accuracy due to the nature of H3 index. Then again, in big data world, you might need to sacrifice accuracy for performance.&lt;&#x2F;p&gt;
&lt;p&gt;But pandas being pandas, it can&#x27;t process further than 5 million rows.&lt;&#x2F;p&gt;
&lt;p&gt;DuckDB is faster than polars, but this is because there is no calculation or aggregation done at runtime, in which polars would be more efficient if it&#x27;s were the case. Surprisingly, DuckDB is the fastest, surpassing even DataFusion (which is written in Rust).&lt;&#x2F;p&gt;
&lt;p&gt;What really surprised me is that spark is faster than polars and DataFusion. Which is to say given certain scale things might turn around.&lt;&#x2F;p&gt;
&lt;p&gt;In all, DuckDB and spark are the fastest. Slightly slower are polars and DataFusion, both are Rust-based. Whereas pandas is slowest - processing 5 million rows in pandas takes about the same time as processing 10 million rows in polars.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;a class=&quot;zola-anchor&quot; href=&quot;#conclusion&quot; aria-label=&quot;Anchor link for: conclusion&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;If you have a small dataset, any method should work, bonus if your framework supports spatial operations. However, at more than 10k rows, you can get by with DuckDB up until 1 million rows, which then it would be hard to scale.&lt;&#x2F;p&gt;
&lt;p&gt;At this point, utilizing H3 index would be more economical, even pandas can process up to 10 million rows. But more than that spark would scale best, since it is a distributed engine. While DataFusion has Ballista, it is still quite tricky to get it up and running, in which your engineering time is better spent on something else.&lt;&#x2F;p&gt;
&lt;p&gt;However, you still need to somehow pre-calculate the H3 index. Given a large dataset and H3 support, only spark fits the bill. At the end of day, you still need spark.&lt;&#x2F;p&gt;
&lt;p&gt;But you can also use Snowflake or something else that has H3 support to pre-calculate the H3 index, but then it would be best if you use your data warehouse to perform spatial join, since this means you don&#x27;t have to move data around.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Static lib linking in Go program</title>
          <pubDate>Tue, 26 Aug 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2025/08/static-lib-linking-in-go-program/</link>
          <guid>https://karnwong.me/posts/2025/08/static-lib-linking-in-go-program/</guid>
          <description xml:base="https://karnwong.me/posts/2025/08/static-lib-linking-in-go-program/">&lt;h2 id=&quot;background&quot;&gt;Background&lt;a class=&quot;zola-anchor&quot; href=&quot;#background&quot; aria-label=&quot;Anchor link for: background&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;I have a Go program for various utilities. Some of the features talk to hardware: &lt;code&gt;sensors&lt;&#x2F;code&gt; and &lt;code&gt;battery statistics&lt;&#x2F;code&gt;. For funsies, I ported this program into Rust because I want to get a feel of the language outside the data&#x2F;ml ecosystem. To my surprise, I found that Rust&#x27;s implementation of these features have better hardware coverage. Specifically, in Go it couldn&#x27;t get sensors info on some hardware, and battery cycle count isn&#x27;t available in Go at all.&lt;&#x2F;p&gt;
&lt;p&gt;I like Rust, but I find Go has better TUI ecosystem. As to not shoot my future-self in the foot, utilizing FFI might be more ideal.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-it-works&quot;&gt;How it works&lt;a class=&quot;zola-anchor&quot; href=&quot;#how-it-works&quot; aria-label=&quot;Anchor link for: how-it-works&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Basically you have to use Rust to build a static library, then import it into Go. Finally, bundle this static lib into a Go binary.&lt;&#x2F;p&gt;
&lt;p&gt;Note that you have to expose the Rust functions for C, and you also need to provide a C header file.&lt;&#x2F;p&gt;
&lt;p&gt;Regarding static vs dynamic library: you probably have an easier time linking a dynamic binary, but it&#x27;s more headaches if you want to distribute a plain binary. This is because for dynamic library, the library itself has to be present somewhere on your system so the Go binary can load external library at runtime.&lt;&#x2F;p&gt;
&lt;p&gt;Since a binary is OS&#x2F;arch dependent, so is static library. This is where the fun starts. Good news is you can use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cross-rs&#x2F;cross&quot;&gt;cross&lt;&#x2F;a&gt; to cross-compile Rust crates, but this doesn&#x27;t apply to actually linking the static lib into Go binary.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cgo-import&quot;&gt;CGO import&lt;a class=&quot;zola-anchor&quot; href=&quot;#cgo-import&quot; aria-label=&quot;Anchor link for: cgo-import&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;In Go, you need to set CGO import:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#cgo linux LDFLAGS: .&#x2F;lib&#x2F;libsystem.a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#cgo darwin LDFLAGS: .&#x2F;lib&#x2F;libsystem.a -framework IOKit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#cgo windows LDFLAGS: .&#x2F;lib&#x2F;libsystem.a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#include &amp;quot;..&#x2F;..&#x2F;lib&#x2F;system.h&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Notice that you probably need different configurations for each OS. Notice that for &lt;code&gt;darwin&lt;&#x2F;code&gt;, &lt;code&gt;framework&lt;&#x2F;code&gt; is required since it&#x27;s MacOS specific. I got the error during build and it pointed me to which framework to specify for &lt;code&gt;LDFLAGS&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;go-build-configurations&quot;&gt;Go build configurations&lt;a class=&quot;zola-anchor&quot; href=&quot;#go-build-configurations&quot; aria-label=&quot;Anchor link for: go-build-configurations&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;You also need to set the right combination for &lt;code&gt;C Compiler&lt;&#x2F;code&gt; and &lt;code&gt;LDFLAGS&lt;&#x2F;code&gt;, in which it is as follows:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;OS&lt;&#x2F;th&gt;&lt;th&gt;Arch&lt;&#x2F;th&gt;&lt;th&gt;CC&lt;&#x2F;th&gt;&lt;th&gt;LDFLAGS&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;linux&lt;&#x2F;td&gt;&lt;td&gt;amd64&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;-linkmode &#x27;external&#x27; -extldflags &#x27;-static&#x27;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;linux&lt;&#x2F;td&gt;&lt;td&gt;arm64&lt;&#x2F;td&gt;&lt;td&gt;aarch64-linux-gnu-gcc&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;-linkmode &#x27;external&#x27; -extldflags &#x27;-static&#x27;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;darwin&lt;&#x2F;td&gt;&lt;td&gt;amd64&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;-linkmode &#x27;external&#x27;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;darwin&lt;&#x2F;td&gt;&lt;td&gt;arm64&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;-linkmode &#x27;external&#x27;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;windows&lt;&#x2F;td&gt;&lt;td&gt;amd64&lt;&#x2F;td&gt;&lt;td&gt;x86_64-w64-mingw32-gcc&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;-linkmode &#x27;external&#x27; -extldflags &#x27;-static -lntdll -lsetupapi&#x27;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Notice the &lt;code&gt;lntdll&lt;&#x2F;code&gt; flag for &lt;code&gt;windows&lt;&#x2F;code&gt;, during initial binary build I didn&#x27;t add this and it throws an error, pointing me to add this flag for compilation.&lt;&#x2F;p&gt;
&lt;p&gt;Note that linux can cross-compile for windows, but darwin needs a MacOS machine.&lt;&#x2F;p&gt;
&lt;p&gt;Also it might throw an error about recommending &lt;code&gt;musl&lt;&#x2F;code&gt;. Because &lt;code&gt;gcc-aarch64-linux-gnu&lt;&#x2F;code&gt; and &lt;code&gt;gcc-mingw-w64-x86-64&lt;&#x2F;code&gt; depend on &lt;code&gt;glibc&lt;&#x2F;code&gt;. To fix this error, you have to use a musl-based C Compiler instead. But this entirely depends on whether your static library talks to &lt;code&gt;glibc&lt;&#x2F;code&gt; or not, you don&#x27;t have much say in this.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ci-cd&quot;&gt;CI&#x2F;CD&lt;a class=&quot;zola-anchor&quot; href=&quot;#ci-cd&quot; aria-label=&quot;Anchor link for: ci-cd&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;You should utilize a matrix strategy to fan out the build jobs, and don&#x27;t forget to install the C Compiler and Rust target for the correct target OS&#x2F;arch combination.&lt;&#x2F;p&gt;
&lt;p&gt;Relevant snippets:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; I&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;nstall cross-compilers&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  r&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;un&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    if [ &amp;quot;${{ matrix.os }}&amp;quot; == &amp;quot;linux&amp;quot; ]; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;      sudo apt-get install gcc-aarch64-linux-gnu&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    elif [ &amp;quot;${{ matrix.os }}&amp;quot; == &amp;quot;windows&amp;quot; ]; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;      sudo apt-get install gcc-mingw-w64-x86-64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; A&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;dd Rust targets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  r&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;un&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    if [ &amp;quot;${{ matrix.os }}&amp;quot; == &amp;quot;darwin&amp;quot; ]; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;      rustup target add x86_64-apple-darwin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;      rustup target add aarch64-apple-darwin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    elif [ &amp;quot;${{ matrix.os }}&amp;quot; == &amp;quot;windows&amp;quot; ]; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;      rustup target add x86_64-pc-windows-gnu&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</description>
      </item>
      <item>
          <title>AWS cost optimization tactics</title>
          <pubDate>Mon, 04 Aug 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2025/08/aws-cost-optimization-tactics/</link>
          <guid>https://karnwong.me/posts/2025/08/aws-cost-optimization-tactics/</guid>
          <description xml:base="https://karnwong.me/posts/2025/08/aws-cost-optimization-tactics/">&lt;p&gt;Imagine working on a product and you finally released it to the public. Things are going great for you, then your budget got out of control and you have to tame the spending. Below are a few tactics you can utilize to curb the costs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cronjobs-ecs-tasks-on-fargate&quot;&gt;Cronjobs -&amp;gt; ECS Tasks on Fargate&lt;a class=&quot;zola-anchor&quot; href=&quot;#cronjobs-ecs-tasks-on-fargate&quot; aria-label=&quot;Anchor link for: cronjobs-ecs-tasks-on-fargate&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Cronjobs mean you need to have an EC2 (vm) running all day and night. Even if your cronjobs only get triggered for an hour late at night, you still need to setup a vm start&#x2F;stop schedule (read: more setup effort), in which you have to make sure that it starts &lt;em&gt;before&lt;&#x2F;em&gt; your cron schedules, and shuts down &lt;em&gt;after&lt;&#x2F;em&gt; your cronjobs run successfully. It&#x27;s a lot of time logistics involved, and if the time window the EC2 stays up is too tight some of your jobs might not run.&lt;&#x2F;p&gt;
&lt;p&gt;ECS tasks is a way for you to fire up container-based jobs, it only charges you for the amount of time the tasks take to complete. You don&#x27;t need to provision a vm, because ECS on fargate is serverless. You can even make it cheaper by using fargate spot! (But don&#x27;t forget to setup retries because sometimes a spot job could fail due to unavailable spot capacity).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ecs-on-fargate-ecs-on-ec2&quot;&gt;ECS on Fargate -&amp;gt; ECS on EC2&lt;a class=&quot;zola-anchor&quot; href=&quot;#ecs-on-fargate-ecs-on-ec2&quot; aria-label=&quot;Anchor link for: ecs-on-fargate-ecs-on-ec2&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;If your workloads are very predictable - i.e. predictable spikes, you might want to consider using EC2-backed ECS. This is because in lieu of using fargate for compute backend (which has a higher price-point per compute-second), you can provision EC2 yourself as ECS backend. You can make it even cheaper by buying reserved instance.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;for-not-always-on-workloads&quot;&gt;For Not-Always-On Workloads&lt;a class=&quot;zola-anchor&quot; href=&quot;#for-not-always-on-workloads&quot; aria-label=&quot;Anchor link for: for-not-always-on-workloads&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;You have a few approaches here. You can use ECS on fargate and setup a schedule for workload activation&#x2F;deactivation. Let&#x27;s say if your workload needs to be active during work hours, but is idle at night, this would work perfectly.&lt;&#x2F;p&gt;
&lt;p&gt;Alternatively, if it&#x27;s a very small workload - let&#x27;s say half a dozen functions, it could be converted into Lambdas, which has an added benefit that it can scale to zero. This means it only charges you when it receives incoming requests.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bonus-what-s-up-with-using-ec2&quot;&gt;Bonus: What&#x27;s up with using EC2&lt;a class=&quot;zola-anchor&quot; href=&quot;#bonus-what-s-up-with-using-ec2&quot; aria-label=&quot;Anchor link for: bonus-what-s-up-with-using-ec2&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;If you want to get something up and running real quick, EC2 is a fine solution. It&#x27;s what everyone is familiar with, same steps as when you were to work on your local workstation.&lt;&#x2F;p&gt;
&lt;p&gt;However, at certain point in time, you would eventually run out of disk space - and you have to set up a disk monitoring and cleanup job.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, you have to perform OS upgrades as well, and things might go wrong, but you&#x27;ll never know until you perform the upgrade. Yes, this sounds like Russian roulette.&lt;&#x2F;p&gt;
&lt;p&gt;And the worst of all is there&#x27;s no clean way for you to read your workloads&#x27; logs without SSH-ing into the vm. Or you have to forward your logs to an external service, but then you have to set it up, which is more work.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Terraform project structure</title>
          <pubDate>Tue, 22 Jul 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2025/07/terraform-project-structure/</link>
          <guid>https://karnwong.me/posts/2025/07/terraform-project-structure/</guid>
          <description xml:base="https://karnwong.me/posts/2025/07/terraform-project-structure/">&lt;p&gt;Recently I gave a terraform talk, and people ask how to get started with terraform. The simple answer is to try to get your hands dirty with it, but at certain point you have to learn how to &quot;manage&quot; the ever-growing terraform project.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;single-project-structure&quot;&gt;Single-project structure&lt;a class=&quot;zola-anchor&quot; href=&quot;#single-project-structure&quot; aria-label=&quot;Anchor link for: single-project-structure&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;In the beginning, you can probably make do with a single terraform workspace containing all resources. A single terraform project can look like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;├──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; backend.tf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;├──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; main.tf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;├──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; outputs.tf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;├──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; providers.tf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;├──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; terraform.tf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;└──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; variables.tf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;code&gt;backend.tf&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is where you store your terraform state.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;hcl&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;terraform&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  backend&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;gcs&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    bucket&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;xxx&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    prefix&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;terraform&#x2F;xxx&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;code&gt;main.tf&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Your terraform resources should be defined here. You can split it into multiple files for each resource&#x2F;service group.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;hcl&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;google_cloud_run_v2_job&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;this&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; define your resource here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;code&gt;outputs.tf&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Anything you want to export stays here.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;hcl&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;output&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;foo&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;xxx&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;code&gt;providers.tf&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is where you define required terraform providers. You probably have to supply required values to authenticate to services.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;hcl&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;provider&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;google&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  project&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;project_id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  region&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;region&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;provider&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;sops&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;code&gt;terraform.tf&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This file is equivalent to your project&#x27;s dependencies - what your project requires to successfully create and modify resources.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;hcl&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;terraform&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  required_providers&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    github&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;      source&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;integrations&#x2F;github&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;      version&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;6.2.1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    google&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;      source&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;hashicorp&#x2F;google&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;      version&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;5.23.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    random&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;      source&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;hashicorp&#x2F;random&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;      version&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;3.5.1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    sops&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;      source&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;carlpett&#x2F;sops&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;      version&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;1.0.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;code&gt;variables.tf&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Anything specific to your setup and can be changed should be defined as variables.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;hcl&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;variable&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;project_id&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;    =&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; string&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  default&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;xxx&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;variable&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;region&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  description&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;The region of resources&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;        =&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; string&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  default&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;     =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;asia-southeast1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Sometimes the variables contain secrets, in which case you might want to create a separate &lt;code&gt;terraform.tfvars&lt;&#x2F;code&gt; and specify your values there. Don&#x27;t check this file into git.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;terraform.tfvars&lt;&#x2F;code&gt; should look like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;hcl&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;foo&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bar&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;multi-project-structure&quot;&gt;Multi-project structure&lt;a class=&quot;zola-anchor&quot; href=&quot;#multi-project-structure&quot; aria-label=&quot;Anchor link for: multi-project-structure&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Over time your terraform project can contain more resources - taking longer and longer to &lt;code&gt;terraform plan&lt;&#x2F;code&gt; and &lt;code&gt;terraform apply&lt;&#x2F;code&gt;. If you start experiencing this, it is probably time to split your current project into multiple projects. There are plenty of resources online for this, but I would suggest you to practice it before splitting your production project, as refactoring a terraform project is a very delicate process.&lt;&#x2F;p&gt;
&lt;p&gt;Over the years I have experimented with a lot of terraform project structure, since I had to maintain all infrastructure in an organization, spanning all products they have. Following structure has been serving me well:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;└──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; environments&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    ├──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; core&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   ├──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; gcp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   ├──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; logging&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   └──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; networking&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   └──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; github&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    ├──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; dev&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   ├──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; aws&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   ├──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; productA&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   └──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; productB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   └──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; gcp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;       ├──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; productC&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;       └──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; productD&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    ├──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; non-prod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   ├──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; aws&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   ├──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; playgroundA&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   └──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; playgroundB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   └──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; gcp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;       ├──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; sandboxA&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;       └──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; sandboxB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    └──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; prod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;        ├──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; aws&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;        │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   ├──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; productA&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;        │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   └──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; productB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;        └──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; gcp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;            ├──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; productC&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;            └──&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; productD&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Essentially, you separate the root level by environments. Under each environment, separate each infrastructure&#x2F;service vendor. Finally, group terraform resources by product&#x2F;project.&lt;&#x2F;p&gt;
&lt;p&gt;You&#x27;ll notice that for core infrastructure it has its own &lt;code&gt;core&lt;&#x2F;code&gt; environment, because it is shared between almost all environments (for instance, shared logging sink for all environments).&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>The true cost of deploying on EC2</title>
          <pubDate>Fri, 18 Jul 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2025/07/the-true-cost-of-deploying-on-ec2/</link>
          <guid>https://karnwong.me/posts/2025/07/the-true-cost-of-deploying-on-ec2/</guid>
          <description xml:base="https://karnwong.me/posts/2025/07/the-true-cost-of-deploying-on-ec2/">&lt;p&gt;Naturally, when you are working on a project, be it python, go, rust, you would write code and make sure it works as expected. For deployments, packaging your project into a docker image and deploy it as a container would guarantee that it would work the same regardless of which machine it&#x27;s running on.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;initial-deployment&quot;&gt;Initial deployment&lt;a class=&quot;zola-anchor&quot; href=&quot;#initial-deployment&quot; aria-label=&quot;Anchor link for: initial-deployment&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;It would be understandable for people to think &quot;I need a VM to deploy my stuff,&quot; since it uses the same setup as their development workflow. It would go like this:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Spin up a VM&lt;&#x2F;li&gt;
&lt;li&gt;Install docker&lt;&#x2F;li&gt;
&lt;li&gt;Clone source repository&lt;&#x2F;li&gt;
&lt;li&gt;Run &lt;code&gt;docker build&lt;&#x2F;code&gt; command&lt;&#x2F;li&gt;
&lt;li&gt;Run &lt;code&gt;docker run&lt;&#x2F;code&gt; or &lt;code&gt;docker compose up&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;For simplicity, let&#x27;s assume there is no databases involved. At this point an app would run normally, however you wouldn&#x27;t be able to access your service, because you haven&#x27;t set up ingress rules. To do that, you would need to fiddle with vpc and security groups attached to your ec2. If done correctly, you should be able to access your service with &lt;code&gt;http:&#x2F;&#x2F;${EC2_PUBLIC_IP}:${SERVICE_PORT}&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Note that, if you stop your ec2 instance and restart, your ec2 would get a new IP address on reboot, which means you have to change the IP you use to access your service. If you want to map your service to a domain, this would pose an issue because the IP would keep changing, rendering your A record unresolvable. To fix this, you need to reserve an ip (elastic ip on aws) and assign it to your ec2.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ssl-strikes-back&quot;&gt;SSL strikes back&lt;a class=&quot;zola-anchor&quot; href=&quot;#ssl-strikes-back&quot; aria-label=&quot;Anchor link for: ssl-strikes-back&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Keen readers would realize that it&#x27;s &lt;code&gt;http&lt;&#x2F;code&gt;, which is not ideal because there would be no encryption when you are interacting with this service. To solve this, you need to put a reverse proxy in front of your service. You can achieve this in two ways:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Add apache2, nginx or caddy in front of your service. This can run as another container on ec2, or as systemd.&lt;&#x2F;li&gt;
&lt;li&gt;Create AWS Load Balancer and use ec2 as backend. You also have to generate a certificate via AWS (or you can import it) and attach to your load balancer as well.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;You probably don&#x27;t need a dedicated load balancer for a small project, but at certain scale it would be helpful when you have a lot of incoming requests, because an LB can distribute loads (assuming you point it to a fleet of ec2 serving up the same service), in turn allowing you to scale out your service.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-about-ci-cd&quot;&gt;What about CI&#x2F;CD&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-about-ci-cd&quot; aria-label=&quot;Anchor link for: what-about-ci-cd&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Manual setup would be for every code changes, you ssh into your ec2, do a &lt;code&gt;git pull&lt;&#x2F;code&gt; and &lt;code&gt;docker build&lt;&#x2F;code&gt; and &lt;code&gt;docker compose down &amp;amp;&amp;amp; docker compose up&lt;&#x2F;code&gt;. If you think this is very tedious, that&#x27;s because it is.&lt;&#x2F;p&gt;
&lt;p&gt;You have a few possible approaches to achieve ci&#x2F;cd:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Set up a cronjob to periodically pull your repo and update running image -&amp;gt; has downtime
&lt;ul&gt;
&lt;li&gt;Alternatively, you can replace a cronjob by using a ci&#x2F;cd system to ssh into ec2 and run the same commands&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Use ci&#x2F;cd system to build and push docker image to aws ecr, then set up a cronjob to periodically update running image -&amp;gt; you need to setup aws iam so your ec2 can pull from a private ecr repo, and this still involves downtime&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Both solutions still results in a downtime, in which if this is not acceptable for your application, keep reading...&lt;&#x2F;p&gt;
&lt;h2 id=&quot;containers-as-a-service&quot;&gt;Containers as a service&lt;a class=&quot;zola-anchor&quot; href=&quot;#containers-as-a-service&quot; aria-label=&quot;Anchor link for: containers-as-a-service&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;At this point you can probably tell that deploying to ec2 is simple, unless it involves ci&#x2F;cd. But since you are using containers, aws has ecs where you can spin up a deployment from a supplied ecr image. Alternatively, you can also use eks, but if you only have a single service, eks is an overkill.&lt;&#x2F;p&gt;
&lt;p&gt;For ci&#x2F;cd, it&#x27;s as simple as build and push image to ecr, update your ecs deployment manifest and update it - all can be done via cli commands, as long as you supply the correct aws iam credentials.&lt;&#x2F;p&gt;
&lt;p&gt;You still need to create a load balancer, because an ecs deployment update works on a rolling basis - a new deployment spins up and if it doesn&#x27;t fail, only then the load balancer would switch traffic to this new deployment, then tear down the previous revision. This translates to no downtime.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;using-ec2-but-with-a-twist&quot;&gt;Using EC2 but with a twist&lt;a class=&quot;zola-anchor&quot; href=&quot;#using-ec2-but-with-a-twist&quot; aria-label=&quot;Anchor link for: using-ec2-but-with-a-twist&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;The good thing about aws ecs is that you can use ec2 as backend as well, in some cases it might be cheaper than the default backend (fargate - which is serverless). Essentially you add containers orchestration on top of ec2.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;While deploying on ec2 is simple at a glance, it introduces a lot of issues, namely unavoidable downtime and complex ci&#x2F;cd setup. By using containers-as-a-service, ci&#x2F;cd can be easier to achieve, and rolling update would be introduced to avoid service downtime during upgrades.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Dataframe processing benchmarks (ภาษาไทย)</title>
          <pubDate>Tue, 08 Jul 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2025/07/dataframe-processing-benchmarks-th/</link>
          <guid>https://karnwong.me/posts/2025/07/dataframe-processing-benchmarks-th/</guid>
          <description xml:base="https://karnwong.me/posts/2025/07/dataframe-processing-benchmarks-th/">&lt;h4 id=&quot;english&quot;&gt;&lt;a href=&quot;&#x2F;posts&#x2F;2025&#x2F;07&#x2F;dataframe-processing-benchmarks&quot;&gt;English&lt;&#x2F;a&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#english&quot; aria-label=&quot;Anchor link for: english&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2025&#x2F;07&#x2F;dataframe-processing-benchmarks-th&#x2F;images&#x2F;cover.webp&quot; alt=&quot;cover&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;ช่วงหลังๆ มานี้ &lt;code&gt;duckdb&lt;&#x2F;code&gt; กับ &lt;code&gt;polars&lt;&#x2F;code&gt; มาแรงขึ้นเรื่อยๆ พ่วงมากับการที่ &lt;code&gt;parquet&lt;&#x2F;code&gt; เป็นที่นิยมมากขึ้นในการใช้เก็บข้อมูล เลยว่าเป็นฤกษ์ดีในการมาดู ว่า data format กับ framework จะมีผลกับความไวในการปั่นข้อมูลขนาดไหน&lt;&#x2F;p&gt;
&lt;h2 id=&quot;processing-1-million-rows&quot;&gt;Processing 1 Million Rows&lt;a class=&quot;zola-anchor&quot; href=&quot;#processing-1-million-rows&quot; aria-label=&quot;Anchor link for: processing-1-million-rows&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2025&#x2F;07&#x2F;dataframe-processing-benchmarks-th&#x2F;images&#x2F;01-1m-transformation.webp&quot; alt=&quot;1m-transformation&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;สำหรับการ transform ข้อมูลแบบง่ายๆ (colNew = colA&#x2F;colB) ค่อนข้างชัดว่า ถ้าอ่านเป็น parquet จะใช้เวลาน้อยสุดในการปั่น&lt;&#x2F;p&gt;
&lt;p&gt;ถ้าเป็น ndjson หรือที่เรียกกันอีกชื่อว่า single-line json ส่วนมากจะโผล่มาสองแบบ: แบบ plaintext กับแบบที่เอาไปห่อไว้ใน gzip อีกที ตอนที่เขียนบทความนี้ polars ยังไม่สามารถอ่าน gzipped ndjson ตรงๆ ได้ แต่ duckdb ทำได้ ซึ่งก็ค่อนข้างเห็นได้ชัดว่าถ้าให้ duckdb ไปอ่าน gzipped ndjson จะใช้เวลานานกว่าถ้าเทียบกับการอ่าน plaintext ndjson แบบปกติ&lt;&#x2F;p&gt;
&lt;p&gt;แต่ก็ไม่แปลกใจที่ pandas จะใช้เวลานานสุดถ้าต้องอ่าน ndjson&lt;&#x2F;p&gt;
&lt;p&gt;มวยอ่านข้อมูล 1 ล้านแถว ถ้าเทียบกันยังไง polars ก็ไวกว่า duckdb แต่ถ้าเป็น parquet ก็จะสูสีกันหน่อย&lt;&#x2F;p&gt;
&lt;p&gt;สำหรับการใช้ python แบบไม่ผ่าน framework ปั่นข้อมูล ก็ถือว่าใช้เวลานานสุด เป็น for-loop ธรรมดาที่ต่อจาก &lt;code&gt;readlines&lt;&#x2F;code&gt; stream อีกที จริงๆ ไม่ค่อยแนะนำให้ใช้ for-loop แต่ก็เคยเห็นใน production อยู่ อยากแนะนำให้เปลี่ยนไปใช้ dataframe framework ตัวไหนก็ได้ที่สะดวก เพราะว่ามันจะเป็นระเบิดเวลา จะมีโอกาสพังเยอะ จนถึงตอนนั้น pipelines พังไม่ค่อยน่ากลัวเท่า data types พังแล้วต้องไปไล่ซ่อม&lt;&#x2F;p&gt;
&lt;p&gt;แต่ก็น่าสนใจตรงที่ ถ้าจับ pandas มาอ่าน parquet ก็ลดเวลาปั่นไปได้เยอะ ก็คือถ้าจำเป็นต้องใช้ pandas แล้วเลี่ยงไม่ได้ การอ่านไฟล์ต้นทางเป็น parquet จะช่วยได้ในเรื่องของความเร็วในการทำงาน แต่ถึงจุดนึงย้ายไปใช้ polars&#x2F;duckdb&#x2F;spark จะยั่งยืนกว่าในระยะยาว&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2025&#x2F;07&#x2F;dataframe-processing-benchmarks-th&#x2F;images&#x2F;02-1m-window-groupby.webp&quot; alt=&quot;1m-window-groupby&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;ในส่วนของการทำ window+groupby หนักๆ สำหรับ 1 ล้านแถว ความเร็วไม่ค่อยต่างกันมาก แต่ polars จะไวกว่านิดหน่อย&lt;&#x2F;p&gt;
&lt;p&gt;เอาล่ะ ได้เวลาเร่งเครื่อง...&lt;&#x2F;p&gt;
&lt;h2 id=&quot;processing-50-million-rows&quot;&gt;Processing 50 Million Rows&lt;a class=&quot;zola-anchor&quot; href=&quot;#processing-50-million-rows&quot; aria-label=&quot;Anchor link for: processing-50-million-rows&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2025&#x2F;07&#x2F;dataframe-processing-benchmarks-th&#x2F;images&#x2F;03-50m-transformation.webp&quot; alt=&quot;50m-transformation&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;ณ จุดนี้ pandas อ่าน ndjson 50 ล้านแถวไม่รอด แต่น่าสนใจตรงที่ polars ใช้เวลานานกว่าถ้าเทียบกับ duckdb ในการอ่านไฟล์จากทั้ง ndjson และ parquet&lt;&#x2F;p&gt;
&lt;p&gt;ที่เด่นจริงๆ คือ การที่ไฟล์ต้นทางเป็น parquet ทำให้ duckdb ใช้เวลาไวขึ้น 6x ถ้าเทียบกับอ่านจาก ndjson สำหรับ polars เอง การอ่านไฟล์เข้ามาจาก parquet ก็ทำให้ปั่นไวขึ้น 3x เทียบกัน ndjson&lt;&#x2F;p&gt;
&lt;p&gt;แต่ยังไม่จบ เพราะว่า ถ้าไปมวยต่อไป คือ window+groupby:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2025&#x2F;07&#x2F;dataframe-processing-benchmarks-th&#x2F;images&#x2F;04-50m-window-groupby.webp&quot; alt=&quot;50m-window-groupby&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;polars ไวกว่า duckdb&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;คนเขาบอกว่า duckdb ไวกว่า polars ก็จริง แต่ขั้วตรงข้ามที่บอกว่า polars ไวกว่า duckdb ก็จริง&lt;&#x2F;p&gt;
&lt;p&gt;ถ้าเทียบกันกับจำนวนแถวที่ต้องปั่นและท่าละเลงข้อมูล ถ้าเป็นอะไรง่ายๆ duckdb จะไวกว่า polars ก็คือถ้ามี 50 ล้านแถว duckdb จะไวกว่า polars สองเท่า&lt;&#x2F;p&gt;
&lt;p&gt;แต่ถ้าละเลงหนักๆ แบบมาทั้ง window + groupby จะเป็น polars ไวกว่า duckdb&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Dataframe processing benchmarks</title>
          <pubDate>Tue, 08 Jul 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2025/07/dataframe-processing-benchmarks/</link>
          <guid>https://karnwong.me/posts/2025/07/dataframe-processing-benchmarks/</guid>
          <description xml:base="https://karnwong.me/posts/2025/07/dataframe-processing-benchmarks/">&lt;h4 id=&quot;phaasaaaithy&quot;&gt;&lt;a href=&quot;&#x2F;posts&#x2F;2025&#x2F;07&#x2F;dataframe-processing-benchmarks-th&quot;&gt;ภาษาไทย&lt;&#x2F;a&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#phaasaaaithy&quot; aria-label=&quot;Anchor link for: phaasaaaithy&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2025&#x2F;07&#x2F;dataframe-processing-benchmarks&#x2F;images&#x2F;cover.webp&quot; alt=&quot;cover&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Given the rise of &lt;code&gt;duckdb&lt;&#x2F;code&gt; and &lt;code&gt;polars&lt;&#x2F;code&gt; in recent years, in addition to &lt;code&gt;parquet&lt;&#x2F;code&gt; format being more widely adopted for data storage format, it might be a good time to see how source data format affects data processing speed - in addition to the framework choice.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;processing-1-million-rows&quot;&gt;Processing 1 Million Rows&lt;a class=&quot;zola-anchor&quot; href=&quot;#processing-1-million-rows&quot; aria-label=&quot;Anchor link for: processing-1-million-rows&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2025&#x2F;07&#x2F;dataframe-processing-benchmarks&#x2F;images&#x2F;01-1m-transformation.webp&quot; alt=&quot;1m-transformation&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For a simple transformation (colNew = colA&#x2F;colB), it is obvious that when source format is parquet, it takes the least time to process the data.&lt;&#x2F;p&gt;
&lt;p&gt;With ndjson, also known as single-line json, it usually comes into two variants: uncompressed and compressed. At the time of writing this article, polars can&#x27;t read gzipped ndjson directly, but duckdb can. It&#x27;s evident that by processing gzipped ndjson, it takes a lot more time compared to uncompressed ndjson for duckdb.&lt;&#x2F;p&gt;
&lt;p&gt;Unsurprisingly, pandas takes significantly longer than duckdb and polars when it comes to reading ndjson.&lt;&#x2F;p&gt;
&lt;p&gt;However, it should be of note that given 1 million rows, polars is faster than duckdb when it comes to parsing ndjson, but for parquet, it&#x27;s almost a tie.&lt;&#x2F;p&gt;
&lt;p&gt;As for pure python for comparison - which took longest to execute, it&#x27;s running a simple for-loop for a &lt;code&gt;readlines&lt;&#x2F;code&gt; stream. I wouldn&#x27;t recommend using a for-loop for processing data, but I&#x27;ve seen a few in production - in which I would recommend you to migrate to polars or whichever dataframe framework you prefer as soon as possible, because it&#x27;s a ticking time bomb for all things that could go wrong - and failing pipelines would be the least of your worries. Hint: the revenge of data types.&lt;&#x2F;p&gt;
&lt;p&gt;Interestingly enough, reading parquet via pandas results in significantly faster processing speed, so if you really need to use pandas, working with parquet can improve execution performance - but at certain point migrating off to polars&#x2F;duckdb&#x2F;spark might be better in the long run.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2025&#x2F;07&#x2F;dataframe-processing-benchmarks&#x2F;images&#x2F;02-1m-window-groupby.webp&quot; alt=&quot;1m-window-groupby&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As for a window+groupby aggregation, at 1 million rows, it&#x27;s almost a tie, but polars takes slightly less time.&lt;&#x2F;p&gt;
&lt;p&gt;Now, to crank it up a notch...&lt;&#x2F;p&gt;
&lt;h2 id=&quot;processing-50-million-rows&quot;&gt;Processing 50 Million Rows&lt;a class=&quot;zola-anchor&quot; href=&quot;#processing-50-million-rows&quot; aria-label=&quot;Anchor link for: processing-50-million-rows&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2025&#x2F;07&#x2F;dataframe-processing-benchmarks&#x2F;images&#x2F;03-50m-transformation.webp&quot; alt=&quot;50m-transformation&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;At this point, pandas struggles to parse 50m rows of ndjson, but interestingly, polars takes longer to run compared to duckdb for both ndjson and parquet.&lt;&#x2F;p&gt;
&lt;p&gt;Also take note that given 50 million rows, having parquet as source in duckdb results in 6x faster execution time compared to ndjson. As for polars, parquet can give a 3x performance boost in relation to ndjson as source.&lt;&#x2F;p&gt;
&lt;p&gt;But not so fast, because if we are talking about window+groupby aggregation:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2025&#x2F;07&#x2F;dataframe-processing-benchmarks&#x2F;images&#x2F;04-50m-window-groupby.webp&quot; alt=&quot;50m-window-groupby&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;polars takes less time than duckdb.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;The claim that duckdb is faster than polars is true. But another conflicting claim that polars is faster than duckdb is also true.&lt;&#x2F;p&gt;
&lt;p&gt;Given the amount of data to process and performed operations, for a simple transformation, duckdb is faster than polars - at 50 million rows this translates to duckdb being 2x faster than polars.&lt;&#x2F;p&gt;
&lt;p&gt;But if we are talking about heavy-duty aggregations, polars is faster than duckdb.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Simplify SSH (and HTTP &amp; Postgres) access management with Warpgate</title>
          <pubDate>Sat, 28 Jun 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2025/06/simplify-ssh-and-postgres-http-access-management-with-warpgate/</link>
          <guid>https://karnwong.me/posts/2025/06/simplify-ssh-and-postgres-http-access-management-with-warpgate/</guid>
          <description xml:base="https://karnwong.me/posts/2025/06/simplify-ssh-and-postgres-http-access-management-with-warpgate/">&lt;h2 id=&quot;background&quot;&gt;Background&lt;a class=&quot;zola-anchor&quot; href=&quot;#background&quot; aria-label=&quot;Anchor link for: background&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;If you have to work with virtual machines (VMs), you know the drill: disable password authentication and only allow private key authentication. If you want to sleep better at night, make the VMs only accessible through a private network to reduce the attack surface.&lt;&#x2F;p&gt;
&lt;p&gt;What about at scale? What if you are not the only person who has to access those VMs, because you are working in a team. Then things get interesting, because allowing developers direct access to VMs means a lot of security implications, and it&#x27;s not uncommon for developers in a hurry to share their private key with a team member - and we all know that the key wouldn&#x27;t be rotated anytime in the near future.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-it-s-been-done&quot;&gt;How it&#x27;s been done&lt;a class=&quot;zola-anchor&quot; href=&quot;#how-it-s-been-done&quot; aria-label=&quot;Anchor link for: how-it-s-been-done&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;In practice, this mostly translates to a bastion host, acting as a bridge between developer&#x27;s machines and target machines. First you use the bastion host to forward the SSH port, then you use it to access the target machine. This would likely involve the bastion host admin to provision a unique private key for each developer, add its public keys to the bastion host. But this is only the bastion host we are talking about, then there are those target machines where ideally the same public keys should be added to authorized keys as well. You see where this is going. If someone leaves the org, yup, better make sure that you revoke their public key from all machines.&lt;&#x2F;p&gt;
&lt;p&gt;One thing to keep in mind is you&#x27;ll have to add some guardrails to disable shell access, since some developers, in a hurry, against their better judgment, might add a few stowaway cronjobs critical to production to the bastion host 🙃.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-hard-part-that-we-all-dread-but-they-need-to-be-done&quot;&gt;The hard part that we all dread, but they need to be done&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-hard-part-that-we-all-dread-but-they-need-to-be-done&quot; aria-label=&quot;Anchor link for: the-hard-part-that-we-all-dread-but-they-need-to-be-done&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Did I mention audit logs? Have fun combing through the logs. And if you find provisioning private keys tedious, I&#x27;m with you on that. Then you have to come up with clever tricks to make sure only certain developer&#x27;s group has to access to particular VMs, while disable access to other VMs. RBAC strikes back.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;then-i-found-warpgate&quot;&gt;Then I found Warpgate&lt;a class=&quot;zola-anchor&quot; href=&quot;#then-i-found-warpgate&quot; aria-label=&quot;Anchor link for: then-i-found-warpgate&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;ll admit at first it was tricky to assess what warpgate was trying to solve, but upon reading their &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;warpgate.null.page&#x2F;&quot;&gt;documentation&lt;&#x2F;a&gt; it paints a clearer picture - to use RBAC to control access to targets.&lt;&#x2F;p&gt;
&lt;p&gt;This comprises three layers:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;User Identity - can be native to warpgate or via SSO&lt;&#x2F;li&gt;
&lt;li&gt;Targets - can be SSH, HTTP, MySQL or Postgres&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;blockquote&gt;
&lt;p&gt;I find this is very neat since I don&#x27;t need separate systems for managing non-SSH access.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;RBAC, which users&#x2F;groups can access which targets, and which authentication mechanism to use&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;blockquote&gt;
&lt;p&gt;You can use password, private key or web-based approval workflow. They can be specified separately per each target type as well.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The setup works like this: warpgate generates its own private&#x2F;public key on initialization. You only have to add its public key to target machines, this means for all your VMs fleet, only one public key is required to be added in order for warpgate to be able to access it. When you SSH into your target machine, your host would be &lt;code&gt;warpgate&#x27;s acme&lt;&#x2F;code&gt; and username is &lt;code&gt;$WARPGATE_USERNAME:$WARPGATE_TARGET_NAME&lt;&#x2F;code&gt;. You can supply a password or private key, or use the web-based approval flow for authentication, depending on how you set it up, and you&#x27;ll be forwarded to the target machine.&lt;&#x2F;p&gt;
&lt;p&gt;It is similar for HTTP target, but the cool thing is you can bind it to a domain as well, which makes it great for internal apps. As for databases, it is similar to ssh targets, existing clients should work without requiring extra configurations.&lt;&#x2F;p&gt;
&lt;p&gt;And per ops tradition, warpgate has a terraform provider, and you should definitely use terraform to manage RBAC, because you&#x27;ll breeze through the audit.&lt;&#x2F;p&gt;
&lt;p&gt;But let&#x27;s not forget one of those times when you need to grant a temporary access, warpgate has you covered as well.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;The best part is that warpgate is free, as in beer 🍺.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Using Nix for CI, but with a twist</title>
          <pubDate>Fri, 20 Jun 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2025/06/using-nix-for-ci-but-with-a-twist/</link>
          <guid>https://karnwong.me/posts/2025/06/using-nix-for-ci-but-with-a-twist/</guid>
          <description xml:base="https://karnwong.me/posts/2025/06/using-nix-for-ci-but-with-a-twist/">&lt;p&gt;CI (continuous integration) is kind of tricky in a sense that each CI vendor has its own implementations, often glued together via yaml configurations. If you have a CI to build a binary, unless you use bash to 1) install dependencies and b) build the artifacts, most likely you would end up with different implementation for each CI platform.&lt;&#x2F;p&gt;
&lt;p&gt;The problem with using plain bash script is that it&#x27;s a lot of glue code (setting PATH variable for one), not to mention having to make sure that dependencies are pinned to a specific version (because things are going to break with upgrades, I can assure you that).&lt;&#x2F;p&gt;
&lt;p&gt;This essentially means that your CI pipelines would be very well optimized if you use vendor-specific building blocks (for installing dependencies, building binaries with cache, etc), but it&#x27;s not portable. Bash scripts are portable but very brittle in a sense that it&#x27;s harder to pin dependencies.&lt;&#x2F;p&gt;
&lt;p&gt;But Nix exists, so why not. Nix is a build system, but you can use it to install packages. Take &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nix-community&#x2F;gomod2nix&quot;&gt;gomod2nix&lt;&#x2F;a&gt; for example, basically it stays within your golang project so you can use nix to build a golang binary. It&#x27;s very pleasant to use, but that&#x27;s a lot of boilerplate code, and it&#x27;s still tricky to figure out how to do cross-compilation build.&lt;&#x2F;p&gt;
&lt;p&gt;But then &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;flox.dev&#x2F;docs&#x2F;install-flox&#x2F;&quot;&gt;flox&lt;&#x2F;a&gt; exists. Think of virtual environment, but behind the scenes it&#x27;s nix installing tools and packages. This means you can offload dependencies installation to flox&#x2F;nix, and continue using bash for the build process.&lt;&#x2F;p&gt;
&lt;p&gt;In &lt;code&gt;.flox&#x2F;env&#x2F;manifest.toml&lt;&#x2F;code&gt;, you would specify packages like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;toml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-section&quot;&gt;install&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;go&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; pkg-path&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;go&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; version&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;^1.23.3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;air&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;pkg-path&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;air&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And once you activate the flox shell, you can continue doing your own thing.&lt;&#x2F;p&gt;
&lt;p&gt;In CI, this means that as long as you can install flox&#x2F;nix, and set it to utilize cache, you are pretty much good to go. Although you probably have to use vendor-specific configurations for uploading build artifacts, but it&#x27;s a small price to pay for not having to reimplement everything for each CI system.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Hello Garage, goodbye MinIO</title>
          <pubDate>Fri, 13 Jun 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2025/06/hello-garage-goodbye-minio/</link>
          <guid>https://karnwong.me/posts/2025/06/hello-garage-goodbye-minio/</guid>
          <description xml:base="https://karnwong.me/posts/2025/06/hello-garage-goodbye-minio/">&lt;p&gt;Given the trend where open-source software license changes to be less permissive, or move features behind a paywall,
existing users might not be quite as happy about this predicament. Case in point: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=44136108&quot;&gt;MinIO Removes Web UI Features from Community Version, Pushes Users to Paid Plans&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;But this post is not about that, but rather more on why I&#x27;m migrating to garage.&lt;&#x2F;p&gt;
&lt;p&gt;Recently I&#x27;ve been using minio as a dvc backend (think of git LFS but using blob storage as backend) and it accumulated
a lot of small files. Understandably, minio performance tanked because it doesn&#x27;t handle small files well. Also minio
deployment seems to use a little too much resources - it consumes 218 MB of memory. This much memory usage would be expected of a web application, but not for something like minio. Also see &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;minio&#x2F;minio&#x2F;issues&#x2F;9966&quot;&gt;this minio issue&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To get started with garage, follow this &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;garagehq.deuxfleurs.fr&#x2F;documentation&#x2F;quick-start&#x2F;&quot;&gt;quickstart&lt;&#x2F;a&gt;. Adjust the
toml config as necessary.&lt;&#x2F;p&gt;
&lt;p&gt;Note that aws s3 api performs a checksum, and recent aws sdk broke garage&#x27;s default settings.
See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;boto&#x2F;boto3&#x2F;issues&#x2F;4392#issuecomment-2868118431&quot;&gt;this issue&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In essence, to get the most recent of garage (v1.1.0) working with aws cli and sdk, following configurations should be
made:&lt;&#x2F;p&gt;
&lt;h4 id=&quot;aws-config&quot;&gt;aws config&lt;a class=&quot;zola-anchor&quot; href=&quot;#aws-config&quot; aria-label=&quot;Anchor link for: aws-config&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;set region to the value you specified in &lt;code&gt;garage.toml&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;environment-variables&quot;&gt;environment variables&lt;a class=&quot;zola-anchor&quot; href=&quot;#environment-variables&quot; aria-label=&quot;Anchor link for: environment-variables&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h4&gt;
&lt;p&gt;For preventing invalid checksum errors.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;AWS_REQUEST_CHECKSUM_CALCULATION&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;w&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;q&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;AWS_RESPONSE_CHECKSUM_VALIDATION&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;w&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;q&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;resources-consumption&quot;&gt;Resources consumption&lt;a class=&quot;zola-anchor&quot; href=&quot;#resources-consumption&quot; aria-label=&quot;Anchor link for: resources-consumption&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;I didn&#x27;t expect this much difference, but it&#x27;s very welcome.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Service&lt;&#x2F;th&gt;&lt;th&gt;CPU&lt;&#x2F;th&gt;&lt;th&gt;Memory&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;MinIO&lt;&#x2F;td&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;218&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Garage&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Because garage is written in rust, score for Ferris the Crab!&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Cloudflare&#x27;s terraform v5 provider migration strategy</title>
          <pubDate>Tue, 10 Jun 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2025/06/cloudflares-terraform-v5-provider-migration-strategy/</link>
          <guid>https://karnwong.me/posts/2025/06/cloudflares-terraform-v5-provider-migration-strategy/</guid>
          <description xml:base="https://karnwong.me/posts/2025/06/cloudflares-terraform-v5-provider-migration-strategy/">&lt;p&gt;Back in February 2025, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developers.cloudflare.com&#x2F;changelog&#x2F;2025-02-03-terraform-v5-provider&#x2F;&quot;&gt;Cloudflare announced that its terraform v5 provider is GA&lt;&#x2F;a&gt;. However, this release contains a lot of breaking changes, but I understand why it had to be this way - because it&#x27;s less work if you generate a terraform provider via OpenAPI specs.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;registry.terraform.io&#x2F;providers&#x2F;cloudflare&#x2F;cloudflare&#x2F;latest&#x2F;docs&#x2F;guides&#x2F;version-5-upgrade&quot;&gt;v4 to v5 provider upgrade guide is provided&lt;&#x2F;a&gt;. However, it&#x27;s not for the faint of heart, and it contains a lot of hacks. Moreover, some resources are renamed, which makes it even more tricky to perform a provider upgrade in-place, seeing it would fail the tfstate validation (trust me I&#x27;ve tried).&lt;&#x2F;p&gt;
&lt;p&gt;For a very small project, after a lot of trial and error I finally figured out that you have to remove all resources where the resource name changes in v5, then re-import them later.&lt;&#x2F;p&gt;
&lt;p&gt;However, I have a large terraform project, and this solution doesn&#x27;t scale well. The good thing is that terraform state is in JSON format, so a little python-fu to extract resource names and ids should work, then initialize a new terraform project and slowly re-import everything back. You can copy the existing project, comment out all resource blocks and backend definition, then re-import cloudflare resources in chunks, and &lt;code&gt;terraform plan&lt;&#x2F;code&gt; periodically for sanity check.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;python-utils-script&quot;&gt;Python Utils Script&lt;a class=&quot;zola-anchor&quot; href=&quot;#python-utils-script&quot; aria-label=&quot;Anchor link for: python-utils-script&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;This is a little hacky, but it&#x27;s a one-time kinda thing. You can modify this for other providers as well, but you&#x27;ll have to adjust the blocks for resource name and ids extraction.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;with&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; open&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;terraform.tfstate&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; f&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    state&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; json&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;load&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; state&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;resources&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    resource_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    resource_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;mode&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;managed&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        is_module&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;module&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; is_module&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            resource_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;module&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;            )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            resource_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    resource_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;instances&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; resource_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;cloudflare_record&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            instance_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;attributes&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            instance_zone_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;attributes&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;zone_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            resource_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;instance_zone_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;instance_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        elif&lt;&#x2F;span&gt;&lt;span&gt; resource_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;cloudflare_api_token&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            resource_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;attributes&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        elif&lt;&#x2F;span&gt;&lt;span&gt; resource_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;cloudflare_page_rule&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            instance_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;attributes&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            instance_zone_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;attributes&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;zone_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            resource_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;instance_zone_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;instance_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        elif&lt;&#x2F;span&gt;&lt;span&gt; resource_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;cloudflare_r2_bucket&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            account&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;attributes&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;account_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;            id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;attributes&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            location&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;attributes&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;location&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            resource_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;account&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;location&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        elif&lt;&#x2F;span&gt;&lt;span&gt; resource_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;cloudflare_pages_domain&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            account&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;attributes&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;account_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            project_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;attributes&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;project_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            domain&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;attributes&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;domain&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            resource_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;account&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;project_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;domain&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        elif&lt;&#x2F;span&gt;&lt;span&gt; resource_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;cloudflare_pages_project&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            account&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;attributes&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;account_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            project_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;attributes&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            resource_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;account&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;project_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;index_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            resource_name_loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; resource_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;[&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;index_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;            print&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;tf import &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;resource_name_loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39; &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;resource_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;            print&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;tf import &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;resource_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39; &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;resource_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;print&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;----&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</description>
      </item>
      <item>
          <title>Model inference in ONNX</title>
          <pubDate>Tue, 03 Jun 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2025/06/model-inference-in-onnx/</link>
          <guid>https://karnwong.me/posts/2025/06/model-inference-in-onnx/</guid>
          <description xml:base="https://karnwong.me/posts/2025/06/model-inference-in-onnx/">&lt;p&gt;Everyone agrees that python is great for data stuff, be it data engineering or machine learning. Although rust is
gaining more traction for data-related applications, python is here to stay.&lt;&#x2F;p&gt;
&lt;p&gt;Those who venture into machine learning are at least familiar with sklearn - a popular framework for machine
learning.&lt;&#x2F;p&gt;
&lt;p&gt;A common use case is you feed it a dataframe (or number arrays) and it will return a mathematical model for you. The
issue is that packaging it to make it production-ready is not trivial, and that you are tied to using python for your
inference code.&lt;&#x2F;p&gt;
&lt;p&gt;While I agree that python is great for data stuff, it really doesn&#x27;t excel at production where you need reliability and
sensible error handling (I should know... I write go, rust python and I really don&#x27;t want my worst enemy to deal with
debugging python in production).&lt;&#x2F;p&gt;
&lt;p&gt;But thankfully there&#x27;s a way out of this - serialize a sklearn model into a portable format (onnx) and serve it in
rust (I tried serving onnx with go, it was very painful - so rust it is).&lt;&#x2F;p&gt;
&lt;p&gt;You can serialize pytorch models into onnx as well, so it&#x27;s not only limited to classic models.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;raw-numbers&quot;&gt;Raw Numbers&lt;a class=&quot;zola-anchor&quot; href=&quot;#raw-numbers&quot; aria-label=&quot;Anchor link for: raw-numbers&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;mean_s&lt;&#x2F;th&gt;&lt;th&gt;median_s&lt;&#x2F;th&gt;&lt;th&gt;min_s&lt;&#x2F;th&gt;&lt;th&gt;max_s&lt;&#x2F;th&gt;&lt;th&gt;language&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;0.133962&lt;&#x2F;td&gt;&lt;td&gt;0.134343&lt;&#x2F;td&gt;&lt;td&gt;0.127497&lt;&#x2F;td&gt;&lt;td&gt;0.142944&lt;&#x2F;td&gt;&lt;td&gt;onnx-python&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;0.021048&lt;&#x2F;td&gt;&lt;td&gt;0.020614&lt;&#x2F;td&gt;&lt;td&gt;0.019894&lt;&#x2F;td&gt;&lt;td&gt;0.024474&lt;&#x2F;td&gt;&lt;td&gt;onnx-rust&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;0.666279&lt;&#x2F;td&gt;&lt;td&gt;0.662034&lt;&#x2F;td&gt;&lt;td&gt;0.654630&lt;&#x2F;td&gt;&lt;td&gt;0.691337&lt;&#x2F;td&gt;&lt;td&gt;scikitlearn-python&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;model-inference-performance&quot;&gt;Model Inference Performance&lt;a class=&quot;zola-anchor&quot; href=&quot;#model-inference-performance&quot; aria-label=&quot;Anchor link for: model-inference-performance&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2025&#x2F;06&#x2F;model-inference-in-onnx&#x2F;images&#x2F;model-inference.webp&quot; alt=&quot;model-inference&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Native sklearn model is slowest, this is expected. By serializing the model into onnx, python serving performance is significantly better. But it&#x27;s even faster if you serve onnx via rust.&lt;&#x2F;p&gt;
&lt;p&gt;This means onnx-rust is &lt;code&gt;552%&lt;&#x2F;code&gt; faster than onnx-python!!!&lt;&#x2F;p&gt;
&lt;p&gt;Is it 🐍 or 🦥, I&#x27;ll let you decide.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;Updated 2025-08-15&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m preparing for an upcoming workshop, so here&#x27;s more benchmark results:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Serving scikit-learn model via fastapi in python, the inference takes &lt;code&gt;0.0145s&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Serving onnx model via axum in rust, the inference takes &lt;code&gt;0.0120s&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This means onnx-rust is &lt;code&gt;0.1718s&lt;&#x2F;code&gt; faster than scikitlearn-python. Which translates to &lt;code&gt;17.18%&lt;&#x2F;code&gt; faster.`&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cost-analysis&quot;&gt;Cost Analysis&lt;a class=&quot;zola-anchor&quot; href=&quot;#cost-analysis&quot; aria-label=&quot;Anchor link for: cost-analysis&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Given a ride-hailing app example: 100k users per month -&amp;gt; 15m requests per month for cost calculation endpoint.&lt;&#x2F;p&gt;
&lt;p&gt;Serving the scikit-learn model in python via google cloud run would cost: &lt;code&gt;8.069 USD&lt;&#x2F;code&gt;. But if we use onnx via rust which is faster, it would cost &lt;code&gt;6.678 USD&lt;&#x2F;code&gt;. Which is roughly around &lt;code&gt;17%&lt;&#x2F;code&gt; in terms of price difference, this is because cloud run price, given fixed compute specs, is a function of time.&lt;&#x2F;p&gt;
&lt;p&gt;For a larger model, which would mean higher latency, it would translate to more cost savings.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>My code search setup throughout the years</title>
          <pubDate>Sat, 31 May 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2025/05/my-code-search-setup-throughout-the-years/</link>
          <guid>https://karnwong.me/posts/2025/05/my-code-search-setup-throughout-the-years/</guid>
          <description xml:base="https://karnwong.me/posts/2025/05/my-code-search-setup-throughout-the-years/">&lt;h2 id=&quot;initial-setup&quot;&gt;Initial Setup&lt;a class=&quot;zola-anchor&quot; href=&quot;#initial-setup&quot; aria-label=&quot;Anchor link for: initial-setup&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Around 2022-23, I was browsing &lt;code&gt;awesome self-hosted&lt;&#x2F;code&gt; and came across &lt;code&gt;Sourcegraph&lt;&#x2F;code&gt;, a popular code search tool. I don&#x27;t plan to pay, and they allowed self-hosting, so it was perfect for me at the time. Then you still can&#x27;t search code in GitHub (which we used for work), so being able to index ever-growing repos was very important. My productivity skyrocketed and our teams were happy because they don&#x27;t have to hunt down that specific line in god-knows-which-repo-and-which-file.&lt;&#x2F;p&gt;
&lt;p&gt;This went on for two years, then the license changes happened and we can&#x27;t use self-hosted Sourcegraph with more than a handful of private repos anymore.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;livegrep-to-the-rescue&quot;&gt;Livegrep to the Rescue&lt;a class=&quot;zola-anchor&quot; href=&quot;#livegrep-to-the-rescue&quot; aria-label=&quot;Anchor link for: livegrep-to-the-rescue&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;I then discovered &lt;code&gt;livegrep&lt;&#x2F;code&gt;, a very lightweight code search solution. Previously with Sourcegraph, to make things easier, they bundled all services into a single container image, which is a good thing because it&#x27;s very convenient. But with livegrep, you need three components: an indexer, backend and frontend. A docker compose is provided so you don&#x27;t have to stitch everything together yourself.&lt;&#x2F;p&gt;
&lt;p&gt;But livegrep is very well optimized, to the point that my current running instance against 200+ repos only consume 99 MB of memory for backend, and 21 MB for frontend, which is a rare sight in 2025.&lt;&#x2F;p&gt;
&lt;p&gt;The way livegrep works is that initially you&#x27;d run an indexer (it has direct integration with GitHub), which would clone the repos and generate the search index. Then you start a backend that picks up the said index, and frontend talks to backend via REST api.&lt;&#x2F;p&gt;
&lt;p&gt;On subsequent indexing, after an indexer job completes, you just have to restart the backend and frontend, respectively.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;new-kid-on-the-block&quot;&gt;New Kid on the Block&lt;a class=&quot;zola-anchor&quot; href=&quot;#new-kid-on-the-block&quot; aria-label=&quot;Anchor link for: new-kid-on-the-block&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Recently there&#x27;s &lt;code&gt;Sourcebot&lt;&#x2F;code&gt;, it uses the same innards as Sourcegraph but with different frontend implementation. It&#x27;s slower than livegrep (very noticeable) and it doesn&#x27;t work quite great when indexing 200+ repos. Which means....&lt;&#x2F;p&gt;
&lt;h2 id=&quot;some-diy-is-needed&quot;&gt;Some DIY is Needed&lt;a class=&quot;zola-anchor&quot; href=&quot;#some-diy-is-needed&quot; aria-label=&quot;Anchor link for: some-diy-is-needed&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;livegrep is perfect for everything except that it doesn&#x27;t automatically clone your private repos by default. If private repos belong to an organization, there is no issues, but if they belong to a user, then livegrep can clone it, but you have to specify those repos manually. This is because the GitHub api livegrep uses to fetch your repos list does not return user&#x27;s private repos (it&#x27;s in the documentation).&lt;&#x2F;p&gt;
&lt;p&gt;To circumvent this, I wrote a small golang utility to fetch repos list (either belonging to orgs or users), then clone them. I also use Forgejo hosted on my home server as well, which means the default livegrep indexer doesn&#x27;t support - going DIY means I can extend the repos cloning workflow to non-GitHub providers.&lt;&#x2F;p&gt;
&lt;p&gt;And the good thing is the code indexing workflow can be run separately in livegrep, so I just have to look up the code indexing config for livegrep, and add a step in my golang utility to generate it, then send it to livegrep indexer to generate the index and voila!&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s really satisfying when you can write code to solve that issue that&#x27;s been bothering you.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>WASM FFI performance benchmark</title>
          <pubDate>Tue, 15 Apr 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2025/04/wasm-ffi-performance-benchmark/</link>
          <guid>https://karnwong.me/posts/2025/04/wasm-ffi-performance-benchmark/</guid>
          <description xml:base="https://karnwong.me/posts/2025/04/wasm-ffi-performance-benchmark/">&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2025&#x2F;04&#x2F;wasm-ffi-performance-benchmark&#x2F;images&#x2F;cover.webp&quot; alt=&quot;cover&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;br&gt;
&lt;p&gt;WASM is known for being very portable because the only thing it asks for is a browser runtime. This means it doesn&#x27;t
matter if you have machines on linux&#x2F;amd64, windows&#x2F;amd64, darwin&#x2F;aarch64, WASM can run on all these platforms without
required modifications.&lt;&#x2F;p&gt;
&lt;p&gt;WASM can be used directly, or as an FFI through various languages&#x2F;SDKs. One common pattern is when you have a
multi-platform apps, the core logic would be compiled into WASM, which is then embedded within app implementations (which can be in Swift for iOS, Kotlin for Android, Electron for web&#x2F;desktop).&lt;&#x2F;p&gt;
&lt;p&gt;I was curious about the overhead from running WASM through various languages, this is the results.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;setup&quot;&gt;Setup&lt;a class=&quot;zola-anchor&quot; href=&quot;#setup&quot; aria-label=&quot;Anchor link for: setup&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Given &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2024&#x2F;12&#x2F;native-implementation-vs-wasm-for-go-python-and-rust-benchmark&#x2F;&quot;&gt;Rust-to-WASM has the best performance&lt;&#x2F;a&gt;,
the WASM binary used as FFI would be written in Rust, which then compiled into WASM.&lt;&#x2F;p&gt;
&lt;p&gt;The code is pretty simple: add random numbers to a fix-sized array, then sum the array, and divide it with the array
length.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;use&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-namespace&quot;&gt; rand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-rust z-entity z-name z-type&quot;&gt;Rng&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; main&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; mut&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-rust z-entity z-name z-type&quot;&gt; Vec&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;f64&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-rust z-entity z-name z-type&quot;&gt; Vec&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;new&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; loops&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; i32&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 999999&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;loops&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; i_float64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; f64&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; random_float&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-namespace&quot;&gt; rand&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;rng&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;random_range&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;999999&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;        vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;random_float&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; i_float64&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Vector length: &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;:?&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;len&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; vector_sum&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; f64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;iter&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Vector sum divided by total loops: &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;:?&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;        vector_sum&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; loops&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; f64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    )&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then execute the WASM binary via wasmtime (native), go, python and rust&#x27;s wasmtime sdk.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;raw-numbers&quot;&gt;Raw Numbers&lt;a class=&quot;zola-anchor&quot; href=&quot;#raw-numbers&quot; aria-label=&quot;Anchor link for: raw-numbers&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;mean_s&lt;&#x2F;th&gt;&lt;th&gt;median_s&lt;&#x2F;th&gt;&lt;th&gt;min_s&lt;&#x2F;th&gt;&lt;th&gt;max_s&lt;&#x2F;th&gt;&lt;th&gt;language&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;0.065217&lt;&#x2F;td&gt;&lt;td&gt;0.064873&lt;&#x2F;td&gt;&lt;td&gt;0.060479&lt;&#x2F;td&gt;&lt;td&gt;0.084518&lt;&#x2F;td&gt;&lt;td&gt;go&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;0.049194&lt;&#x2F;td&gt;&lt;td&gt;0.048882&lt;&#x2F;td&gt;&lt;td&gt;0.046070&lt;&#x2F;td&gt;&lt;td&gt;0.055017&lt;&#x2F;td&gt;&lt;td&gt;native&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;0.108358&lt;&#x2F;td&gt;&lt;td&gt;0.107370&lt;&#x2F;td&gt;&lt;td&gt;0.102075&lt;&#x2F;td&gt;&lt;td&gt;0.144279&lt;&#x2F;td&gt;&lt;td&gt;python&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;0.065958&lt;&#x2F;td&gt;&lt;td&gt;0.065392&lt;&#x2F;td&gt;&lt;td&gt;0.060728&lt;&#x2F;td&gt;&lt;td&gt;0.077792&lt;&#x2F;td&gt;&lt;td&gt;rust&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;We will revisit this later.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;benchmark-results&quot;&gt;Benchmark Results&lt;a class=&quot;zola-anchor&quot; href=&quot;#benchmark-results&quot; aria-label=&quot;Anchor link for: benchmark-results&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;statistics&quot;&gt;Statistics&lt;a class=&quot;zola-anchor&quot; href=&quot;#statistics&quot; aria-label=&quot;Anchor link for: statistics&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2025&#x2F;04&#x2F;wasm-ffi-performance-benchmark&#x2F;images&#x2F;01-overview.webp&quot; alt=&quot;overview&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Python takes the longest to execute WASM binary, which is expected since Python is an interpreted language. Running WASM binary directly is also fastest, this makes sense because there&#x27;s no languages&#x2F;SDKs overhead.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2025&#x2F;04&#x2F;wasm-ffi-performance-benchmark&#x2F;images&#x2F;02-go-vs-rust.webp&quot; alt=&quot;go-vs-rust&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Although it&#x27;s very surprising to see that Go and Rust have almost similar performance, but &lt;code&gt;max&lt;&#x2F;code&gt; value for Go, which is slightly higher than Rust&#x27;s makes sense due to its garbage collector.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;execution-time-throughout-iterations&quot;&gt;Execution Time Throughout Iterations&lt;a class=&quot;zola-anchor&quot; href=&quot;#execution-time-throughout-iterations&quot; aria-label=&quot;Anchor link for: execution-time-throughout-iterations&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2025&#x2F;04&#x2F;wasm-ffi-performance-benchmark&#x2F;images&#x2F;03-iterations.webp&quot; alt=&quot;iterations&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This coincides with above statistics, and you can clearly see that Go and Rust are having almost identical performance.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;a class=&quot;zola-anchor&quot; href=&quot;#conclusion&quot; aria-label=&quot;Anchor link for: conclusion&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Python has the most overhead for running WASM as FFI. Native WASM execution is fastest since there is no SDK overhead.&lt;&#x2F;p&gt;
&lt;p&gt;Go and Rust are slightly slower than Native (&lt;code&gt;1.62%&lt;&#x2F;code&gt; difference), but Go and Rust itself are having a &lt;code&gt;0.8%&lt;&#x2F;code&gt; gap (&lt;code&gt;0.000519&lt;&#x2F;code&gt; second difference).&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>WASM deployment benchmark</title>
          <pubDate>Mon, 10 Mar 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2025/03/wasm-deployment-benchmark/</link>
          <guid>https://karnwong.me/posts/2025/03/wasm-deployment-benchmark/</guid>
          <description xml:base="https://karnwong.me/posts/2025/03/wasm-deployment-benchmark/">&lt;p&gt;Correction 2025-06-16: there was a calculation error for artifacts size difference, it has been fixed.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Previously, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2024&#x2F;12&#x2F;native-implementation-vs-wasm-for-go-python-and-rust-benchmark&#x2F;&quot;&gt;we&#x27;ve seen how WASM performs&lt;&#x2F;a&gt;.
But what about delivery methods? This means runtime overhead as well, because executing a raw binary vs container means
startup time is involved.&lt;&#x2F;p&gt;
&lt;p&gt;Generally WASM as a binary can be executed in two ways: as a binary or from a container. But it wouldn&#x27;t be fair to not
compare it with native binary (linux&#x2F;amd64, for example).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;experiment-design&quot;&gt;Experiment Design&lt;a class=&quot;zola-anchor&quot; href=&quot;#experiment-design&quot; aria-label=&quot;Anchor link for: experiment-design&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Write a simple rust code to add numbers to an array, and sum the array.&lt;&#x2F;li&gt;
&lt;li&gt;Build
&lt;ul&gt;
&lt;li&gt;linux&#x2F;amd64 binary&lt;&#x2F;li&gt;
&lt;li&gt;WASM binary&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Create a container image
&lt;ul&gt;
&lt;li&gt;linux&#x2F;amd64&lt;&#x2F;li&gt;
&lt;li&gt;wasi&#x2F;wasm&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Compare
&lt;ul&gt;
&lt;li&gt;binary vs container size&lt;&#x2F;li&gt;
&lt;li&gt;binary vs container execution time (including startup overhead)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wasmedge.org&#x2F;docs&#x2F;develop&#x2F;deploy&#x2F;cri-runtime&#x2F;containerd&quot;&gt;Wasmedge&lt;&#x2F;a&gt; is used as a container runtime.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;results&quot;&gt;Results&lt;a class=&quot;zola-anchor&quot; href=&quot;#results&quot; aria-label=&quot;Anchor link for: results&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Below is the raw data.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;arch&lt;&#x2F;th&gt;&lt;th&gt;binary_size_kb&lt;&#x2F;th&gt;&lt;th&gt;image_size_kb&lt;&#x2F;th&gt;&lt;th&gt;execution_time_binary_ms&lt;&#x2F;th&gt;&lt;th&gt;execution_time_container_ms&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;linux&#x2F;amd64&lt;&#x2F;td&gt;&lt;td&gt;477&lt;&#x2F;td&gt;&lt;td&gt;8810&lt;&#x2F;td&gt;&lt;td&gt;13&lt;&#x2F;td&gt;&lt;td&gt;338.5&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;wasm&lt;&#x2F;td&gt;&lt;td&gt;100&lt;&#x2F;td&gt;&lt;td&gt;150&lt;&#x2F;td&gt;&lt;td&gt;47.5&lt;&#x2F;td&gt;&lt;td&gt;3531&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;artifacts-size&quot;&gt;Artifacts Size&lt;a class=&quot;zola-anchor&quot; href=&quot;#artifacts-size&quot; aria-label=&quot;Anchor link for: artifacts-size&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;We can see that both WASM binary and container image take up less space compared to native architecture.&lt;&#x2F;p&gt;
&lt;p&gt;WASM artifacts, both binary and container image, barely take up any space (100kb for binary, 150kb for container image).&lt;&#x2F;p&gt;
&lt;p&gt;This results in nearly 377% for binary size difference, and 5773% for container size difference. That&#x27;s really a lot of
space you can save in container registry.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;execution-time&quot;&gt;Execution Time&lt;a class=&quot;zola-anchor&quot; href=&quot;#execution-time&quot; aria-label=&quot;Anchor link for: execution-time&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Note: linux&#x2F;amd64 native vs container execution time (excluding container startup overhead) have negligible
difference.&lt;&#x2F;strong&gt; This mean we can somewhat attribute the &lt;code&gt;Execution Time (Container)&lt;&#x2F;code&gt; axis as container startup overhead.&lt;&#x2F;p&gt;
&lt;p&gt;Binary execution time would be faster, but compound it with container startup time, there&#x27;s more overhead to run a WASM
container.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2025&#x2F;03&#x2F;wasm-deployment-benchmark&#x2F;images&#x2F;execution-time.webp&quot; alt=&quot;execution time&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;a class=&quot;zola-anchor&quot; href=&quot;#conclusion&quot; aria-label=&quot;Anchor link for: conclusion&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;WASM is great if you want platform-agnostic deployment. The benefits are that the artifacts size is smaller and it can
run on any platform, but at the cost of longer execution time.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Migrate from Docker Desktop to Podman on Darwin</title>
          <pubDate>Sun, 02 Mar 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2025/03/migrate-from-docker-desktop-to-podman-on-darwin/</link>
          <guid>https://karnwong.me/posts/2025/03/migrate-from-docker-desktop-to-podman-on-darwin/</guid>
          <description xml:base="https://karnwong.me/posts/2025/03/migrate-from-docker-desktop-to-podman-on-darwin/">&lt;p&gt;Lately Docker Desktop on Mac behaves weirdly, namely its erratic memory consumption. Not willing to babysit the memory usage, I looked into alternatives, and found a few contenders: Colima, Podman and Orbstack.&lt;&#x2F;p&gt;
&lt;p&gt;Being an open-source aficionado, naturally I gravitate to Colima and Podman. Although my spidey sense tells me Podman is more polished. Gave it a go and it works beautifully, so here&#x27;s my setup to make it backward compatible with tools utilizing docker command and socket.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;installing-podman&quot;&gt;Installing Podman&lt;a class=&quot;zola-anchor&quot; href=&quot;#installing-podman&quot; aria-label=&quot;Anchor link for: installing-podman&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;brew&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; install&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-cask&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; podman-desktop&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;brew&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; install&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; podman&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;brew&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; install&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; podman-compose&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;shell-config&quot;&gt;Shell Config&lt;a class=&quot;zola-anchor&quot; href=&quot;#shell-config&quot; aria-label=&quot;Anchor link for: shell-config&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;I use Fish, but it can be applied to other shells.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;switch&lt;&#x2F;span&gt;&lt;span&gt; (uname&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    case Darwin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; backward compatibility with docker command&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;        function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; docker&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;            podman&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; $&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;argv&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; make it work with tools relying on docker socket&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;        function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; lazydocker&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;            DOCKER_HOST&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unix:&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;$(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;podman&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; machine&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; inspect&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-format&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;{{.ConnectionInfo.PodmanSocket.Path}}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;HOME&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;.nix-profile&#x2F;bin&#x2F;lazydocker&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</description>
      </item>
      <item>
          <title>Cross-platform keyring-like setup (also works without desktop environment)</title>
          <pubDate>Thu, 13 Feb 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2025/02/cross-platform-keyring-like-setup-also-works-without-desktop-environment/</link>
          <guid>https://karnwong.me/posts/2025/02/cross-platform-keyring-like-setup-also-works-without-desktop-environment/</guid>
          <description xml:base="https://karnwong.me/posts/2025/02/cross-platform-keyring-like-setup-also-works-without-desktop-environment/">&lt;p&gt;Sometimes, running an application requires you to supply a password, or something along these lines. If you have a terminal-based workflow, sometimes it can require an authentication token.&lt;&#x2F;p&gt;
&lt;p&gt;These configurations would need to be supplied either at runtime or stored somewhere on your system. We can agree that typing the creds each time isn&#x27;t fun. But putting those secrets in a file on your filesystem? Attackers love this, so maybe don&#x27;t make them too happy!&lt;&#x2F;p&gt;
&lt;p&gt;Conventional wisdom is you should store the credentials in a system&#x27;s keyring. This means you need a desktop environment (headless linux won&#x27;t work with this). And that if you were to migrate to a new machine, you have to set it up again. Hmmmm.....&lt;&#x2F;p&gt;
&lt;p&gt;I ran into this exact predicament, and I&#x27;m happy to share you my workaround to this. It&#x27;s very simple - using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;getsops&#x2F;sops&quot;&gt;SOPs&lt;&#x2F;a&gt; to encrypt secrets and store it somewhere on your system. Then create a shell function to fetch this secret key from your encrypted file.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;usage&quot;&gt;Usage&lt;a class=&quot;zola-anchor&quot; href=&quot;#usage&quot; aria-label=&quot;Anchor link for: usage&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Setup SOPs: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;getsops&#x2F;sops#usage&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;getsops&#x2F;sops#usage&lt;&#x2F;a&gt;. I use &lt;code&gt;age&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Create a secrets file: &lt;code&gt;sops -i secrets.sops.yaml&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Write your secret keys and values&lt;&#x2F;li&gt;
&lt;li&gt;Move your &lt;code&gt;secrets.sops.yaml&lt;&#x2F;code&gt; to your shell config&#x27;s path. I use &lt;code&gt;fish&lt;&#x2F;code&gt; so it&#x27;s at &lt;code&gt;$HOME&#x2F;.config&#x2F;fish&#x2F;secrets&#x2F;&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Create a fish function to fetch a secret via key&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; get_fish_secret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    ~&#x2F;.nix-profile&#x2F;bin&#x2F;sops&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ~&#x2F;.config&#x2F;fish&#x2F;secrets&#x2F;secrets.sops.yaml&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; ~&#x2F;.nix-profile&#x2F;bin&#x2F;yq&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; .&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;argv&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;6&quot;&gt;
&lt;li&gt;In your shell alias&#x2F;functions&#x2F;config, access secrets via &lt;code&gt;$(get_fish_secret MINIO_ENDPOINT)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;This setup also means you can store this with your dotfiles, since it&#x27;s already encrypted.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s to KISS, and don&#x27;t let anyone tell you otherwise.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>My journey for fully switching from Windows over to Linux</title>
          <pubDate>Sat, 25 Jan 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2025/01/my-journey-for-fully-switching-from-windows-over-to-linux/</link>
          <guid>https://karnwong.me/posts/2025/01/my-journey-for-fully-switching-from-windows-over-to-linux/</guid>
          <description xml:base="https://karnwong.me/posts/2025/01/my-journey-for-fully-switching-from-windows-over-to-linux/">&lt;p&gt;&lt;strong&gt;Note: This is not a post to bash on Windows. It&#x27;s more of what I need for work and tinkering stuff are better done on
Linux&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;background&quot;&gt;Background&lt;a class=&quot;zola-anchor&quot; href=&quot;#background&quot; aria-label=&quot;Anchor link for: background&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;My first OS was Windows. My first-ever automation script was written in Batch script, and I learned tons from tinkering
with the systems with it.&lt;&#x2F;p&gt;
&lt;p&gt;Then I explored Linux during my teens, for around five years I dual-booted Windows and Ubuntu side by side. Love using
both, not willing to lose the other kind of thing.&lt;&#x2F;p&gt;
&lt;p&gt;In college, my laptop was outdated at that point, battery doesn&#x27;t hold much charge. Apple happened to have discounts for
students, so I got a Macbook. During this time I started learning Python, but I still use Windows for media management
and gaming. I really noticed the difference when programming in Unix-based systems, things are much easier and less
painful.&lt;&#x2F;p&gt;
&lt;p&gt;Then I started working, I&#x27;m an avid gamer so I purchased a new PC mostly for gaming and media management (tagging music,
books, etc). Due to my work setup (single monitor, Macbook for work), it means if I want to play games on Windows, I
have to manually switch the monitor input channel and detach USB hub for peripherals attached to a Macbook to the PC
rig. Over time with more work responsibilities, I barely use Windows. This went on for around 5 years.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-turning-point&quot;&gt;The Turning Point&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-turning-point&quot; aria-label=&quot;Anchor link for: the-turning-point&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Since I take on management responsibilities, it means my day starts earlier than I was an individual contributor. Which
means I somewhat control my schedule, but it depends on when I have meetings throughout the day.&lt;&#x2F;p&gt;
&lt;p&gt;I drink tea&#x2F;coffee in the morning, cook every other day during lunch. Previously back when I was an IC, I can not touch
a computer before 1PM, but now I have to stay glued to the computer to attend meetings and respond to bajillion messages
and emails.&lt;&#x2F;p&gt;
&lt;p&gt;I live in a house, due to the layout, my desk and the kitchen island is around 10-meter apart. The problem? I have to move
my Macbook and dock it to my desk. Every single day. It gets old real fast. So I had a bright idea: partition off a 500
GB SSD for gaming on my PC and use it to install Ubuntu on it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;one-month-later&quot;&gt;One Month Later&lt;a class=&quot;zola-anchor&quot; href=&quot;#one-month-later&quot; aria-label=&quot;Anchor link for: one-month-later&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;I really love this setup, then I found out Proton is a thing and gaming on Linux is actually ok. Wheels are turning
in my head and it clicked: I don&#x27;t need to use Windows for gaming.&lt;&#x2F;p&gt;
&lt;p&gt;To test this idea, I installed Witcher 3 on Ubuntu and gave it a go. Next thing I know is I&#x27;m 1&#x2F;3 finished with the
game. This was really fun. Only problem: The rest of the storage on this PC is tied to Windows. Oops.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;migration&quot;&gt;Migration&lt;a class=&quot;zola-anchor&quot; href=&quot;#migration&quot; aria-label=&quot;Anchor link for: migration&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;It would be great if I can move other workloads I still require using Windows fully to Linux. The said workload is music
tagging, which luckily you can use &lt;code&gt;puddletag&lt;&#x2F;code&gt; in lieu of &lt;code&gt;MP3Tag&lt;&#x2F;code&gt; on Windows. But I still want &lt;code&gt;foobar2000&lt;&#x2F;code&gt;-like music
player on Linux, which isn&#x27;t available. Then I found out someone packaged it as a &lt;code&gt;snap&lt;&#x2F;code&gt;. And hey it works!&lt;&#x2F;p&gt;
&lt;p&gt;To make sure I really don&#x27;t need to use Windows, I migrated everything I need to use Windows for (gaming - done, music
tagging via puddletag - done, foobar2000 - done) and wait for a few weeks.&lt;&#x2F;p&gt;
&lt;p&gt;D-day, I backup data on NTFS to an external drive, remove all partitions, and partition it as follows:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Drive&lt;&#x2F;th&gt;&lt;th&gt;Usage&lt;&#x2F;th&gt;&lt;th&gt;Mountpath&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;SSD 256 GB&lt;&#x2F;td&gt;&lt;td&gt;boot&lt;&#x2F;td&gt;&lt;td&gt;&#x2F;boot&#x2F;efi&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;home&lt;&#x2F;td&gt;&lt;td&gt;&#x2F;home&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;SSD 500 GB&lt;&#x2F;td&gt;&lt;td&gt;gaming&lt;&#x2F;td&gt;&lt;td&gt;&#x2F;mnt&#x2F;ssd&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;HDD 1 TB&lt;&#x2F;td&gt;&lt;td&gt;data&lt;&#x2F;td&gt;&lt;td&gt;&#x2F;mnt&#x2F;hdd&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Fought a little with Archlinux, because it hates NVIDIA GPU apparently, so had to reflash Ubuntu.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m using &lt;code&gt;Nix&lt;&#x2F;code&gt; for packages and configurations, in total it took me 1 day to backup + install OS, and the other one for applying the configurations.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;closing&quot;&gt;Closing&lt;a class=&quot;zola-anchor&quot; href=&quot;#closing&quot; aria-label=&quot;Anchor link for: closing&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Overall I&#x27;m very happy with this setup, and turns out I can apply better graphics settings for games compared to when I was on Windows.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Information gathering infrastructure</title>
          <pubDate>Mon, 30 Dec 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2024/12/information-gathering-infrastructure/</link>
          <guid>https://karnwong.me/posts/2024/12/information-gathering-infrastructure/</guid>
          <description xml:base="https://karnwong.me/posts/2024/12/information-gathering-infrastructure/">&lt;pre class=&quot;mermaid&quot;&gt;
  flowchart LR

Feed --&amp;gt; Miniflux

%% feeds
subgraph Homelab
Miniflux --&amp;gt; Wallabag
end

Wallabag --&amp;gt;KOReader

%% newsletters
subgraph SaaS
Newsletters --&amp;gt; Email
end

subgraph Automation
Email --&amp;gt; EmailToEpubScript
end

EmailToEpubScript --&amp;gt; Syncthing

%% device
subgraph Device
KOReader --&amp;gt; Ereader
Syncthing --&amp;gt; Ereader
end
&lt;&#x2F;pre&gt;
&lt;p&gt;Once upon a time, I was asked by a recruiter regarding how I keep up with news and industry trends. I described something along this diagram, but apparently it went over his head.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m an avid reader, but reading on a computer or tablet screen is not fun for prolonged period of time. I&#x27;ve been using an ereader since 2012, and I love how easy it is on my eyes.&lt;&#x2F;p&gt;
&lt;p&gt;Back then things were simple, almost every site provided RSS. Then Google Reader got shut down, and people moved onto newsletters model, although some sites still provide RSS. Since I prefer to read stuff on my ereader, the flow is like this:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;for-feeds&quot;&gt;For feeds&lt;a class=&quot;zola-anchor&quot; href=&quot;#for-feeds&quot; aria-label=&quot;Anchor link for: for-feeds&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Subscribe them via Miniflux, an RSS feed aggregator. It&#x27;s hosted on my homelab.&lt;&#x2F;li&gt;
&lt;li&gt;For articles I want to read later, I send them to Wallabag via Miniflux integration. Walalbag is a Pocket-like app, self-hostable.&lt;&#x2F;li&gt;
&lt;li&gt;On my ereader, I have KOReader installed. It has a Wallabag plugin to download and sync articles.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;for-newsletters&quot;&gt;For newsletters&lt;a class=&quot;zola-anchor&quot; href=&quot;#for-newsletters&quot; aria-label=&quot;Anchor link for: for-newsletters&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Use an email address for newsletter subscription to subscribe newsletters.&lt;&#x2F;li&gt;
&lt;li&gt;Use a Go program to fetch emails and convert them to epub&lt;&#x2F;li&gt;
&lt;li&gt;Put epub files in a Syncthing folder. Syncthing is a file-sync application, this should be on both your workstation and ereader&lt;&#x2F;li&gt;
&lt;li&gt;On ereader, sync a folder that you use via Syncthing to obtain epub files.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</description>
      </item>
      <item>
          <title>Native implementation vs WASM for Go, Python and Rust benchmark</title>
          <pubDate>Wed, 04 Dec 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2024/12/native-implementation-vs-wasm-for-go-python-and-rust-benchmark/</link>
          <guid>https://karnwong.me/posts/2024/12/native-implementation-vs-wasm-for-go-python-and-rust-benchmark/</guid>
          <description xml:base="https://karnwong.me/posts/2024/12/native-implementation-vs-wasm-for-go-python-and-rust-benchmark/">&lt;p&gt;In 2024 you would hear the term &lt;code&gt;wasm&lt;&#x2F;code&gt; pop up now and then. It is not exactly new, but it&#x27;s gaining more traction due to
wider ecosystem in recent years. Wasm stands for web assembly, essentially it&#x27;s a format that allows you to execute
binaries in browser runtimes.&lt;&#x2F;p&gt;
&lt;p&gt;Imagine creating a website, and you need to implement a specific function. The problem is that it is much easier to
implement this function in Go, but your website is written in typescript. This happens to be a static site, so a backend
shouldn&#x27;t be necessary. You can either:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Implement this feature as a separate api, and have your website call it - but this would add more overhead to your
setup&lt;&#x2F;li&gt;
&lt;li&gt;Write this function in Go, and compile it into wasm and call it in your frontend code&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;There are bleeding edge use cases for wasm as well, namely utilizing CDN to serve wasm binaries in lieu of maintaining
multi-region infrastructure. The future is interesting.&lt;&#x2F;p&gt;
&lt;p&gt;Nowadays, many languages support compilation into wasm. Since I&#x27;m familiar with Go, Python and Rust I&#x27;m giving this a
go.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;experiment-setup&quot;&gt;Experiment Setup&lt;a class=&quot;zola-anchor&quot; href=&quot;#experiment-setup&quot; aria-label=&quot;Anchor link for: experiment-setup&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;A simple multiply function implemented natively in three languages, which then is compiled into wasm binary with
following setup:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;go&quot;&gt;Go&lt;a class=&quot;zola-anchor&quot; href=&quot;#go&quot; aria-label=&quot;Anchor link for: go&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;GOOS&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;w&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; GOARCH&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;w&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; go&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; build&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;o&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; main.wasm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;python&quot;&gt;Python&lt;a class=&quot;zola-anchor&quot; href=&quot;#python&quot; aria-label=&quot;Anchor link for: python&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;uv&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; tool&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; install&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-python&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 3.11&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; py2wasm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;py2wasm&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; main.py&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;o&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; main.wasm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;rust&quot;&gt;Rust&lt;a class=&quot;zola-anchor&quot; href=&quot;#rust&quot; aria-label=&quot;Anchor link for: rust&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;rustup&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; target&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; add&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; wasm32-wasip1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;cargo&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; build&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-target&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; wasm32-wasip1&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-release&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Wasm binary is executed via &lt;code&gt;wasmtime&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;benchmark-results&quot;&gt;Benchmark Results&lt;a class=&quot;zola-anchor&quot; href=&quot;#benchmark-results&quot; aria-label=&quot;Anchor link for: benchmark-results&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Note: wasm binary execution has a cold start. This means on the first run, it would be significantly slower than
subsequent runs.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;statistics&quot;&gt;Statistics&lt;a class=&quot;zola-anchor&quot; href=&quot;#statistics&quot; aria-label=&quot;Anchor link for: statistics&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2024&#x2F;12&#x2F;native-implementation-vs-wasm-for-go-python-and-rust-benchmark&#x2F;images&#x2F;01-stats.png&quot; alt=&quot;statistics&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;At a glance, it is obvious that Python&#x27;s wasm takes significantly longer than its native implementation. Go&#x27;s wasm
implementation is also slower. Rust&#x27;s wasm performance has the least gap with native implementation. Meaning: Rust to
wasm does not result in drastic performance difference.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2024&#x2F;12&#x2F;native-implementation-vs-wasm-for-go-python-and-rust-benchmark&#x2F;images&#x2F;02-stats-zoom.png&quot; alt=&quot;statistics-zoom&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Zooming in, we can see that there is still quite a gap between Rust and Rust&#x27;s wasm, but it&#x27;s very miniscule.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;execution-time-throughout-iterations&quot;&gt;Execution Time Throughout Iterations&lt;a class=&quot;zola-anchor&quot; href=&quot;#execution-time-throughout-iterations&quot; aria-label=&quot;Anchor link for: execution-time-throughout-iterations&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2024&#x2F;12&#x2F;native-implementation-vs-wasm-for-go-python-and-rust-benchmark&#x2F;images&#x2F;03-point.png&quot; alt=&quot;execution-time&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For all run iterations, Python plateaus. Go&#x27;s wasm also stood out.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2024&#x2F;12&#x2F;native-implementation-vs-wasm-for-go-python-and-rust-benchmark&#x2F;images&#x2F;04-point-zoom.png&quot; alt=&quot;execution-time-zoom&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Zooming in, we can clearly see that Rust&#x27;s wasm is very close to native Go and Rust implementation. In Go and Python, I
actually feel it&#x27;s longer to run the benchmark, but I didn&#x27;t notice Rust&#x27;s wasm taking longer than native Rust at all.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;a class=&quot;zola-anchor&quot; href=&quot;#conclusion&quot; aria-label=&quot;Anchor link for: conclusion&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;In terms of performance difference (median) for wasm in Go, Python and Rust:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Language&lt;&#x2F;th&gt;&lt;th&gt;Wasm Performance Difference (Second)&lt;&#x2F;th&gt;&lt;th&gt;Wasm Performance Difference (Percent)&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Go&lt;&#x2F;td&gt;&lt;td&gt;0.017&lt;&#x2F;td&gt;&lt;td&gt;1317%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Python&lt;&#x2F;td&gt;&lt;td&gt;0.02&lt;&#x2F;td&gt;&lt;td&gt;23%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Rust&lt;&#x2F;td&gt;&lt;td&gt;0.003&lt;&#x2F;td&gt;&lt;td&gt;466%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;In terms of actual execution time, Python has the most wasm overhead (at 0.02 second), Go is coming in second at 0.017 second. Rust meanwhile has the least wasm overhead at 0.003 second.&lt;&#x2F;p&gt;
&lt;p&gt;But in terms of percent difference from native implementation, Go has a whopping 1317% longer execution time in wasm. Python while having the most wasm runtime difference, it does not increase much from native implementation (at 23%). Rust still has 466% wasm overhead, but in terms of raw numbers it&#x27;s only 0.003 second.&lt;&#x2F;p&gt;
&lt;p&gt;Should you use wasm? It depends on your use case. But if you are one of the lucky few who employ Rust developers, why not give it a go? The wasm performance difference won&#x27;t likely impact your business. Unless you are Cloudflare or Discord.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Various notes on career-related stuff</title>
          <pubDate>Sat, 19 Oct 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2024/10/various-notes-on-career-related-stuff/</link>
          <guid>https://karnwong.me/posts/2024/10/various-notes-on-career-related-stuff/</guid>
          <description xml:base="https://karnwong.me/posts/2024/10/various-notes-on-career-related-stuff/">&lt;h2 id=&quot;compensation&quot;&gt;Compensation&lt;a class=&quot;zola-anchor&quot; href=&quot;#compensation&quot; aria-label=&quot;Anchor link for: compensation&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Sometimes you need to take a pay cut in order to learn new skills. But it will pay off in the end.
&lt;ul&gt;
&lt;li&gt;On the other hand, if you are paid above the market rate, when you have to move it&#x27;s probably harder because most orgs won&#x27;t offer the same compensation.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;skills&quot;&gt;Skills&lt;a class=&quot;zola-anchor&quot; href=&quot;#skills&quot; aria-label=&quot;Anchor link for: skills&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;PM &#x2F; PO &#x2F; EM &#x2F; Sales should understand technical stuff, as in they are aware of pros and cons of solutions being used. Bonus if they used to be an IC.&lt;&#x2F;li&gt;
&lt;li&gt;&quot;Do you need data structures and algorithms for $x&quot; often comes up in community. Short answer is you don&#x27;t need it until you do. But most people never reach the point where they need to utilize DSA. Not because it&#x27;s obsolete, rather more of most people can get by with poorly-optimized code.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;career-ladder&quot;&gt;Career ladder&lt;a class=&quot;zola-anchor&quot; href=&quot;#career-ladder&quot; aria-label=&quot;Anchor link for: career-ladder&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;No matter how well you can perform in your current role, if you don&#x27;t have the right amount of soft skills and big-picture thinking, you can&#x27;t advance further.&lt;&#x2F;li&gt;
&lt;li&gt;Most ICs who&#x27;s outgrowing their senior&#x2F;technical lead roles tend to jump straight into considering that they are staff&#x2F;principal engineer. This is almost always not the case, because to be a staff&#x2F;principal, you still need soft skills and business acumen. You are influencing without authority after all.&lt;&#x2F;li&gt;
&lt;li&gt;Most engineers are stuck at mid level, and that&#x27;s to be expected. And even less reach senior level. Less and less for technical lead and engineering manager.
&lt;ul&gt;
&lt;li&gt;Some people are still mid level after 10 years in the industry, and you have to let them be. Not everyone has what it takes to advance.&lt;&#x2F;li&gt;
&lt;li&gt;You would also find that some people can operate at a higher level, but it utilizes a lot of cognitive load for them, to the point they prefer to step down a level just to not lose their sanity.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;If you are doing your best and are the best performed member of your team - if you are not getting promoted, chances are your manager doesn&#x27;t want to lose you, because keeping you exactly where you are means your manager doesn&#x27;t have to find someone to replace you.
&lt;ul&gt;
&lt;li&gt;But it can also be that you need to catch up on your soft skills. Talk to your manager to assess your skills gap.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Having &quot;senior&quot; in the title doesn&#x27;t make someone actually operating at a senior level. It&#x27;s just a title. The same goes for &quot;manager&quot; as well.
&lt;ul&gt;
&lt;li&gt;A lot of senior engineers by title are actually mid levels. And a lot of managers only took the job because they want more pay but don&#x27;t actually enjoy managerial duties.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;roles&quot;&gt;Roles&lt;a class=&quot;zola-anchor&quot; href=&quot;#roles&quot; aria-label=&quot;Anchor link for: roles&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Being a manager isn&#x27;t about attending meetings all day. Rather it&#x27;s unblocking people and making sure people get the support they need.
&lt;ul&gt;
&lt;li&gt;But if they do this job well, you wouldn&#x27;t notice them at all. But if they do it poorly, you will notice their existence.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Data roles can be business or tech oriented, or somewhere in the middle. No point in fighting whether a DS&#x2F;DE&#x2F;MLE role should be technical or business-led.&lt;&#x2F;li&gt;
&lt;li&gt;Some roles are not entry-level. For instance, data engineering, data science, devops. But the caveat is that if you are joining an established team, it&#x27;s somewhat doable for entry-level.&lt;&#x2F;li&gt;
&lt;li&gt;Some job descriptions for data engineering can include anything from development, ml deployment, data pipelines, visualization, etc. Some ops roles can expect anything from dev, llm experiment and deployment.
&lt;ul&gt;
&lt;li&gt;This is a symptom of hiring managers not really understand roles collaboration. Because realistically no one can juggle everything at the same time.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Your actual responsibilities and title may not align. It&#x27;s up to you to present your title in resume.&lt;&#x2F;li&gt;
&lt;li&gt;After technical lead, one possible path is picking up management, PM and sales roles.
&lt;ul&gt;
&lt;li&gt;If you have to manage but can&#x27;t understand engineers, it&#x27;s not going to work.&lt;&#x2F;li&gt;
&lt;li&gt;If you have to keep the timeline in check and follow-up with people from multiple teams as a PM, not understanding the concerns from each team is not going to make your job as a PM easier.&lt;&#x2F;li&gt;
&lt;li&gt;Pitching products and services to clients while not fully understand your offerings&#x27; capabilities can cause more headaches for the engineering team, because if you promised what can&#x27;t actually be delivered, the engineering team wouldn&#x27;t want to work with you.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;job-change&quot;&gt;Job change&lt;a class=&quot;zola-anchor&quot; href=&quot;#job-change&quot; aria-label=&quot;Anchor link for: job-change&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;If you don&#x27;t learn something new at work for a while, maybe it&#x27;s time to move.&lt;&#x2F;li&gt;
&lt;li&gt;Sometimes it&#x27;s not you, it&#x27;s them. If you want to change job because you don&#x27;t like someone at work, you probably find it&#x27;s not effective because such people can exist anywhere. Question is how are you going to handle them. Sometimes things are outside your control, and at certain point there&#x27;s no reason to fight against the current.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;career-change&quot;&gt;Career change&lt;a class=&quot;zola-anchor&quot; href=&quot;#career-change&quot; aria-label=&quot;Anchor link for: career-change&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Data folks want to move to SWE. Vice versa is true. Both citing more pay on the other side.&lt;&#x2F;li&gt;
&lt;li&gt;Side projects do help, but what actually happens is people copy-pasting them left and right. So unless your resume stands out, no one would look at your side projects. Even then, your side projects should be original idea.&lt;&#x2F;li&gt;
&lt;li&gt;Some people want to switch career for better pay, there&#x27;s nothing wrong with it. But keep in mind the possibility that you might not be cut out for it.&lt;&#x2F;li&gt;
&lt;li&gt;It can be hard to accept that you can&#x27;t switch over to a career you aimed for. The longer this keeps going, the greater cognitive dissonance. Be kind to yourself, because there are probably other things out there that you are good at.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</description>
      </item>
      <item>
          <title>Calling C from Go, Python and Rust benchmark</title>
          <pubDate>Sat, 12 Oct 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2024/10/calling-c-from-go-python-and-rust-benchmark/</link>
          <guid>https://karnwong.me/posts/2024/10/calling-c-from-go-python-and-rust-benchmark/</guid>
          <description xml:base="https://karnwong.me/posts/2024/10/calling-c-from-go-python-and-rust-benchmark/">&lt;p&gt;There&#x27;s a consensus that generally, c is very fast, and python is very slow. But if we are talking about go and rust, you would find that rust is slightly faster than go. So from fastest to slowest: c, rust, go, python.&lt;&#x2F;p&gt;
&lt;p&gt;But what if you have go, python and rust calling c function? There would be more overhead, but how much?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;calling-c-from-go-python-and-rust&quot;&gt;Calling C from Go, Python and Rust&lt;a class=&quot;zola-anchor&quot; href=&quot;#calling-c-from-go-python-and-rust&quot; aria-label=&quot;Anchor link for: calling-c-from-go-python-and-rust&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;stats&quot;&gt;Stats&lt;a class=&quot;zola-anchor&quot; href=&quot;#stats&quot; aria-label=&quot;Anchor link for: stats&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2024&#x2F;10&#x2F;calling-c-from-go-python-and-rust-benchmark&#x2F;images&#x2F;01-stats-all.webp&quot; alt=&quot;01-stats-all.webp&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Turns out python has the most overhead.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2024&#x2F;10&#x2F;calling-c-from-go-python-and-rust-benchmark&#x2F;images&#x2F;02-stats-exclude-python.webp&quot; alt=&quot;02-stats-exclude-python.webp&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;But with go and rust, overheads are more or less negligible, with rust having the least overhead.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;execution-time&quot;&gt;Execution Time&lt;a class=&quot;zola-anchor&quot; href=&quot;#execution-time&quot; aria-label=&quot;Anchor link for: execution-time&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2024&#x2F;10&#x2F;calling-c-from-go-python-and-rust-benchmark&#x2F;images&#x2F;03-times-all.webp&quot; alt=&quot;03-times-all.webp&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You can see that python execution time plateaued, but go and rust are within the same range as c.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2024&#x2F;10&#x2F;calling-c-from-go-python-and-rust-benchmark&#x2F;images&#x2F;04-times-c-go-rust.webp&quot; alt=&quot;04-times-c-go-rust.webp&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You would also notice that go and c have random execution time peaks, but rust is the most stable in terms of execution time. Additionally, calling the same c code, using rust results in the most constant memory usage footprint.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-same-function-but-implemented-natively&quot;&gt;The Same Function But Implemented Natively&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-same-function-but-implemented-natively&quot; aria-label=&quot;Anchor link for: the-same-function-but-implemented-natively&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2024&#x2F;10&#x2F;calling-c-from-go-python-and-rust-benchmark&#x2F;images&#x2F;05-native-stats-all.webp&quot; alt=&quot;07-native-stats-all.webp&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s the same pattern if native functions are used instead of c foreign function interface.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;calling-c-vs-native-function&quot;&gt;Calling C vs Native Function&lt;a class=&quot;zola-anchor&quot; href=&quot;#calling-c-vs-native-function&quot; aria-label=&quot;Anchor link for: calling-c-vs-native-function&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2024&#x2F;10&#x2F;calling-c-from-go-python-and-rust-benchmark&#x2F;images&#x2F;06-all-stats-c-rust.webp&quot; alt=&quot;06-all-stats-c-rust.webp&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;But if we really have to compare CFFI and native function implementation, &lt;code&gt;pure rust&lt;&#x2F;code&gt; is faster than &lt;code&gt;rust calling c&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;side-by-side-comparison-for-go-and-rust&quot;&gt;Side-by-side Comparison for Go and Rust&lt;a class=&quot;zola-anchor&quot; href=&quot;#side-by-side-comparison-for-go-and-rust&quot; aria-label=&quot;Anchor link for: side-by-side-comparison-for-go-and-rust&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2024&#x2F;10&#x2F;calling-c-from-go-python-and-rust-benchmark&#x2F;images&#x2F;07-go-comparison.webp&quot; alt=&quot;07-go-comparison.webp&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Comparing &lt;code&gt;pure go&lt;&#x2F;code&gt; (in blue) and &lt;code&gt;go calling c&lt;&#x2F;code&gt;, pure go execution time is faster.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2024&#x2F;10&#x2F;calling-c-from-go-python-and-rust-benchmark&#x2F;images&#x2F;08-rust-comparison.webp&quot; alt=&quot;08-rust-comparison.webp&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;With &lt;code&gt;pure rust&lt;&#x2F;code&gt; (in rust) and &lt;code&gt;rust calling c&lt;&#x2F;code&gt; it&#x27;s still native implementation faster than CFFI, although with rust, the overhead is more or less negligible.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2024&#x2F;10&#x2F;calling-c-from-go-python-and-rust-benchmark&#x2F;images&#x2F;09-all-times-c-rust.webp&quot; alt=&quot;09-all-times-c-rust.webp&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;But if we really have to compare &lt;code&gt;c&lt;&#x2F;code&gt; and &lt;code&gt;pure rust&lt;&#x2F;code&gt; (in rust), c is still faster, but the difference here  is still negligible.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bonus&quot;&gt;Bonus&lt;a class=&quot;zola-anchor&quot; href=&quot;#bonus&quot; aria-label=&quot;Anchor link for: bonus&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2024&#x2F;10&#x2F;calling-c-from-go-python-and-rust-benchmark&#x2F;images&#x2F;10-all-stats-all.webp&quot; alt=&quot;10-all-stats-all.webp&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You can also call rust from python via pyo3. In which, for the same function implementation, it is waaaaay faster than CFFI!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;tldr&quot;&gt;TLDR&lt;a class=&quot;zola-anchor&quot; href=&quot;#tldr&quot; aria-label=&quot;Anchor link for: tldr&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Calling c from go and rust doesn&#x27;t have much overhead. But if you are calling c from python, that&#x27;s a very different story.&lt;&#x2F;li&gt;
&lt;li&gt;If we are talking about pure implementations, native rust is comparable to c.&lt;&#x2F;li&gt;
&lt;li&gt;For boosting python performance, utilizing pyo3 via rust is also a good option, since it brings the performance closer to go and rust.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</description>
      </item>
      <item>
          <title>LLM serving latency benchmark</title>
          <pubDate>Wed, 09 Oct 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2024/10/llm-serving-latency-benchmark/</link>
          <guid>https://karnwong.me/posts/2024/10/llm-serving-latency-benchmark/</guid>
          <description xml:base="https://karnwong.me/posts/2024/10/llm-serving-latency-benchmark/">&lt;p&gt;After the rise of ChatGPT in 2023, these days most people are familiar with the concept of LLM - Large Language Model. If you are LLM users, things are looking bright because there are gazillion options for you to choose from.&lt;&#x2F;p&gt;
&lt;p&gt;But if you are on the other side - creating and deploying LLMs, there are certain things you need to think about. For one, your implementation team would have languages&#x2F;frameworks they specialize in, so that&#x27;s already a constraint you have to work with when designing a solution.&lt;&#x2F;p&gt;
&lt;p&gt;Thankfully there are myriad of options to choose from to deploy LLMs, (see &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Hannibal046&#x2F;Awesome-LLM?tab=readme-ov-file#llm-deployment&quot;&gt;here&lt;&#x2F;a&gt;). Even easier if you don&#x27;t have to do fine-tuning, because you can serve up the model straightaway.&lt;&#x2F;p&gt;
&lt;p&gt;I picked following frameworks to test LLM serving performance:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Language&lt;&#x2F;th&gt;&lt;th&gt;Framework&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;C++&lt;&#x2F;td&gt;&lt;td&gt;Llamafile&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Go&lt;&#x2F;td&gt;&lt;td&gt;Ollama&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Python&lt;&#x2F;td&gt;&lt;td&gt;HuggingFace&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Rust&lt;&#x2F;td&gt;&lt;td&gt;mistral.rs&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;For experiment details, see &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kahnwong&#x2F;llm-serving-benchmark&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Model used: &lt;code&gt;gemma-2-2b-it&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s dive in!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;baseline-stats&quot;&gt;Baseline Stats&lt;a class=&quot;zola-anchor&quot; href=&quot;#baseline-stats&quot; aria-label=&quot;Anchor link for: baseline-stats&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2024&#x2F;10&#x2F;llm-serving-latency-benchmark&#x2F;images&#x2F;baseline-stats.webp&quot; alt=&quot;baseline-stats&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;From the chart, HuggingFace via Python takes longest to perform inferences. Llamafile via C++ and mistral.rs via Rust have similar performance, but Ollama via Go has slightly more latency. Ollama is written in Go, which probably explains higher latency due to garbage collection which is bundled in Go binaries.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2024&#x2F;10&#x2F;llm-serving-latency-benchmark&#x2F;images&#x2F;baseline-stats-cpp-rs.webp&quot; alt=&quot;baseline-stats-cpp-go.png&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Zooming in Llamafile and mistral.rs, it&#x27;s clear that mistral.rs performs better. This is most likely from the fact that Rust has better optimizations compared to C++.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;latency-per-iteration&quot;&gt;Latency per Iteration&lt;a class=&quot;zola-anchor&quot; href=&quot;#latency-per-iteration&quot; aria-label=&quot;Anchor link for: latency-per-iteration&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2024&#x2F;10&#x2F;llm-serving-latency-benchmark&#x2F;images&#x2F;latency-per-iteration.webp&quot; alt=&quot;img.png&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;All tests have 10 iterations. From the scatter plot, you can see that sometimes, Llamafile &#x2F; Ollama &#x2F; mistral.rs can have very similar performance, but often Ollama takes longer than Llamafile &#x2F; mistral.rs, which is in-line with the baseline stats from above section. Python still takes the longest, and does not seem to get lower than 14 seconds on each run.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2024&#x2F;10&#x2F;llm-serving-latency-benchmark&#x2F;images&#x2F;latency-per-iteration-cpp-rs.webp&quot; alt=&quot;img.png&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Zooming in Llama and mistral.rs, it is clear that mistral.rs has lower latency than Llamafile. Only once Llamafile performs better than mistral.rs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;takeaway&quot;&gt;Takeaway&lt;a class=&quot;zola-anchor&quot; href=&quot;#takeaway&quot; aria-label=&quot;Anchor link for: takeaway&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Development time and finding the right people to work with you to deploy LLM, Rust-based frameworks yield the best performance.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>AWS IAM credentials best practices</title>
          <pubDate>Sat, 05 Oct 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2024/10/aws-iam-credentials-best-practices/</link>
          <guid>https://karnwong.me/posts/2024/10/aws-iam-credentials-best-practices/</guid>
          <description xml:base="https://karnwong.me/posts/2024/10/aws-iam-credentials-best-practices/">&lt;p&gt;It&#x27;s hard to escape AWS, seeing how prevalent it is in global internet infrastructure. Chances are, most websites you visit are hosted on AWS.&lt;&#x2F;p&gt;
&lt;p&gt;As a software engineer, you probably encounter AWS at certain point in your career, and while getting AWS IAM credentials to work locally during development (via &lt;code&gt;aws-cli&lt;&#x2F;code&gt;) would suffice, sometimes in production land, you might need some adjustments.&lt;&#x2F;p&gt;
&lt;p&gt;Having worked with AWS extensively, here are what I found to be useful to keep in mind while working with AWS IAM credentials.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;disable-default-profile&quot;&gt;Disable &lt;code&gt;default&lt;&#x2F;code&gt; profile&lt;a class=&quot;zola-anchor&quot; href=&quot;#disable-default-profile&quot; aria-label=&quot;Anchor link for: disable-default-profile&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;When you first run &lt;code&gt;aws configure&lt;&#x2F;code&gt; it will ask you for &lt;code&gt;access key id&lt;&#x2F;code&gt; and &lt;code&gt;secret access key&lt;&#x2F;code&gt;. You can fill them, but you might accidentally delete or modify resources you didn&#x27;t intend to. And rectifying the state can be time-consuming. Generally, I find it better to explicitly specify a specific AWS profile whenever I&#x27;m interacting with AWS. This is so there is an extra guardrails layer. Additionally, you probably need to use different AWS profiles for each project &#x2F; service, might as well make it a habit.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;define-a-separate-read-only-and-read-write-profile&quot;&gt;Define a separate &lt;code&gt;read-only&lt;&#x2F;code&gt; and &lt;code&gt;read-write&lt;&#x2F;code&gt; profile&lt;a class=&quot;zola-anchor&quot; href=&quot;#define-a-separate-read-only-and-read-write-profile&quot; aria-label=&quot;Anchor link for: define-a-separate-read-only-and-read-write-profile&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Let&#x27;s say I&#x27;m working on a service where users can upload files to S3. During development, I would need to use creds with &lt;code&gt;read-write&lt;&#x2F;code&gt; permissions, because I&#x27;m going to be doing a lot of tests, and until I finish the development, there would be a lot of manual uploads&#x2F;deletes.&lt;&#x2F;p&gt;
&lt;p&gt;However, once things are deployed to production, I would spend more time investigating errors regarding this upload features, this would translate to &quot;verify that $image exists on S3&quot;, and this only requires &lt;code&gt;read-only&lt;&#x2F;code&gt; permission.&lt;&#x2F;p&gt;
&lt;p&gt;While it&#x27;s possible to use creds with &lt;code&gt;read-write&lt;&#x2F;code&gt; permissions, doing so on a prod bucket is like driving without wearing a seat belt. It works, but there is no extra layer of safety to prevent accidental oopsies, but it&#x27;s not so fun recovering the said images.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;grant-permissions-to-groups-not-users&quot;&gt;Grant permissions to groups, not users&lt;a class=&quot;zola-anchor&quot; href=&quot;#grant-permissions-to-groups-not-users&quot; aria-label=&quot;Anchor link for: grant-permissions-to-groups-not-users&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;This is generic for all RBAC situations, because it&#x27;s not fun to synchronize permissions for all users in a group.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;avoid-supplying-aws-iam-credentials-in-production&quot;&gt;Avoid supplying AWS IAM credentials in production&lt;a class=&quot;zola-anchor&quot; href=&quot;#avoid-supplying-aws-iam-credentials-in-production&quot; aria-label=&quot;Anchor link for: avoid-supplying-aws-iam-credentials-in-production&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;This applies to other cloud providers as well - generally cloud computes has an IAM role &#x2F; service account attached, which means you don&#x27;t have to explicitly inject IAM credentials to make it able to authenticate to AWS. And your security department would rejoice, because they don&#x27;t have to deal with yet another &quot;quarterly secrets rotation.&quot;&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>When (not) to use Terraform</title>
          <pubDate>Sat, 05 Oct 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2024/10/when-not-to-use-terraform/</link>
          <guid>https://karnwong.me/posts/2024/10/when-not-to-use-terraform/</guid>
          <description xml:base="https://karnwong.me/posts/2024/10/when-not-to-use-terraform/">&lt;p&gt;If we are talking about IaC, Terraform would be on the list. It made IaC popular and help a lot of companies maintain infrastructure at scale. Especially when you have multiple sets of infrastructures to maintain, Terraform can help you reduce the setup time tremendously via using Terraform Modules. Think of this like a function &#x2F; class in programming languages.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve been cranking out a lot of Terraform, a lot of trials and errors along the way. Picking other people&#x27;s brains by reading a lot of blog posts, trawl community forums to see how other people use Terraform and what are their challenges. Below are summarizations of what I&#x27;ve experienced, in addition to what the general sentiments are.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;terraform-is-great-for-foundational-resources&quot;&gt;Terraform is great for foundational resources&lt;a class=&quot;zola-anchor&quot; href=&quot;#terraform-is-great-for-foundational-resources&quot; aria-label=&quot;Anchor link for: terraform-is-great-for-foundational-resources&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Think of foundational resources as the first layer you have to build before you can deploy your apps. This would include databases, VPCs, virtual machines, storage volumes. These are rarely changed, or if you want to, downtimes can occur.&lt;&#x2F;p&gt;
&lt;p&gt;Out of all of these, it&#x27;s probably safest to only modify database configs and virtual machine specs, since it results in the least downtime.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;for-app-deployment-ymmv&quot;&gt;For app deployment, YMMV&lt;a class=&quot;zola-anchor&quot; href=&quot;#for-app-deployment-ymmv&quot; aria-label=&quot;Anchor link for: for-app-deployment-ymmv&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Although Terraform can also be used to deploy apps, it is not a good idea to have [foundational resources] in the same workspace as [app deployment].&lt;&#x2F;p&gt;
&lt;p&gt;This is because after initial app deployment, subsequent deployments should be done via CI&#x2F;CD, this essentially means [something else that&#x27;s not Terraform is updating the app deployment manifest]&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. This translates to [your Terraform state will constantly be out-of-sync].&lt;&#x2F;p&gt;
&lt;p&gt;This especially is a problem if your Terraform config uses &lt;code&gt;latest&lt;&#x2F;code&gt; for image tag. If your devs just rolled back a deployment to a previous SHA, if you apply this Terraform workspace, chances are you are going to override the deployment rollback (and this would make the devs confused as heck as to why their deployment is suddenly on the latest version after they just did a rollback).&lt;&#x2F;p&gt;
&lt;p&gt;But it&#x27;s never a no, because I still find it practical to initialize an app deployment in Terraform, but it&#x27;s in a separate workspace on a per-app basis. This means it won&#x27;t mess with other infra resources outside of app deployments.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;Technically you can use Terraform in CI&#x2F;CD for app deployment, but that&#x27;s another can of worms.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h2 id=&quot;if-you-can-use-it-to-set-up-provision-iam-users-access&quot;&gt;If you can, use it to set up &#x2F; provision IAM &lt;em&gt;users&lt;&#x2F;em&gt; access&lt;a class=&quot;zola-anchor&quot; href=&quot;#if-you-can-use-it-to-set-up-provision-iam-users-access&quot; aria-label=&quot;Anchor link for: if-you-can-use-it-to-set-up-provision-iam-users-access&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;I have a friend who works a lot with auditors, and he told me that most orgs fail auditing because they don&#x27;t have a process for IAM access provisioning. This means you can&#x27;t track who has access to what, or when the permissions had been granted to particular users&#x2F;groups.&lt;&#x2F;p&gt;
&lt;p&gt;It is very tedious, and it should be in a separate Terraform workspace. But if you can achieve this, you would have a single source-of-truth for RBAC.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Hello World API Performance Benchmark (Go, Node, Python, Rust)</title>
          <pubDate>Fri, 20 Sep 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2024/09/hello-world-api-performance-benchmark-go-node-python-rust/</link>
          <guid>https://karnwong.me/posts/2024/09/hello-world-api-performance-benchmark-go-node-python-rust/</guid>
          <description xml:base="https://karnwong.me/posts/2024/09/hello-world-api-performance-benchmark-go-node-python-rust/">&lt;p&gt;&lt;strong&gt;Correction 2024-09-21&lt;&#x2F;strong&gt;: after using multi-stage build, Node image size dropped from 1.1GB to 130MB.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;The first programming language I achieved proficiency was Python, so for the longest time I&#x27;ve been using it to do most
stuff. Last year I picked up Go, and I had a blast with it. This month I picked up Rust for data&#x2F;ml works, and so far I
was very impressed.&lt;&#x2F;p&gt;
&lt;p&gt;It got me thinking - it&#x27;s been said multiple times is Python is slower than compiled languages, and Node is very easy to
use but uses a lot of memory. Since I can code in multiple languages, why not do a simple API benchmark? So here&#x27;s the
results.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;docker-image-size&quot;&gt;Docker image size&lt;a class=&quot;zola-anchor&quot; href=&quot;#docker-image-size&quot; aria-label=&quot;Anchor link for: docker-image-size&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;It&#x27;s a given that when you compile your code into a binary, it would be smaller than adding the whole runtime and
dependencies into an image.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Language&lt;&#x2F;th&gt;&lt;th&gt;Image Size (MB)&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Go&lt;&#x2F;td&gt;&lt;td&gt;13.4&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Node&lt;&#x2F;td&gt;&lt;td&gt;130&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Python&lt;&#x2F;td&gt;&lt;td&gt;146&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Rust&lt;&#x2F;td&gt;&lt;td&gt;8.63&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;resources-utilization-on-startup&quot;&gt;Resources utilization on startup&lt;a class=&quot;zola-anchor&quot; href=&quot;#resources-utilization-on-startup&quot; aria-label=&quot;Anchor link for: resources-utilization-on-startup&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Once we deploy the APIs, this is how much resources they consume on startup.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Language&lt;&#x2F;th&gt;&lt;th&gt;CPU Utilization&lt;&#x2F;th&gt;&lt;th&gt;Memory Utilization&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Go&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Node&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;56&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Python&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;35&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Rust&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;0*&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;*This is a round-down, which means it utilizes really low amount of RAM.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;api-performance&quot;&gt;API Performance&lt;a class=&quot;zola-anchor&quot; href=&quot;#api-performance&quot; aria-label=&quot;Anchor link for: api-performance&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;total-requests-and-response-time&quot;&gt;Total Requests and Response Time&lt;a class=&quot;zola-anchor&quot; href=&quot;#total-requests-and-response-time&quot; aria-label=&quot;Anchor link for: total-requests-and-response-time&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Given concurrent &lt;code&gt;5000 VUs&lt;&#x2F;code&gt; for &lt;code&gt;120s&lt;&#x2F;code&gt;, here is total requests you can make in a given duration, with response time.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Language&lt;&#x2F;th&gt;&lt;th&gt;Total Requests&lt;&#x2F;th&gt;&lt;th&gt;AVG RT&lt;&#x2F;th&gt;&lt;th&gt;MIN RT&lt;&#x2F;th&gt;&lt;th&gt;MEDIAN RT&lt;&#x2F;th&gt;&lt;th&gt;MAX RT&lt;&#x2F;th&gt;&lt;th&gt;P95 RT&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Go&lt;&#x2F;td&gt;&lt;td&gt;898,131&lt;&#x2F;td&gt;&lt;td&gt;335.77ms&lt;&#x2F;td&gt;&lt;td&gt;1.78ms&lt;&#x2F;td&gt;&lt;td&gt;239.55ms&lt;&#x2F;td&gt;&lt;td&gt;33.38s&lt;&#x2F;td&gt;&lt;td&gt;914.37ms&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Node*&lt;&#x2F;td&gt;&lt;td&gt;383,091&lt;&#x2F;td&gt;&lt;td&gt;823.61ms&lt;&#x2F;td&gt;&lt;td&gt;2.29ms&lt;&#x2F;td&gt;&lt;td&gt;393.98ms&lt;&#x2F;td&gt;&lt;td&gt;33.75s&lt;&#x2F;td&gt;&lt;td&gt;1.41s&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Python*&lt;&#x2F;td&gt;&lt;td&gt;225,929&lt;&#x2F;td&gt;&lt;td&gt;1.42s&lt;&#x2F;td&gt;&lt;td&gt;3.15ms&lt;&#x2F;td&gt;&lt;td&gt;861.22ms&lt;&#x2F;td&gt;&lt;td&gt;35.37s&lt;&#x2F;td&gt;&lt;td&gt;1.98s&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Rust&lt;&#x2F;td&gt;&lt;td&gt;901,038&lt;&#x2F;td&gt;&lt;td&gt;408.57ms&lt;&#x2F;td&gt;&lt;td&gt;2ms&lt;&#x2F;td&gt;&lt;td&gt;274.13ms&lt;&#x2F;td&gt;&lt;td&gt;40.77s&lt;&#x2F;td&gt;&lt;td&gt;901.35ms&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;*Container restarted during peak load&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;For total requests, we can see that Go and Rust have very similar performance, while being the most performant of all.
And Node is faster than Python, but still significantly slower than Go&#x2F;Rust.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2024&#x2F;09&#x2F;hello-world-api-performance-benchmark-go-node-python-rust&#x2F;images&#x2F;total-requests.webp&quot; alt=&quot;total-requests.webp&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;But if we are talking about response time, it is very apparent that python is the least performant of all. Go and Rust
is a tie.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2024&#x2F;09&#x2F;hello-world-api-performance-benchmark-go-node-python-rust&#x2F;images&#x2F;response-time.webp&quot; alt=&quot;response-time.webp&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;peak-resources-utilization&quot;&gt;Peak Resources utilization&lt;a class=&quot;zola-anchor&quot; href=&quot;#peak-resources-utilization&quot; aria-label=&quot;Anchor link for: peak-resources-utilization&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Turns out Node is the most resource hungry, and Rust uses slightly more CPU than Go.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Language&lt;&#x2F;th&gt;&lt;th&gt;CPU (Mi)&lt;&#x2F;th&gt;&lt;th&gt;Memory (MB)&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Go&lt;&#x2F;td&gt;&lt;td&gt;410&lt;&#x2F;td&gt;&lt;td&gt;52.48&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Node&lt;&#x2F;td&gt;&lt;td&gt;1000&lt;&#x2F;td&gt;&lt;td&gt;203.17&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Python&lt;&#x2F;td&gt;&lt;td&gt;1000&lt;&#x2F;td&gt;&lt;td&gt;67.01&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Rust&lt;&#x2F;td&gt;&lt;td&gt;492&lt;&#x2F;td&gt;&lt;td&gt;45.49&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2024&#x2F;09&#x2F;hello-world-api-performance-benchmark-go-node-python-rust&#x2F;images&#x2F;peak-resources-all.webp&quot; alt=&quot;peak-resources-all.webp&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Zooming in on Go and Rust, we can see that Go uses slightly less CPU but more memory than Rust.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;a class=&quot;zola-anchor&quot; href=&quot;#conclusion&quot; aria-label=&quot;Anchor link for: conclusion&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Python and Node take up the most image size.&lt;&#x2F;li&gt;
&lt;li&gt;Go and Rust consume the least amount of resources and have very similar performance. While the differences are almost negligible, Rust can serve more requests.&lt;&#x2F;li&gt;
&lt;li&gt;Node is faster than Python, but utilizes more resources.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</description>
      </item>
      <item>
          <title>Simplify self-hosting backups to S3 with docker</title>
          <pubDate>Sat, 07 Sep 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2024/09/simplify-self-hosting-backups-to-s3-with-docker/</link>
          <guid>https://karnwong.me/posts/2024/09/simplify-self-hosting-backups-to-s3-with-docker/</guid>
          <description xml:base="https://karnwong.me/posts/2024/09/simplify-self-hosting-backups-to-s3-with-docker/">&lt;p&gt;These days there are multiple ways to deploy a workload, be it cloud-based or bare-metal. For cloud, depending on whether you are using PaaS or IaaS, backup options can vary.&lt;&#x2F;p&gt;
&lt;p&gt;Why do we need to backup? Because your workloads can contain a state, this can be stored as local files, inside a database, or as other assets outside the application itself.&lt;&#x2F;p&gt;
&lt;p&gt;Take a database for example, ideally you would need a daily backup so you can revert a database to a state before its corruption without losing as much data. Some workloads might store uploaded images, for simplicity let&#x27;s say they are being written to disk.&lt;&#x2F;p&gt;
&lt;p&gt;For a backup, it can be as simple as running a database dump command, or compress a data directory and save it somewhere. Following the rule of thumb: you should have off-site backups.&lt;&#x2F;p&gt;
&lt;p&gt;In cloud, a managed database would have daily backups as a built-in feature, offloading users from setting up the backup operation themselves.&lt;&#x2F;p&gt;
&lt;p&gt;But in a bare-metal setup (which also applies for self-hosting), you need to somehow store the backup artifacts in, say, AWS S3. And there&#x27;s a lot of commands involved:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;current_date&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;$(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;date&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; +%Y-%m-%d&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;backup_bucket&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell z-string&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell z-string&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;BUCKET_NAME&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:-&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;backup&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;backup_prefix&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;s3:&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;backup_bucket&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;current_date&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;filename&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;SERVICE_NAME&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-sqldump-&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;current_date&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.bin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;PGPASSWORD&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;POSTGRES_PASSWORD&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; pg_dump&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;Fc&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;c&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;U&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;POSTGRES_USERNAME&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-host&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;POSTGRES_HOSTNAME&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;filename&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;aws&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s3&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; cp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell z-string&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell z-string&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;aws_args&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;filename&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;backup_prefix&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;filename&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Creating a bash script can work, but this means you have to install required binaries or else the script won&#x27;t be able to execute. In which after this you can parameterize the inputs.&lt;&#x2F;p&gt;
&lt;p&gt;The final step would involve setting up a cronjob, which is unavoidable, but doing the path logistics is not fun. Additionally, testing a crontab is very clunky, it would involve editing the crontabs to trigger in a minute from now. And when it&#x27;s triggered, you can&#x27;t see logs in real-time.&lt;&#x2F;p&gt;
&lt;p&gt;But crontabs still execute commands, why not package this into a docker image, so a backup job would essentially be a &lt;code&gt;docker run&lt;&#x2F;code&gt; command? This way it&#x27;s easier to debug, all dependencies are accounted for, and you can use it anywhere without setting up the environment (you still need docker, but you are unlikely to mess up a docker installation).&lt;&#x2F;p&gt;
&lt;p&gt;So when tying it all together, a Dockerfile would contain following binaries (so we can backup postgres or a path, and push it to s3):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;docker&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method&quot;&gt;FROM&lt;&#x2F;span&gt;&lt;span&gt; nixos&#x2F;nix:latest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; nix-channel --update&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; nix-env -iA nixpkgs.bash &amp;amp;&amp;amp; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  nix-env -iA nixpkgs.gnutar &amp;amp;&amp;amp; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  nix-env -iA nixpkgs.gzip &amp;amp;&amp;amp; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  nix-env -iA nixpkgs.curl &amp;amp;&amp;amp; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  nix-env -iA nixpkgs.postgresql_16 &amp;amp;&amp;amp; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  nix-env -iA nixpkgs.awscli2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; set entrypoint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method&quot;&gt;WORKDIR&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;opt&#x2F;backup&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method&quot;&gt;COPY&lt;&#x2F;span&gt;&lt;span&gt; entrypoint.sh .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; chmod +x entrypoint.sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method&quot;&gt;ENTRYPOINT&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bash&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;entrypoint.sh&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Notice the entrypoint. Essentially it would take in environment variables, and run the backup commands, then push it to s3. After a successful upload, send a notification.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#!&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;bin&#x2F;bash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ----------------- VARS ----------------- #&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;MODE= # `ARCHIVE`, `DB_POSTGRES`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;SERVICE_NAME=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;BACKUP_PATH=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;BUCKET_NAME=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;BACKUP_PATH_EXCLUDE= # optional&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;POSTGRES_USERNAME=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;POSTGRES_PASSWORD=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;POSTGRES_HOSTNAME=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;S3_ENDPOINT= # optional&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; either of this&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;NTFY_TOPIC_URL&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;DISCORD_WEBHOOK_URL&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; set filename&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;current_date&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;$(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;date&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; +%Y-%m-%d&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;backup_bucket&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell z-string&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell z-string&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;BUCKET_NAME&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:-&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;backup&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;backup_prefix&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;s3:&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;backup_bucket&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;current_date&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; backup&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;MODE&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-logical&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ARCHIVE&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; ]&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt; filename&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;SERVICE_NAME&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;current_date&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.tar.gz&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ref: https:&#x2F;&#x2F;stackoverflow.com&#x2F;a&#x2F;42985721&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt; tar_args&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-array&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-array&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt; -v BACKUP_PATH_EXCLUDE &lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  tar_args&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment z-compound&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-array&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;c&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;l&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;BACKUP_PATH_EXCLUDE&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-array&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt; tar_args&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment z-compound&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-array&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;c&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;z&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;filename&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;BACKUP_PATH&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-array&quot;&gt; )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; tar&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell z-string&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell z-string&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;tar_args&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;elif&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;MODE&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-logical&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;DB_POSTGRES&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; ]&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt; filename&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;SERVICE_NAME&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-sqldump-&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;current_date&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.bin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt; PGPASSWORD&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;POSTGRES_PASSWORD&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; pg_dump&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;Fc&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;c&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;U&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;POSTGRES_USERNAME&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-host&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;POSTGRES_HOSTNAME&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;filename&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt; echo&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;MODE&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; is not supported&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; upload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;aws_args&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-array&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-array&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt; -v S3_ENDPOINT &lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt; aws_args&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment z-compound&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-array&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;o&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;l&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;S3_ENDPOINT&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-array&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;aws&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s3&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; cp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell z-string&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell z-string&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;aws_args&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;filename&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;backup_prefix&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;filename&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; notify&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;notify_message&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Successfully backup &lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;SERVICE_NAME&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt; -v NTFY_TOPIC_URL &lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; curl&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;notify_message&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;NTFY_TOPIC_URL&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;elif&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt; -v DISCORD_WEBHOOK_URL &lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; curl&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;H&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Accept: application&#x2F;json&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;H&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Content-Type:application&#x2F;json&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;X&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; POST&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-data&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;content&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;: &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;notify_message&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;DISCORD_WEBHOOK_URL&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt; echo&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Cannot send a notification since no notification backend has been configured.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Personally I use Kubernetes for self-hosting, but I have a few services on a small VPS using docker. This setup means I can use the same method to backup docker or kubernetes workloads.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Streamlit load test performance</title>
          <pubDate>Sat, 07 Sep 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2024/09/streamlit-load-test-performance/</link>
          <guid>https://karnwong.me/posts/2024/09/streamlit-load-test-performance/</guid>
          <description xml:base="https://karnwong.me/posts/2024/09/streamlit-load-test-performance/">&lt;p&gt;Streamlit is well-loved by many people, especially among data folks due to the fact that it does not require prior web programming knowledge to get started.&lt;&#x2F;p&gt;
&lt;p&gt;Popular use cases for streamlit can be anything from a quick machine learning application poc or internal dashboards. But what if you want to create a production deployment? Would streamlit still be a viable option?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;experiment-setup&quot;&gt;Experiment setup&lt;a class=&quot;zola-anchor&quot; href=&quot;#experiment-setup&quot; aria-label=&quot;Anchor link for: experiment-setup&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;For a production deployment, let&#x27;s assume there are 500 concurrent users. For a single-page streamlit with a chat box taking 3 seconds to return a single-paragraph message:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2024&#x2F;09&#x2F;streamlit-load-test-performance&#x2F;images&#x2F;streamlit-ui.webp&quot; alt=&quot;streamlit-ui.webp&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;With following configuration for the load test:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;c&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;onfig&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  p&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;hases&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;    -&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;uration&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 100&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      a&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;rrivalRate&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 50&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      m&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;axVusers&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 500&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;benchmark-result&quot;&gt;Benchmark result&lt;a class=&quot;zola-anchor&quot; href=&quot;#benchmark-result&quot; aria-label=&quot;Anchor link for: benchmark-result&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;--------------------------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Summary&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; report&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; @&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; 12:50:35&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;+0700&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;--------------------------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;browser.http_requests:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ...................................................&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 5926&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;browser.page.TTFB.http:&#x2F;&#x2F;localhost:8501&#x2F;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;  min:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ...................................................................&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;  max:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ...................................................................&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 19934.3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;  mean:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ..................................................................&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 6975.6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;  median:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ................................................................&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 7260.8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;  p95:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ...................................................................&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 16486.1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;  p99:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ...................................................................&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 18963.6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;browser.page.codes.200:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ..................................................&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 5950&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;errors.page.goto:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; Timeout&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; 30000ms&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; exceeded.:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; .............................&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1486&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;errors.page.goto:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; net::ERR_CONNECTION_RESET&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; at&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; http:&#x2F;&#x2F;localhost:8501&#x2F;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ...&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;vusers.completed:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ........................................................&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 421&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;vusers.created:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ..........................................................&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1916&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;vusers.created_by_name.0:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ................................................&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1916&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;vusers.failed:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ...........................................................&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1495&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;vusers.session_length:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;  min:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ...................................................................&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1874.4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;  max:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ...................................................................&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 30379.4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;  mean:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ..................................................................&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 23027.7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;  median:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ................................................................&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 25598.5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;  p95:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ...................................................................&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 30040.3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;  p99:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ...................................................................&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 30040.3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;vusers.skipped:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ..........................................................&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 3084&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Notice the &lt;code&gt;median&lt;&#x2F;code&gt; value of &lt;code&gt;25598.5&lt;&#x2F;code&gt;, this is roughly around &lt;code&gt;25 seconds&lt;&#x2F;code&gt; to render the above streamlit page.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;takeaway&quot;&gt;Takeaway&lt;a class=&quot;zola-anchor&quot; href=&quot;#takeaway&quot; aria-label=&quot;Anchor link for: takeaway&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Moral of the story: streamlit is great for a quick poc or low traffic apps. Anything more than this and you should consider using a dedicated web framework to create the frontend.&lt;&#x2F;p&gt;
&lt;p&gt;Also, yes, CPU and memory usage also shot up.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Reasons why you shouldn&#x27;t use programming languages for IaC</title>
          <pubDate>Mon, 05 Aug 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2024/08/reasons-why-you-shouldnt-use-programming-languages-for-iac/</link>
          <guid>https://karnwong.me/posts/2024/08/reasons-why-you-shouldnt-use-programming-languages-for-iac/</guid>
          <description xml:base="https://karnwong.me/posts/2024/08/reasons-why-you-shouldnt-use-programming-languages-for-iac/">&lt;p&gt;When it comes to IaC (infrastructure as code), most people might have heard of HashiCorp&#x27;s Terraform (it uses HCL as DSL. Interestingly enough, Terraform also has its own CDK to translate programming languages into HCL), Pulumi or AWS CDK. The latter two support programming languages as DSL.&lt;&#x2F;p&gt;
&lt;p&gt;Mostly there are two camps:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;People who swear by HCL and think you shouldn&#x27;t use programming languages for IaC&lt;&#x2F;li&gt;
&lt;li&gt;People who don&#x27;t see why you need to pick up a new language in order to use IaC, so they prefer using a programming language they already are familiar with instead&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Both camps are not wrong, they are both valid. However, I want to share my take on why you should use HCL for IaC.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;pros-for-using-programming-languages&quot;&gt;Pros for using programming languages&lt;a class=&quot;zola-anchor&quot; href=&quot;#pros-for-using-programming-languages&quot; aria-label=&quot;Anchor link for: pros-for-using-programming-languages&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;The obvious perk is that you don&#x27;t need to pick up a new language, which means you can get started right away to enjoy the benefits of IaC.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cons&quot;&gt;Cons&lt;a class=&quot;zola-anchor&quot; href=&quot;#cons&quot; aria-label=&quot;Anchor link for: cons&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;However, when you are looking for resources or templates, you might find it harder because there are many different implementations to achieve the same thing, due to the nature of programming languages where it allows for flexibility. To create a single VM inside a VPC, you can run into many different examples, depending on how people define the IaC.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, if you are using less popular languages (golang, for instance) you might have fewer references than people who use javascript&#x2F;typescript or python.&lt;&#x2F;p&gt;
&lt;p&gt;As for IaC codebase maintenance, you would have to find people who:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Can use your programming language of choice for IaC&lt;&#x2F;li&gt;
&lt;li&gt;Understands devops and infrastructure&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Which would significantly reduce your candidate pools, whereas if you use HCL (a DSL, which means it&#x27;s less complex than a programming language, and by definition, has less learning curve), you would not be limited by the fact that your candidate has to know a specific programming language.&lt;&#x2F;p&gt;
&lt;p&gt;The same argument can be made that you still have to find people who know HCL, but being a DSL, it takes less time to get familiar with it. (Some notes on this: some people find it really hard to pick up a new language&#x2F;DSL&#x2F;whathaveyou. So it&#x27;s understandable if they prefer to use a familiar programming language for IaC, and there&#x27;s nothing wrong with that.)&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>GCP&#x27;s service account credentials can be a security risk. Here&#x27;s how to mitigate them.</title>
          <pubDate>Sun, 14 Jul 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2024/07/gcps-service-account-credentials-can-be-a-security-risk-heres-how-to-mitigate-them/</link>
          <guid>https://karnwong.me/posts/2024/07/gcps-service-account-credentials-can-be-a-security-risk-heres-how-to-mitigate-them/</guid>
          <description xml:base="https://karnwong.me/posts/2024/07/gcps-service-account-credentials-can-be-a-security-risk-heres-how-to-mitigate-them/">&lt;p&gt;If you look online, many sources would tell you that you should use service account to authenticate for GCP services. While this is true, it&#x27;s not for all the cases.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;for-local-development-you-should-use-application-default-credentials&quot;&gt;For local development, you should use Application Default Credentials&lt;a class=&quot;zola-anchor&quot; href=&quot;#for-local-development-you-should-use-application-default-credentials&quot; aria-label=&quot;Anchor link for: for-local-development-you-should-use-application-default-credentials&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Imagine working in a team, and you have to work with Cloud Run, so you request your infra team for a service account. This looks good, but then your teammates also have to work with this service. They happen to be in a hurry, so you share your service account to your teammates. Now this can be a problem, because now there are multiple users who have access to this service account. It would be very tricky to trawl through the audit logs and identify which developer interact with cloud run, because the system only sees a single identity.&lt;&#x2F;p&gt;
&lt;p&gt;This is why for a local development workflow, application default credentials should be used to authenticate to GCP. Essentially you perform a login action via the gcloud command line and set ADC, it would then leave a credential file in your local filesystem. Other Google&#x2F;GCP SDKs can then pick this up and use it to authenticate to GCP services. This also adds a benefit that no credentials have to be generated, meaning there&#x27;s no cleanup overhead.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;for-cross-perimeter-authentication-only-required-personnel-should-be-able-to-access-the-credentials&quot;&gt;For cross-perimeter authentication, only required personnel should be able to access the credentials&lt;a class=&quot;zola-anchor&quot; href=&quot;#for-cross-perimeter-authentication-only-required-personnel-should-be-able-to-access-the-credentials&quot; aria-label=&quot;Anchor link for: for-cross-perimeter-authentication-only-required-personnel-should-be-able-to-access-the-credentials&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;But if we are talking a deployment, it&#x27;s possible that you need to have $serviceA talks to $serviceB. In GCP, you can assign service account to the compute directly, as this method doesn&#x27;t require generating a credentials.&lt;&#x2F;p&gt;
&lt;p&gt;But there&#x27;s also cases where you have to access GCP services from outside of GCP. For example, using Fivetran to read data from BigQuery. Unfortunately this method requires creating a credential tied to a service account. This can become a risk if you don&#x27;t limit permission for who can create &#x2F; view credentials. Following the principle of least privilege can in turn mitigate unauthorized actors from accessing service account credentials.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Thoughts on summarization service system design</title>
          <pubDate>Sun, 09 Jun 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2024/06/thoughts-on-summarization-service-system-design/</link>
          <guid>https://karnwong.me/posts/2024/06/thoughts-on-summarization-service-system-design/</guid>
          <description xml:base="https://karnwong.me/posts/2024/06/thoughts-on-summarization-service-system-design/">&lt;p&gt;For a summarization task, there should be an input, in which it&#x27;s reduced to a handful of paragraphs. This input is in text format.
You don&#x27;t necessarily start from a text format though, since the source content can be audio or video files. But this means at the end, the source input has to be converted into a text format, and this involves a &lt;code&gt;transcription&lt;&#x2F;code&gt; task.&lt;&#x2F;p&gt;
&lt;p&gt;Transcription means taking an audio, then convert it to text. Luckily these days there are APIs you can use to achieve this. Depending on each API provider, but it&#x27;s safe to assume most would support &lt;code&gt;WAVE&lt;&#x2F;code&gt; or &lt;code&gt;FLAC&lt;&#x2F;code&gt; encoding.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;audio-formats&quot;&gt;Audio formats&lt;a class=&quot;zola-anchor&quot; href=&quot;#audio-formats&quot; aria-label=&quot;Anchor link for: audio-formats&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Audio formats can be categorized into two main groups: lossless and lossy. Lossless means all information are preserved, and can be converted between any lossless format without losing data. For example, going from &lt;code&gt;WAVE -&amp;gt; FLAC&lt;&#x2F;code&gt; should allow you to convert the resulting &lt;code&gt;FLAC -&amp;gt; WAVE&lt;&#x2F;code&gt; without losing quality.&lt;&#x2F;p&gt;
&lt;p&gt;However, when you convert &lt;code&gt;MP3 -&amp;gt; WAVE&lt;&#x2F;code&gt;, this is a lossy to lossless format, which means the resulting &lt;code&gt;WAVE&lt;&#x2F;code&gt; file would contain as much information as the MP3 file.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-does-audio-format-matter&quot;&gt;Why does audio format matter&lt;a class=&quot;zola-anchor&quot; href=&quot;#why-does-audio-format-matter&quot; aria-label=&quot;Anchor link for: why-does-audio-format-matter&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;If you read &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cloud.google.com&#x2F;speech-to-text&#x2F;docs&#x2F;encoding#lossless_compression&quot;&gt;GCP&#x27;s Cloud Speech-to-Text docs&lt;&#x2F;a&gt;, it would tell you that using &lt;code&gt;FLAC&lt;&#x2F;code&gt; is better if you are conscious about storage.
This is good and all, but the caveats (not mentioned in the docs) is that, if you convert a lossy format (which is very common in videos) to FLAC, it would take a lot longer than converting it to WAVE. This is because WAVE is an &lt;code&gt;uncompressed&lt;&#x2F;code&gt; format, which means there&#x27;s less conversion overhead, seeing FLAC utilizes a heavy compression.&lt;&#x2F;p&gt;
&lt;p&gt;We are talking about &lt;code&gt;48 hours&lt;&#x2F;code&gt; conversion time vs &lt;code&gt;a few minutes&lt;&#x2F;code&gt;. Compute is cheap, but storage is cheaper.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-about-calling-patterns&quot;&gt;What about calling patterns&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-about-calling-patterns&quot; aria-label=&quot;Anchor link for: what-about-calling-patterns&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Both transcription and summarization can take quite a while (longer than a few minutes). It does not make sense to throw the entire logic into a function and have your api return it as-is, since it would leave a connection open, and if your workloads are interrupted, all progress are lost.
Which is why an event-based approach is a better fit for this scenario. Initial api call would trigger an event, and serverless functions (one for each transcription and summarization) run these tasks, when completed a status is updated into the database. Frontend can poll the backend every few seconds to fetch the status of these long-running operations.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-if-you-are-lazy-and-just-want-to-only-create-a-single-backend&quot;&gt;What if you are lazy and just want to only create a single backend?&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-if-you-are-lazy-and-just-want-to-only-create-a-single-backend&quot; aria-label=&quot;Anchor link for: what-if-you-are-lazy-and-just-want-to-only-create-a-single-backend&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Sure, it can work. As per anything in this universe: if you try hard enough, it will somehow work. But good luck explaining to your users why it takes forever to see a response on the web UI.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Faster spark workloads with Comet</title>
          <pubDate>Sun, 07 Apr 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2024/04/faster-spark-workloads-with-comet/</link>
          <guid>https://karnwong.me/posts/2024/04/faster-spark-workloads-with-comet/</guid>
          <description xml:base="https://karnwong.me/posts/2024/04/faster-spark-workloads-with-comet/">&lt;p&gt;For big data processing, spark is still king. Over the years, many improvements have been made to improve spark performance. Databricks themselves created &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.databricks.com&#x2F;product&#x2F;photon&quot;&gt;photon&lt;&#x2F;a&gt;, a spark engine that can accelerate spark queries, but this is proprietary to Databricks.&lt;&#x2F;p&gt;
&lt;p&gt;Other alternatives do exist (see &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arrow.apache.org&#x2F;blog&#x2F;2024&#x2F;03&#x2F;06&#x2F;comet-donation&#x2F;&quot;&gt;here&lt;&#x2F;a&gt; for more details), but they are not trivial to setup.&lt;&#x2F;p&gt;
&lt;p&gt;But if you use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;apache&#x2F;arrow-datafusion-comet&quot;&gt;Apache Arrow DataFusion Comet&lt;&#x2F;a&gt;, surprisingly it does not take much time at all to setup. Comet stands on arrow, a data format growing in popularity.&lt;&#x2F;p&gt;
&lt;p&gt;For a start, you would need to compile a jar (you need rust and maven), and good news is comet also supports spark 3.4 (as of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;apache&#x2F;arrow-datafusion-comet#current-status&quot;&gt;2024-04-07&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Then it&#x27;s the usual: add a jar to spark jars path, and configure spark session to use comet:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;spark&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    SparkSession&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;builder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;config&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;spark.executor.memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;8g&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;config&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;spark.driver.memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;8g&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; comet configs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;config&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;spark.sql.extensions&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;org.apache.comet.CometSparkSessionExtensions&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;config&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;spark.comet.enabled&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;true&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;config&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;spark.comet.exec.enabled&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;true&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;config&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;spark.comet.exec.all.enabled&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;true&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;getOrCreate&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;result&quot;&gt;Result&lt;a class=&quot;zola-anchor&quot; href=&quot;#result&quot; aria-label=&quot;Anchor link for: result&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;For a simple group by query, using comet results in 30% faster execution time on average.
At most, it can be up to 64% faster.
&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2024&#x2F;04&#x2F;faster-spark-workloads-with-comet&#x2F;images&#x2F;spark-engine-query-performance.webp&quot; alt=&quot;img.png&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;remarks&quot;&gt;Remarks&lt;a class=&quot;zola-anchor&quot; href=&quot;#remarks&quot; aria-label=&quot;Anchor link for: remarks&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;However, if you look at comet architecture diagram:
&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2024&#x2F;04&#x2F;faster-spark-workloads-with-comet&#x2F;images&#x2F;comet-architecture.webp&quot; alt=&quot;img.png&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This means that for certain operations, comet fallbacks to JVM for execution. If I update the benchmark query to perform window and join, the performance gain from comet is negligible.&lt;&#x2F;p&gt;
&lt;p&gt;Comet is still in its early stages, but if your workloads is query-only (ie no window or join - transformations) comet should significantly reduce your workloads runtime.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Slim down Python Docker image size with Poetry and Pip</title>
          <pubDate>Sun, 07 Apr 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2024/04/slim-down-python-docker-image-size-with-poetry-and-pip/</link>
          <guid>https://karnwong.me/posts/2024/04/slim-down-python-docker-image-size-with-poetry-and-pip/</guid>
          <description xml:base="https://karnwong.me/posts/2024/04/slim-down-python-docker-image-size-with-poetry-and-pip/">&lt;p&gt;Python package management is not straightforward, seeing default package manager (pip) does not behave like node&#x27;s npm, in a sense that it doesn&#x27;t track dependencies versions.&lt;&#x2F;p&gt;
&lt;p&gt;This is why you should use &lt;code&gt;poetry&lt;&#x2F;code&gt; to manage python packages, since it creates a lock file, so you can be sure that on every re-install, the versions would be the same.&lt;&#x2F;p&gt;
&lt;p&gt;However, this poses a challenge when you want to create a docker image with poetry, because you need to do an extra &lt;code&gt;pip install poetry&lt;&#x2F;code&gt; (unless you bake this into your base python image). Additionally, turns out using poetry to install packages results in larger docker image size.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;dockerfiles&quot;&gt;Dockerfiles&lt;a class=&quot;zola-anchor&quot; href=&quot;#dockerfiles&quot; aria-label=&quot;Anchor link for: dockerfiles&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Below are dockerfiles I use to compare between using &lt;code&gt;poetry&lt;&#x2F;code&gt; and &lt;code&gt;pip&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;dockerfile-poetry&quot;&gt;Dockerfile.poetry&lt;a class=&quot;zola-anchor&quot; href=&quot;#dockerfile-poetry&quot; aria-label=&quot;Anchor link for: dockerfile-poetry&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;docker&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method&quot;&gt;FROM&lt;&#x2F;span&gt;&lt;span&gt; python:3.12-slim&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method&quot;&gt;WORKDIR&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;app&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; hadolint ignore=DL3013&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; pip install --no-cache-dir poetry&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method&quot;&gt;COPY&lt;&#x2F;span&gt;&lt;span&gt; pyproject.toml .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method&quot;&gt;COPY&lt;&#x2F;span&gt;&lt;span&gt; poetry.lock .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; poetry install --only main --no-root --no-directory&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;dockerfile-pip&quot;&gt;Dockerfile.pip&lt;a class=&quot;zola-anchor&quot; href=&quot;#dockerfile-pip&quot; aria-label=&quot;Anchor link for: dockerfile-pip&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;docker&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method&quot;&gt;FROM&lt;&#x2F;span&gt;&lt;span&gt; python:3.12-slim&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method&quot;&gt;WORKDIR&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;app&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method&quot;&gt;COPY&lt;&#x2F;span&gt;&lt;span&gt; requirements.txt .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; pip install -r requirements.txt --no-cache-dir&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;installed-packages&quot;&gt;Installed packages&lt;a class=&quot;zola-anchor&quot; href=&quot;#installed-packages&quot; aria-label=&quot;Anchor link for: installed-packages&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;toml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;requests&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;^2.31.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;polars&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;^0.20.18&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;fastapi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;^0.110.1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;pydantic&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;^2.6.4&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;python-dotenv&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;^1.0.1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;langchain&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;^0.1.14&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;psycopg2-binary&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;^2.9.9&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;result&quot;&gt;Result&lt;a class=&quot;zola-anchor&quot; href=&quot;#result&quot; aria-label=&quot;Anchor link for: result&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;And the resulting image size is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;log&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;benchmark_poetry      latest            23d3105ad0dd   &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt; seconds ago   520MB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;benchmark_pip         latest            b7932a02a8d1   &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt; hours ago     388MB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As you can see, using poetry makes the image &lt;code&gt;132 MB&lt;&#x2F;code&gt; larger. Let&#x27;s say you deploy 12 times per month, that&#x27;s extra &lt;code&gt;1584 MB&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;While I agree that these days storage is cheap, reducing images size here and there won&#x27;t hurt 😎.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Dataframe write performance to Postgres</title>
          <pubDate>Sun, 17 Mar 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2024/03/dataframe-write-performance-to-postgres/</link>
          <guid>https://karnwong.me/posts/2024/03/dataframe-write-performance-to-postgres/</guid>
          <description xml:base="https://karnwong.me/posts/2024/03/dataframe-write-performance-to-postgres/">&lt;p&gt;Previously, I talked about &lt;a href=&quot;&#x2F;posts&#x2F;2023&#x2F;04&#x2F;duckdb-vs-polars-vs-spark&quot;&gt;dataframe performance&lt;&#x2F;a&gt;, but this doesn&#x27;t include writing data to destination part.&lt;&#x2F;p&gt;
&lt;p&gt;At a large scale, big data means you need to use spark for data processing (unless you prefer SQL, in which this post is irrelevant). But not many orgs need big data, so small data frameworks should work, since they are easier to setup and use compared to spark.&lt;&#x2F;p&gt;
&lt;p&gt;Initially I wanted to include pandas as well, but sadly it performs significantly worse than polars, so only spark and polars remain on the benchmark.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;benchmark-results&quot;&gt;Benchmark results&lt;a class=&quot;zola-anchor&quot; href=&quot;#benchmark-results&quot; aria-label=&quot;Anchor link for: benchmark-results&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Repo is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kahnwong&#x2F;db-write-performance-benchmark&#x2F;&quot;&gt;here&lt;&#x2F;a&gt;. The results:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2024&#x2F;03&#x2F;dataframe-write-performance-to-postgres&#x2F;images&#x2F;benchmark.png&quot; alt=&quot;benchmark&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Polars is faster than spark when it comes to writing data to postgres. This is in-line with spark vs polars performance, since polars puts everything in-memory, whereas spark can read from disk. Additionally, spark is a distributed framework, so there is an overhead compared to polars.&lt;&#x2F;p&gt;
&lt;p&gt;Essentially, if your data is small enough (but larger than pandas can deal with) you can use polars. But if your data is very large, consider using spark, so you don&#x27;t run into scaling issues later on.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;addendum&quot;&gt;Addendum&lt;a class=&quot;zola-anchor&quot; href=&quot;#addendum&quot; aria-label=&quot;Anchor link for: addendum&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Also note that polars can only utilize &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.sqlalchemy.org&#x2F;en&#x2F;20&#x2F;dialects&#x2F;&quot;&gt;sqlalchemy&lt;&#x2F;a&gt; or &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.pola.rs&#x2F;user-guide&#x2F;io&#x2F;database&#x2F;#adbc_1&quot;&gt;adbc&lt;&#x2F;a&gt; to write to databases.&lt;&#x2F;p&gt;
&lt;p&gt;For polars, using adbc is faster, since the dataframe doesn&#x27;t require de-serialization into pandas, but adbc only supports sqlite and postgres.&lt;&#x2F;p&gt;
&lt;p&gt;Sqlalchemy can write to columnar databases, but due to pandas limitations, it&#x27;s not quite intuitive to split data into chunks then do incremental inserts to a columnar database.&lt;&#x2F;p&gt;
&lt;p&gt;My suggestion would be: if you notice performance degradation for your analytics workload, consider migrating to spark and using columnar database for a warehouse instead.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>How to connect to Cloud SQL from Cloud Run (no, you don&#x27;t need a VPC)</title>
          <pubDate>Sat, 10 Feb 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2024/02/how-to-connect-to-cloud-sql-from-cloud-run/</link>
          <guid>https://karnwong.me/posts/2024/02/how-to-connect-to-cloud-sql-from-cloud-run/</guid>
          <description xml:base="https://karnwong.me/posts/2024/02/how-to-connect-to-cloud-sql-from-cloud-run/">&lt;p&gt;A minimal application architecture would compose of a database, and an application backend. Serverless database is still in its infancy, but thankfully container-based runtime is very much alive and doing well. On GCP, a serverless container-based runtime do exist, known as Cloud Run.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;standard-database-access-pattern&quot;&gt;Standard database access pattern&lt;a class=&quot;zola-anchor&quot; href=&quot;#standard-database-access-pattern&quot; aria-label=&quot;Anchor link for: standard-database-access-pattern&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Per standard security practices, you should not expose your database to public, this means you should use a proxy&#x2F;tunnel or private network to reach your database.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2024&#x2F;02&#x2F;how-to-connect-to-cloud-sql-from-cloud-run&#x2F;images&#x2F;db-access-pattern.webp&quot; alt=&quot;db-access-pattern&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;From above diagram, the Backend instance can access the database directly, since they are within the same VPC. However, for your local machine, you would make a connection to a tunnel, which then forwards your request to the database. This adds another layer of security because access to the tunnel is restricted, meaning not everyone can access your database, even when they know the IP &#x2F; username &#x2F; password.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cloud-run-and-and-cloud-sql&quot;&gt;Cloud Run and and Cloud SQL&lt;a class=&quot;zola-anchor&quot; href=&quot;#cloud-run-and-and-cloud-sql&quot; aria-label=&quot;Anchor link for: cloud-run-and-and-cloud-sql&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;With Cloud Run and Cloud SQL, things are a bit different, but for a good reason. Both Cloud Run and Cloud SQL are in GCP-managed VPC, meaning, they can talk to each other directly.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2024&#x2F;02&#x2F;how-to-connect-to-cloud-sql-from-cloud-run&#x2F;images&#x2F;gcp-nentwork.webp&quot; alt=&quot;gcp-nentwork&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This means, if you are deploying your workloads in a VPC and you need to connect to Cloud SQL, you need to set up VPC peering so your workloads can reach Cloud SQL via private IP.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cloud-run-configuration&quot;&gt;Cloud Run configuration&lt;a class=&quot;zola-anchor&quot; href=&quot;#cloud-run-configuration&quot; aria-label=&quot;Anchor link for: cloud-run-configuration&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Good news is you only need to set two parameters to reach Cloud SQL from Cloud Run. In Terraform, this would be equivalent to:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;terraform&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;google_cloud_run_service&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;this&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;cloud-run-cloud-sql-template&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  location&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;region&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  project&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;project_id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  template&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;    metadata&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;      annotations&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;autoscaling.knative.dev&#x2F;maxScale&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;         = &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;100&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;run.googleapis.com&#x2F;client-name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;           = &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;cloud-console&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;run.googleapis.com&#x2F;cloudsql-instances&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;    = google_sql_database_instance.this.connection_name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;run.googleapis.com&#x2F;execution-environment&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; = &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;gen2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;run.googleapis.com&#x2F;startup-cpu-boost&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;     = &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;    spec&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;      container_concurrency&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 80&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;      service_account_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;xxxxxxxxxxxx-compute@developer.gserviceaccount.com&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;      timeout_seconds&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;       =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 300&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;      containers&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;        image&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;asia-southeast1-docker.pkg.dev&#x2F;xxxxxxxx&#x2F;cloud-run-cloud-sql-template&#x2F;cloud-run-cloud-sql-template:xxxxx&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;        env&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;          name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;POSTGRES_HOSTNAME&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;          value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;cloudsql&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;google_sql_database_instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;this&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;connection_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;        env&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;          name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;POSTGRES_USERNAME&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;          value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; google_sql_user&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;this&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;        env&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;          name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;POSTGRES_PASSWORD&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;          value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; random_password&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;this&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;result&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;        env&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;          name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;POSTGRES_DBNAME&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;          value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;postgres&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;        env&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;          name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;POSTGRES_PORT&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;          value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;5432&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Essentially, you need to set &lt;code&gt;run.googleapis.com&#x2F;cloudsql-instances&lt;&#x2F;code&gt; under &lt;code&gt;annotations&lt;&#x2F;code&gt; to be your &lt;code&gt;$CloudSQLConnectionName&lt;&#x2F;code&gt;, and in environment variable, use &lt;code&gt;&#x2F;cloudsql&#x2F;${google_sql_database_instance.this.connection_name}&lt;&#x2F;code&gt; for &lt;code&gt;$POSTGRES_HOSTNAME&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-do-some-tutorials-tell-me-to-set-up-serverless-vpc-access&quot;&gt;Why do some tutorials tell me to set up Serverless VPC Access&lt;a class=&quot;zola-anchor&quot; href=&quot;#why-do-some-tutorials-tell-me-to-set-up-serverless-vpc-access&quot; aria-label=&quot;Anchor link for: why-do-some-tutorials-tell-me-to-set-up-serverless-vpc-access&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;While setting up Serverless VPC Access would also make Cloud Run able to reach Cloud SQL, this is like taking a detour, because the only difference between the non-serverless-vpc-access approach is the ability to use &lt;code&gt;private IP&lt;&#x2F;code&gt; to reach Cloud SQL. By definition, Serverless VPC Access allows serverless services (Cloud Run, Cloud Functions) to reach resources in a VPC using private IP. The network representation would look like this:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2024&#x2F;02&#x2F;how-to-connect-to-cloud-sql-from-cloud-run&#x2F;images&#x2F;serverless-vpc-access.webp&quot; alt=&quot;serverless-vpc-access.png&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;a class=&quot;zola-anchor&quot; href=&quot;#summary&quot; aria-label=&quot;Anchor link for: summary&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;You don&#x27;t need to set up networking configurations to get Cloud Run to reach Cloud SQL. Just supply two configurations and it should work.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>What is platform engineering?</title>
          <pubDate>Sun, 21 Jan 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2024/01/what-is-platform-engineering/</link>
          <guid>https://karnwong.me/posts/2024/01/what-is-platform-engineering/</guid>
          <description xml:base="https://karnwong.me/posts/2024/01/what-is-platform-engineering/">&lt;p&gt;Back in 2017-2018, everyone wanted to be a data scientist. Then reality hits, that they need a data engineer for a successful machine learning project. Things didn&#x27;t end there, since they also need a machine learning engineer to create production-ready code.&lt;&#x2F;p&gt;
&lt;p&gt;Some people think you only need an MLE and suddenly your ML project would become a reality, sadly the reality begs to differ, because you also need to find someone to deploy and scale it, enter DevOps engineer (who understands ML, this is very important).&lt;&#x2F;p&gt;
&lt;p&gt;So what&#x27;s next? What if you are working on a dozen ML projects, and you find that you have to create everything from scratch, every time. Would things be better if you can somehow only need to customize the relevant bits, and reuse templates for the rest?&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m happy to tell you that there is a role for this, and it is platform engineering. This applies to other kinds of software development as well, I just use data works as an example.&lt;&#x2F;p&gt;
&lt;p&gt;In a nutshell, a platform engineer is someone who understands how to implement end-to-end projects, and is familiar with how teams&#x2F;roles collaborate, so they can offer shortest path (read: abstractions) to delivery.&lt;&#x2F;p&gt;
&lt;p&gt;This is very important, because you have to speak everyone&#x27;s language, so you can &quot;sell&quot; on why your solutions benefit them, and how they can use it to achieve faster time-to-market.&lt;&#x2F;p&gt;
&lt;p&gt;Failing this, you can end up with abstractions no one wants to work with, because it doesn&#x27;t actually solve their problems.&lt;&#x2F;p&gt;
&lt;p&gt;As for abstractions, think of writing functions for reusable parts in your codebase. Just that this time it&#x27;s at a project level. You could say it&#x27;s a larger scale of abstractions. Definitely more moving parts and details to consider, which makes this role very challenging!&lt;&#x2F;p&gt;
&lt;p&gt;Although, if you look up platform engineering in 2024, many people would tell you it&#x27;s about Internal Developer Platform (IDP). It is part of a toolbox, but not necessarily what you need for platform engineering. At a certain scale, IDP would be beneficial, but it would be a very long time before you reach that point.&lt;&#x2F;p&gt;
&lt;p&gt;Jokingly, I say platform engineering is a glue job. We understand and can function in many different roles, but we don&#x27;t like it as much as guiding people how to collaborate and work together!&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Collaboration model for data science projects</title>
          <pubDate>Sat, 20 Jan 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2024/01/collaboration-model-for-data-science-projects/</link>
          <guid>https://karnwong.me/posts/2024/01/collaboration-model-for-data-science-projects/</guid>
          <description xml:base="https://karnwong.me/posts/2024/01/collaboration-model-for-data-science-projects/">&lt;p&gt;Many data science teams are struggling with implementing end-to-end machine learning projects. It&#x27;s a very common phenomenon, so if you are experiencing this, you are not alone. Having worked in every stage of data science project lifecycle, in addition to normal web services deployments, this is what I think how we should collaborate.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;collaboration-model-between-teams&quot;&gt;Collaboration model between teams&lt;a class=&quot;zola-anchor&quot; href=&quot;#collaboration-model-between-teams&quot; aria-label=&quot;Anchor link for: collaboration-model-between-teams&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2024&#x2F;01&#x2F;collaboration-model-for-data-science-projects&#x2F;images&#x2F;diagram.webp&quot; alt=&quot;collaboration model&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;&#x2F;strong&gt;: The diagram does not signify order of communication. Rather, it states the communication pathways between teams.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Clients have problems. Business Analysts gather initial requirements.&lt;&#x2F;li&gt;
&lt;li&gt;Project managers plan tasks and timelines, to be discussed with Tech Lead on both Web Development and Data Team&lt;&#x2F;li&gt;
&lt;li&gt;Tech Lead on both teams discuss how their services should be integrated, then loop in Platform Engineer &#x2F; Solutions Architect on the deployment model, in which DevOps Engineer would be the one implementing CI&#x2F;CD &#x2F; deployment.&lt;&#x2F;li&gt;
&lt;li&gt;Once each Team Lead break down the tasks, the team would start developing services.&lt;&#x2F;li&gt;
&lt;li&gt;Specifically for Data Team, once the ML model is working, it would be sent over to Machine Learning Engineer to optimize and  refactor the code, so it&#x27;s ready for production.&lt;&#x2F;li&gt;
&lt;li&gt;After each team has finished development, start integration tests.&lt;&#x2F;li&gt;
&lt;li&gt;Once everything is ready, deploy to prod and test again.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;why-involve-web-development-team&quot;&gt;Why involve Web Development team&lt;a class=&quot;zola-anchor&quot; href=&quot;#why-involve-web-development-team&quot; aria-label=&quot;Anchor link for: why-involve-web-development-team&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;For web services, there are many frameworks and languages to choose from, ranging from PHP, .NET, NodeJS, etc. But for data works, python is the de-facto language of choice, which means the languages used for web services and data works are different. To which, the solution is to expose data services in REST API &#x2F; GRPC format, so web services can interact with.&lt;&#x2F;p&gt;
&lt;p&gt;This essentially means both teams should communicate on api endpoints and communications between web and data services. Specifically, how data api would be triggered, and what data to send over, in addition to expected return response from data api.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;This is an over-simplification, which means some details are omitted.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Should data scientists deploy models to production?</title>
          <pubDate>Sat, 30 Dec 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2023/12/should-data-scientists-deploy-models-to-production/</link>
          <guid>https://karnwong.me/posts/2023/12/should-data-scientists-deploy-models-to-production/</guid>
          <description xml:base="https://karnwong.me/posts/2023/12/should-data-scientists-deploy-models-to-production/">&lt;p&gt;Over the years I&#x27;ve heard stories of data teams struggling with deploying machine learning models to production. Clearly
there is a pattern here. This article is my reflection on the matter.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;so-what-s-the-problem&quot;&gt;So what&#x27;s the problem?&lt;a class=&quot;zola-anchor&quot; href=&quot;#so-what-s-the-problem&quot; aria-label=&quot;Anchor link for: so-what-s-the-problem&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Data scientists, by definition, create mathematical models from data so some unknowns can become known. This is
colloquially known as &quot;prediction.&quot;  For example, if you have sales data from last year, you can use it to forecast
sales performance of next year.&lt;&#x2F;p&gt;
&lt;p&gt;The fun starts when data scientists have to &quot;deploy&quot; models to production, because their expertise do not always extend
to what are required to deploy models to production.&lt;&#x2F;p&gt;
&lt;p&gt;Below is a diagram of machine learning project workflow, abridged to only include steps from data team&#x27;s perspective,
excluding web development.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2023&#x2F;12&#x2F;should-data-scientists-deploy-models-to-production&#x2F;images&#x2F;diagram.webp&quot; alt=&quot;ml-project-flow&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-difference-between-data-science-machine-learning-engineering-and-mlops&quot;&gt;The difference between data science, machine learning engineering and mlops&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-difference-between-data-science-machine-learning-engineering-and-mlops&quot; aria-label=&quot;Anchor link for: the-difference-between-data-science-machine-learning-engineering-and-mlops&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;There are multiple definitions for data scientist, machine learning engineer and mlops, but a common theme for each is that:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Role&lt;&#x2F;th&gt;&lt;th&gt;Area of Focus&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Data Scientist&lt;&#x2F;td&gt;&lt;td&gt;Create mathematical models&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Machine Learning Engineer&lt;&#x2F;td&gt;&lt;td&gt;Make sure mathematical models can be deployed&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;MLOps&lt;&#x2F;td&gt;&lt;td&gt;Deploy mathematical models and make sure the system is up and operational&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;As you can see, machine learning engineering is more closely aligned with software engineering, which makes sense why data
scientists are struggling with model deployments, because it&#x27;s a territory they are unfamiliar with.&lt;&#x2F;p&gt;
&lt;p&gt;In the same vein, mlops is a subtype of devops, which utilizes different skills set than machine learning engineering.
mlops main focus is to make sure the whole pipelines are running smoothly and that the systems are operational.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-a-separate-mlops-role&quot;&gt;Why a separate mlops role&lt;a class=&quot;zola-anchor&quot; href=&quot;#why-a-separate-mlops-role&quot; aria-label=&quot;Anchor link for: why-a-separate-mlops-role&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Refer to software engineering vs devops, it&#x27;s the same debate. The gist is that developing a system and monitoring it
are different, plus there are many things to consider when deploying a workload, especially things that don&#x27;t happen in
development workflow.&lt;&#x2F;p&gt;
&lt;p&gt;For one, you can&#x27;t deploy an app the same way as ML api endpoint. The resources requirements are different, and
packaging ML system is trickier than an app, seeing some requires GPU during inference, etc.&lt;&#x2F;p&gt;
&lt;p&gt;Also monitoring is different, since you have to factor in data and model drift as well. In
addition, [the inference api] &#x2F; [the backend calling an inference api] have to log input&#x2F;output so the team can do back
testing and adjust the models post-initial deployment, seeing the nature of training &#x2F; users input data do affect the
model prediction.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;do-people-who-can-do-all-these-exist&quot;&gt;Do people who can do all these exist?&lt;a class=&quot;zola-anchor&quot; href=&quot;#do-people-who-can-do-all-these-exist&quot; aria-label=&quot;Anchor link for: do-people-who-can-do-all-these-exist&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;They do, but they are not your average engineers. If you do find them, congratulations!&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Setting up Postgres locally, what could go wrong?</title>
          <pubDate>Sat, 23 Dec 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2023/12/setting-up-postgres-locally/</link>
          <guid>https://karnwong.me/posts/2023/12/setting-up-postgres-locally/</guid>
          <description xml:base="https://karnwong.me/posts/2023/12/setting-up-postgres-locally/">&lt;p&gt;There are multiple reasons why someone wants to set up a postgres locally. Either for learning SQL or as an application&#x27;s backend. Over the years I see people struggle with using postgres locally, so here are common use cases and possible issues, with solutions for each.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;for-learning-sql&quot;&gt;For Learning SQL&lt;a class=&quot;zola-anchor&quot; href=&quot;#for-learning-sql&quot; aria-label=&quot;Anchor link for: for-learning-sql&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;SQL is very common for analysts to use for accessing data from a database, because the data size outgrows Excel. However, SQL is a query language, not a database engine. This essentially means if you want to get familiar with SQL, there are other simpler alternatives, such as SQLite or DuckDB (which can load data from local files directly without doing an explicit data import). Plus, you don&#x27;t need authentication to use either of them!&lt;&#x2F;p&gt;
&lt;p&gt;This would save people a lot of headaches from fixing connection errors, which can be anything from wrong username&#x2F;password, wrong host, host is not reachable, etc.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;as-application-backend&quot;&gt;As Application Backend&lt;a class=&quot;zola-anchor&quot; href=&quot;#as-application-backend&quot; aria-label=&quot;Anchor link for: as-application-backend&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;postgres-setup&quot;&gt;Postgres setup&lt;a class=&quot;zola-anchor&quot; href=&quot;#postgres-setup&quot; aria-label=&quot;Anchor link for: postgres-setup&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;There are many ways to set up postgres locally. You can use an official installer to install postgres natively. This is very convenient, but you can only have one version of postgres installed at the same time.&lt;&#x2F;p&gt;
&lt;p&gt;However, given the version of postgres you use for your application is very important, I would recommend people to set up postgres via docker, since this allows you to choose any postgres version you want for your project, and you can reset the state of postgres easily, since you can mount the data to a host path.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;networking-issues&quot;&gt;Networking issues&lt;a class=&quot;zola-anchor&quot; href=&quot;#networking-issues&quot; aria-label=&quot;Anchor link for: networking-issues&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;If you are using postgres via docker, and you are developing an application locally, don&#x27;t forget to expose port &lt;code&gt;5432&lt;&#x2F;code&gt; when you start a postgres container, otherwise your application won&#x27;t be able to discover postgres. You&#x27;ll know it&#x27;s working if you can discover this postgres via &lt;code&gt;localhost&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;But, if you are running your application as a docker container:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Postgres container&lt;&#x2F;th&gt;&lt;th&gt;Postgres hostname as seen from application&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Expose port to &lt;code&gt;5432&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;host.docker.internal&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Don&#x27;t expose port &lt;code&gt;5432&lt;&#x2F;code&gt; &amp;amp; run application and postgres via &lt;code&gt;docker compose&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;$postgresServiceName&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Reason being from a docker container&#x27;s perspective, it doesn&#x27;t share &lt;code&gt;localhost&lt;&#x2F;code&gt; with your host system, which means &lt;code&gt;localhost&lt;&#x2F;code&gt; as seen on your machine, and the one seen in docker are completely different!&lt;&#x2F;p&gt;
&lt;p&gt;As for referencing a compose service name as database host, that&#x27;s a docker networking feature, where each services in a single compose file can discover each other via a compose service name.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;closing&quot;&gt;Closing&lt;a class=&quot;zola-anchor&quot; href=&quot;#closing&quot; aria-label=&quot;Anchor link for: closing&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Mostly this is networking issues, and not being familiar with docker networking model can trip most people up, hopefully this article is useful to you. Please let me know if you would like me to expand on some other use cases.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Things to watch out for GCP SSL with Cloudflare DNS</title>
          <pubDate>Mon, 18 Dec 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2023/12/things-to-watch-out-for-gcp-ssl-with-cloudflare-dns/</link>
          <guid>https://karnwong.me/posts/2023/12/things-to-watch-out-for-gcp-ssl-with-cloudflare-dns/</guid>
          <description xml:base="https://karnwong.me/posts/2023/12/things-to-watch-out-for-gcp-ssl-with-cloudflare-dns/">&lt;p&gt;For our production workload, we deploy the workloads on Kubernetes, in which an ingress resource is created per each deployment. Resources in ingress are GCP Load Balancer and SSL Certificate. As for DNS, we use Cloudflare since it enables CDN without extra configurations on our part.&lt;&#x2F;p&gt;
&lt;p&gt;A few months after the deployment went live initially, we were informed that the website couldn&#x27;t be accessed. Turns out GCP couldn&#x27;t renew the SSL Certificate (error &lt;code&gt;FAILED_NOT_VISIBLE&lt;&#x2F;code&gt;.) Looking at GCP docs, turns out if the DNS couldn&#x27;t be resolved to the Load Balancer IP, it couldn&#x27;t provision&#x2F;renew a certificate.&lt;&#x2F;p&gt;
&lt;p&gt;The fix? Disable proxy on Cloudflare records and wait until GCP successfully renews the certs.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Serverless real-time machine learning inference with AWS</title>
          <pubDate>Tue, 28 Nov 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2023/11/serverless-real-time-machine-learning-inference-with-aws/</link>
          <guid>https://karnwong.me/posts/2023/11/serverless-real-time-machine-learning-inference-with-aws/</guid>
          <description xml:base="https://karnwong.me/posts/2023/11/serverless-real-time-machine-learning-inference-with-aws/">&lt;p&gt;For a machine learning project, usually it is divided into two main categories: research and production. For research ML project, the model would be created and used locally on a researcher&#x27;s machine. For a production ML project, a deployment would be involved. Usual pattern is to create a service to load a model, accept input, then return a prediction.&lt;&#x2F;p&gt;
&lt;p&gt;Production ML is also divided into two main patterns: batch or real-time. For batch inference, a job would be triggered on an interval to pre-calculate predictions, then store somewhere. As for real-time inference, it is more tricky, since this involves web application architecture (at least the data and application tier).&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s assume there is a website where you can identify animals by uploading a photo. The model can expect a mandatory coordinates point to narrow down the possible list of animals. Ideally there would also be a database containing a list of animals in given geographical area. This service isn&#x27;t used all the time, but during certain periods there are traffic spikes.&lt;&#x2F;p&gt;
&lt;p&gt;Together, during an inference it would look like this:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;ML service reads input image&lt;&#x2F;li&gt;
&lt;li&gt;Extract coordinates from input image&lt;&#x2F;li&gt;
&lt;li&gt;Obtain relevant features from database&lt;&#x2F;li&gt;
&lt;li&gt;Obtain prediction from model&lt;&#x2F;li&gt;
&lt;li&gt;Return prediction&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;There are many ways to set up this ML inference architecture, but for less operational overheads, serverless offerings can be utilized. On AWS the architecture would look like this:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;AWS Lambda for ML service, since it automatically scales based on amount of incoming requests.&lt;&#x2F;li&gt;
&lt;li&gt;AWS Aurora Serverless for storing data used during feature engineering step.&lt;&#x2F;li&gt;
&lt;li&gt;AWS ElastiCache Serverless for caching features, to reduce lookup time during feature engineering.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Given the nature of sporadic service usage, but might have traffic spikes, this setup allows scaling, and you don&#x27;t have to pay for compute when services are idle during off-peak hours.&lt;&#x2F;p&gt;
&lt;p&gt;To elaborate, when there are a lot of concurrent requests, Lambda would scale on its own. But the bottleneck would be the database, since it doesn&#x27;t always scale orthogonally to Lambda. However, every time an ML service fetches data from database, it doesn&#x27;t necessarily looking for new data. In most cases, it would look up the same data because users tend to submit images taken from certain geographical areas, which can be their hometown, current location, or tourist spots. An in-memory cache such as Redis (in AWS it&#x27;s ElastiCache) can be used to reduce database loads by caching frequently-accessed data. Previously the full serverless setup isn&#x27;t possible because AWS didn&#x27;t offer serverless in-memory database, but &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;aws.amazon.com&#x2F;blogs&#x2F;aws&#x2F;amazon-elasticache-serverless-for-redis-and-memcached-now-generally-available&#x2F;&quot;&gt;now it does&lt;&#x2F;a&gt;!&lt;&#x2F;p&gt;
&lt;p&gt;You can also combine this with AWS ECS on Fargate for an actual application tier, which means you can fully focus on your application and not the operational overhead. And storage can be S3, in which AWS manages everything for you. Print logs here and there and send it to CloudWatch, and now you have observability (ECS and Lambda automatically log metrics!)&lt;&#x2F;p&gt;
&lt;p&gt;The possibilities!&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Some problems can be solved with workflows</title>
          <pubDate>Fri, 24 Nov 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2023/11/some-problems-can-be-solved-with-workflows/</link>
          <guid>https://karnwong.me/posts/2023/11/some-problems-can-be-solved-with-workflows/</guid>
          <description xml:base="https://karnwong.me/posts/2023/11/some-problems-can-be-solved-with-workflows/">&lt;p&gt;When we face with engineering problems, it&#x27;s too easy to fall into the trap thinking it should be solved with a technical solution. Seasoned engineers think differently, because they realize that most of the time, it&#x27;s &quot;people&quot; or &quot;workflow&quot; problems. Let me provide a few examples.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;management-wants-analysts-to-use-jupyter-notebook-to-reduce-time-required-to-create-a-routine-report&quot;&gt;Management wants analysts to use Jupyter notebook to reduce time required to create a routine report&lt;a class=&quot;zola-anchor&quot; href=&quot;#management-wants-analysts-to-use-jupyter-notebook-to-reduce-time-required-to-create-a-routine-report&quot; aria-label=&quot;Anchor link for: management-wants-analysts-to-use-jupyter-notebook-to-reduce-time-required-to-create-a-routine-report&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Background:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Most analysts are comfortable using Microsoft Excel to work with data, some can also use SQL, but it&#x27;s rare for analysts to be familiar with Python.&lt;&#x2F;li&gt;
&lt;li&gt;Jupyter notebook is an interactive development interface for data works, since users can execute a chunk of code at a time, and render data without requiring re-running the full code.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Problem: every month a two-person analyst team would spend two days stitching up multiple CSV files (can be up to 60) via VLookup for a monthly report. This is because analysts have to look up information for each record, in which they use a template query and manually execute 50 queries with changed parameters.&lt;&#x2F;p&gt;
&lt;p&gt;Initial solution: management wants analysts to use Jupyter notebook to reduce time spent on monthly report.&lt;&#x2F;p&gt;
&lt;p&gt;Issues with proposed solution: analysts are comfortable with SQL, but have no experience with programming languages. Using Jupyter notebook can help reduce operations time, but this would require a huge effort for analysts to learn Python, and the only use case for them would be to run this report monthly.&lt;&#x2F;p&gt;
&lt;p&gt;Solution: optimize SQL query to reduce operations time, this means analysts don&#x27;t have to learn Python. At most, an engineer would have to come up with a helper script to generate SQL from initial input, and analysts only have to run the generated SQL and get a single file, instead of 50 files.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;engineer-wants-product-owner-to-upload-image-assets-to-blob-storage-directly-to-reduce-operations-overhead&quot;&gt;Engineer wants product owner to upload image assets to blob storage directly to reduce operations overhead&lt;a class=&quot;zola-anchor&quot; href=&quot;#engineer-wants-product-owner-to-upload-image-assets-to-blob-storage-directly-to-reduce-operations-overhead&quot; aria-label=&quot;Anchor link for: engineer-wants-product-owner-to-upload-image-assets-to-blob-storage-directly-to-reduce-operations-overhead&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Problem: a service requires image assets, which is provided by the business &#x2F; marketing team. A product owner would receive new images and have to inform engineers to update respective images in a CDN bucket.&lt;&#x2F;p&gt;
&lt;p&gt;Initial solution: Create a cloud IAM user with upload-only permission to allow a product owner to upload images to CDN bucket directly.&lt;&#x2F;p&gt;
&lt;p&gt;Issues with proposed solution: Creating a cloud IAM account increases attack surface, and the product owner could mistakenly upload assets to the wrong path. Given the upload-only permission, they can&#x27;t delete images in the wrong path, this could lead to a confusion down the line as to which images are actually used. In addition, the product owner doesn&#x27;t work with cloud services on a daily basis, this would require some onboarding before the product owner is comfortable enough with cloud web console.&lt;&#x2F;p&gt;
&lt;p&gt;Solution: this is a tech product, which means the product owner is familiar with some enginering tools. Upon further inquiry, turns out this product owner is familiar with git. This means we can set up a git repository to have a content of CDN bucket, the product owner just have to update the state of git repo to reflect desired state, then make a PR. After a push to master, a CI&#x2F;CD would kick off to sync the git repo with CDN bucket.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Using Apache Iceberg to reduce data lake operations overhead</title>
          <pubDate>Wed, 15 Nov 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2023/11/using-apache-iceberg-to-reduce-data-lake-operations-overhead/</link>
          <guid>https://karnwong.me/posts/2023/11/using-apache-iceberg-to-reduce-data-lake-operations-overhead/</guid>
          <description xml:base="https://karnwong.me/posts/2023/11/using-apache-iceberg-to-reduce-data-lake-operations-overhead/">&lt;p&gt;&lt;strong&gt;Updated 2024-02-21&lt;&#x2F;strong&gt; - update iceberg catalog ref url&lt;&#x2F;p&gt;
&lt;p&gt;Every business generates data, some very little, some do generate ginormous amount of data. If you are familiar with the basic web application architecture, there are data, application and web tier. But it doesn&#x27;t end there, because the data generated has to be analyzed for reports. A lot of organizations have analysts working on production database directly. This works fine and well, until the data they are working with is very large to the point that a single query can take half a day to process!&lt;&#x2F;p&gt;
&lt;p&gt;So what do people do? This is when data engineers set up pipelines to move data from $sourceDataLocation to $destinationDataLocation. Sounds simple enough, but the data doesn&#x27;t only move once! Because most often than not, data from $sourceDataLocation is not in a usable format by analysts. Some transformations have to be made, columns have to be added or joined with other related data, etc. This process is known as Extract, Transform, Load (ETL, but these days you should aim for ELTLTLTLTLTLTLTLTL.)&lt;&#x2F;p&gt;
&lt;p&gt;The difference between doing a Load before a Transform is that, if your transformation tasks failed, you don&#x27;t have to re-ingest the source data! At small data volume this would add more overhead, but if we are talking about 100GB then this process adds more resilience to the pipeline architecture.&lt;&#x2F;p&gt;
&lt;p&gt;Since this is big data territory, the general consensus is to use the data lake model, where data are stored in a blob storage, since this means cheaper cost (compared to storing data in a database, either relational or columnar), and more throughput for writing and accessing the data. Spark is used for data processing, since it is a distributed dataframe framework.&lt;&#x2F;p&gt;
&lt;p&gt;As with the nature of businesses, some changes would be made to the web application along the way, either due to more features added, or a direction shift. This means over time, there would be new data columns added, some renamed to better fit the purpose of a business.&lt;&#x2F;p&gt;
&lt;p&gt;However, this does pose a few issues, namely accessing the data is not as convenient (because it involves a user specifying actual data path in blob storage), and if you want to rename or add columns, you would have to manually go through existing data and update it in the data lake manually. For orgs that have petabyte-scale of data, a single schema change can mean a few weeks of backfilling pipelines.&lt;&#x2F;p&gt;
&lt;p&gt;Non-intuitive data access pattern and the need for schema evolution are very painful experiences for data engineers, and they eat up a lot of engineering time to make sure data lake operations are running smoothly. I discovered Apache Iceberg last year, was recently tinkered with it, and it solves a lot of major data lake operation headaches in following ways (there are many more, so check out their &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;iceberg.apache.org&#x2F;docs&#x2F;latest&#x2F;&quot;&gt;official docs!&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Area&lt;&#x2F;th&gt;&lt;th&gt;Spark&lt;&#x2F;th&gt;&lt;th&gt;Iceberg&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Parquet file size&lt;&#x2F;td&gt;&lt;td&gt;Have to manually optimize so that each resulting parquet would be around 128MB for optimum performance.&lt;&#x2F;td&gt;&lt;td&gt;Automatically taken care of.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Schema evolution&lt;&#x2F;td&gt;&lt;td&gt;Have to re-process existing data so all files would have the same schema, otherwise it would break a .read() operation.&lt;&#x2F;td&gt;&lt;td&gt;Can execute SQL DDL without requiring full table rewrite.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Versioning&lt;&#x2F;td&gt;&lt;td&gt;Have to utilize blob storage versioning, but to actually revert back to a previous state still requires a lot of configuration.&lt;&#x2F;td&gt;&lt;td&gt;Can freely time-travel to the desire revision, since all writes to Iceberg are stored. This mean a table overwrite doesn&#x27;t actually delete existing data, it is an append underneath, just that the presentation layer only show the latest data state.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Partitioned table&lt;&#x2F;td&gt;&lt;td&gt;Have to create a partition-key column. After writing a table, partition keys can&#x27;t be updated, unless you perform a full table rewrite.&lt;&#x2F;td&gt;&lt;td&gt;Can synthesize a partition column on-the-fly (ex. use timestamp column as partition key, but set it as date), with support for partition key modifications after initial table write.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Add new table partition&lt;&#x2F;td&gt;&lt;td&gt;Have to configure spark so it doesn&#x27;t delete existing partitions if they are not present in your current dataframe.&lt;&#x2F;td&gt;&lt;td&gt;Iceberg supports partition key in the DDL, and on table write you can specify whether it is an overwrite or overwrite on partition.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Also technically, Iceberg doesn&#x27;t require a stateful component if you utilize hadoop catalog (think of a manifest of all table revisions), because the manifests are stored together with the data as normal json files. However, this means concurrent writes are not possible. To prevent this, you can select available &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.tabular.io&#x2F;apache-iceberg-cookbook&#x2F;getting-started-catalog-background&#x2F;&quot;&gt;Iceberg catalogs&lt;&#x2F;a&gt;. For a lightweight and vendor-agnostic catalog, you can use REST catalog with Postgres, and these would be only required stateful backend for Apache Iceberg setup.&lt;&#x2F;p&gt;
&lt;p&gt;Did I mention that by default, Iceberg uses ztsd compression, which means smaller file size than the default snappy compression on parquet?&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Reduce operational costs with Terraform</title>
          <pubDate>Sat, 04 Nov 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2023/11/reduce-operational-costs-with-terraform/</link>
          <guid>https://karnwong.me/posts/2023/11/reduce-operational-costs-with-terraform/</guid>
          <description xml:base="https://karnwong.me/posts/2023/11/reduce-operational-costs-with-terraform/">&lt;h2 id=&quot;background&quot;&gt;Background&lt;a class=&quot;zola-anchor&quot; href=&quot;#background&quot; aria-label=&quot;Anchor link for: background&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Think of websites you visit each day. Most likely they are hosted on a cloud provider such as AWS, GCP, Azure. The good news is it&#x27;s very easy to create a simple deployment with a virtual machine, but for scalable and high-availability workloads, usual recommendations is to use a container-based runtime such as AWS ECS&#x2F;EKS, GCP Cloud Run&#x2F;GKE. These services also require more configurations than a simple VM deployment.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-problem&quot;&gt;The problem&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-problem&quot; aria-label=&quot;Anchor link for: the-problem&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Usually DevOps team would be provisioning required cloud resources through a cloud provider&#x27;s web console (known as ClickOps), and if you&#x27;re lucky, they write down the deployment details in a shared company documentation site, which has its own cost, especially if you require SSO.&lt;&#x2F;p&gt;
&lt;p&gt;This also means that, for each deployment pattern, there needs to be a corresponding entry in the documentation. Even more, some deployments require setting up environment variables to access a database or services requiring authentication, in which a DevOps engineer would also have to specify in the documentation where the secrets&#x2F;configs are stored, since environment variables are dynamic, and they are tied to a deployment environment per each service.&lt;&#x2F;p&gt;
&lt;p&gt;This also poses another challenge, that a deployment steps outlined in the documentation can be out-of-date, since it requires an engineer to update the steps manually. If this keeps going on, no one would trust the documentation, which can result in a massive operation overhead (from tracking down the actual deployment steps, locate the secrets, etc) and knowledge loss if engineers leave the team.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-operational-costs&quot;&gt;The operational costs&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-operational-costs&quot; aria-label=&quot;Anchor link for: the-operational-costs&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Assuming a team of DevOps consists of:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;8 engineers&lt;&#x2F;li&gt;
&lt;li&gt;3 deployments per engineer per day&lt;&#x2F;li&gt;
&lt;li&gt;$140K salary  -&amp;gt; 1 man-minute costs &lt;code&gt;140,000 USD &#x2F; 12 months &#x2F; 20 days &#x2F; 8 hours &#x2F; 60 minutes&lt;&#x2F;code&gt; = &lt;code&gt;1.2 USD&#x2F;minute&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Provisioning cloud resources via a provider&#x27;s web console has following costs:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Setting up a shared documentation website; Confluence costs &lt;code&gt;6.05 USD * 8 engineers * 1 month&lt;&#x2F;code&gt; = &lt;code&gt;48.4 USD &#x2F; month&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Tracking down deployment steps, locating secrets, making sure that environment variables &#x2F; secrets are correct: &lt;code&gt;3 services * 30 minutes * 8 engineers * 1.2 USD&#x2F;minute * 20 days&lt;&#x2F;code&gt; = &lt;code&gt;17,280 USD &#x2F; month&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Updating deployment steps in the documentation: &lt;code&gt;3 services * 30 minutes * 8 engineers * 1.2 USD&#x2F;minute * 20 days&lt;&#x2F;code&gt; = &lt;code&gt;17,280 USD &#x2F; month&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;what-about-other-costs&quot;&gt;What about other costs?&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-about-other-costs&quot; aria-label=&quot;Anchor link for: what-about-other-costs&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Sometimes the finance department would inquire the cost of each service, in which a DevOps engineer would have to comb through the documentation, list cloud services used, then calculate the cost. This process can take around 15-30 minutes, and since this is done manually, some errors might occur due to human errors when obtaining resource types or looking up the costs.&lt;&#x2F;p&gt;
&lt;p&gt;Assuming there are 100 services, costs are calculated each quarter, and it takes an engineer 15 minutes to calculate the cost of each service: &lt;code&gt;100 services * 15 minutes * 1 engineers * 1.2 USD&#x2F;minute * 4 quarters&lt;&#x2F;code&gt; = &lt;code&gt;7,200 USD &#x2F; year&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-solution&quot;&gt;The solution&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-solution&quot; aria-label=&quot;Anchor link for: the-solution&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.terraform.io&#x2F;&quot;&gt;Terraform&lt;&#x2F;a&gt; is an IaC (infrastructure as code) tool, which means you can declare cloud resources programmatically, and you can uses it to apply cloud configurations. It can also act as a living documentation, since terraform code directly translates to desired cloud resources. This would eliminate the need for a documentation instance, tracking down steps&#x2F;configurations and updating the documentation manually. Plus, it takes almost no time to perform a cost breakdown by using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.infracost.io&#x2F;&quot;&gt;Infracost&lt;&#x2F;a&gt; CLI against a terraform project.&lt;&#x2F;p&gt;
&lt;p&gt;In total, you would save &lt;code&gt;48.4 USD + 17,280 USD + 17,280 USD&lt;&#x2F;code&gt; = &lt;code&gt;34,608.4 USD &#x2F; month&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In a single year, this means &lt;code&gt;34,608.4 USD &#x2F; month * 12 months&lt;&#x2F;code&gt; = &lt;code&gt;415,300.8 USD &#x2F; year&lt;&#x2F;code&gt; can be saved!&lt;&#x2F;p&gt;
&lt;p&gt;Very crazy!&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Spark on Kubernetes</title>
          <pubDate>Tue, 12 Sep 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2023/09/spark-on-kubernetes/</link>
          <guid>https://karnwong.me/posts/2023/09/spark-on-kubernetes/</guid>
          <description xml:base="https://karnwong.me/posts/2023/09/spark-on-kubernetes/">&lt;h2 id=&quot;background&quot;&gt;Background&lt;a class=&quot;zola-anchor&quot; href=&quot;#background&quot; aria-label=&quot;Anchor link for: background&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;For data processing tasks, there are different ways you can go about it:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;using SQL to leverage a database engine to perform data transformation&lt;&#x2F;li&gt;
&lt;li&gt;dataframe-based frameworks such as pandas, ray, dask, polars&lt;&#x2F;li&gt;
&lt;li&gt;big data processing frameworks such as spark&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Check out &lt;a href=&quot;&#x2F;posts&#x2F;2023&#x2F;04&#x2F;duckdb-vs-polars-vs-spark&quot;&gt;this article&lt;&#x2F;a&gt; for more info on polars vs spark benchmark.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-problem&quot;&gt;The problem&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-problem&quot; aria-label=&quot;Anchor link for: the-problem&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;At larger data scale, other solutions (except spark) can work, but with a lot of vertical scaling, and this can get very expensive. For a comparison, our team had to scale a database to 4&#x2F;16 GB and it still took the whole night, whereas spark on a single node can process the data in 2 minutes flat.&lt;&#x2F;p&gt;
&lt;p&gt;Using spark would solve a lot of scaling problems, the only problem is that spark in cluster mode is very hard to set up. That&#x27;s why most if not all cloud providers provide managed spark runtime (AWS EMR, GCP Dataproc, Azure Databricks). And since these are managed spark, this means you can&#x27;t test it locally (and you&#x27;ll have to wait at least 5 minutes for the cluster to start and finish bootstrapping.)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-solution&quot;&gt;The solution&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-solution&quot; aria-label=&quot;Anchor link for: the-solution&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;As of Apache Spark 3.1 release in March 2021, spark on kubernetes is generally available. This is great in so many ways, including but not limited to:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;you have full control of your infra&lt;&#x2F;li&gt;
&lt;li&gt;takes less than 10 seconds to start a spark cluster&lt;&#x2F;li&gt;
&lt;li&gt;can store logs in a central location, to be viewed later via spark history server&lt;&#x2F;li&gt;
&lt;li&gt;can use minio as local storage backend (better throughput compared to calling S3 via home&#x2F;work internet)&lt;&#x2F;li&gt;
&lt;li&gt;cheaper than all managed solutions, even serverless variants (more on this later)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;demo&quot;&gt;Demo&lt;a class=&quot;zola-anchor&quot; href=&quot;#demo&quot; aria-label=&quot;Anchor link for: demo&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;start-a-local-kubernetes-cluster&quot;&gt;Start a local kubernetes cluster&lt;a class=&quot;zola-anchor&quot; href=&quot;#start-a-local-kubernetes-cluster&quot; aria-label=&quot;Anchor link for: start-a-local-kubernetes-cluster&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Minikube, Kind or K3d should work.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;k3d&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; cluster&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; create&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; spark-cluster&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-api-port&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; 0.0.0.0:6443&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; verify that a cluster is created&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;kubectl&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; get&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; nodes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;create-a-namespace-for-spark-jobs&quot;&gt;Create a namespace for spark jobs&lt;a class=&quot;zola-anchor&quot; href=&quot;#create-a-namespace-for-spark-jobs&quot; aria-label=&quot;Anchor link for: create-a-namespace-for-spark-jobs&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;kubectl&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; create&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; namespace&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; spark&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;create-a-service-account-for-spark&quot;&gt;Create a service account for spark&lt;a class=&quot;zola-anchor&quot; href=&quot;#create-a-service-account-for-spark&quot; aria-label=&quot;Anchor link for: create-a-service-account-for-spark&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;kubectl&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; create&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; serviceaccount&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; spark&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-namespace&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; spark&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;kubectl&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; create&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; clusterrolebinding&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; spark-role&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-clusterrole=edit&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-serviceaccount=spark:spark&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-namespace=spark&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;install-local-spark-so-you-can-run-spark-submit&quot;&gt;Install local spark (so you can run &lt;code&gt;spark-submit&lt;&#x2F;code&gt;)&lt;a class=&quot;zola-anchor&quot; href=&quot;#install-local-spark-so-you-can-run-spark-submit&quot; aria-label=&quot;Anchor link for: install-local-spark-so-you-can-run-spark-submit&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;brew&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; install&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; temurin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;brew&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; install&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; apache-spark&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;run-a-demo-spark-job&quot;&gt;Run a demo spark job&lt;a class=&quot;zola-anchor&quot; href=&quot;#run-a-demo-spark-job&quot; aria-label=&quot;Anchor link for: run-a-demo-spark-job&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;If encounter &lt;code&gt;To use support for EC Keys&lt;&#x2F;code&gt; error: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;75796747&#x2F;spark-submit-error-to-use-support-for-ec-keys-you-must-explicitly-add-this-depe&quot;&gt;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;75796747&#x2F;spark-submit-error-to-use-support-for-ec-keys-you-must-explicitly-add-this-depe&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; get kubernetes control plane url via `kubectl cluster-info`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;spark-submit&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;--master&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; k8s:&#x2F;&#x2F;https:&#x2F;&#x2F;0.0.0.0:6443&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;--deploy-mode&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; cluster&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;--name&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; spark-pi&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;--conf&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; spark.kubernetes.namespace=spark&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;--conf&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; spark.kubernetes.authenticate.driver.serviceAccountName=spark&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;--conf&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; spark.executor.instances=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;--conf&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; spark.kubernetes.container.image=spark:3.4.1&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;local:&#x2F;&#x2F;&#x2F;opt&#x2F;spark&#x2F;examples&#x2F;src&#x2F;main&#x2F;python&#x2F;pi.py&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;tearing-down-k3d&quot;&gt;Tearing down k3d&lt;a class=&quot;zola-anchor&quot; href=&quot;#tearing-down-k3d&quot; aria-label=&quot;Anchor link for: tearing-down-k3d&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;k3d&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; cluster&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; delete&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; spark-cluster&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;full-demo&quot;&gt;Full Demo&lt;a class=&quot;zola-anchor&quot; href=&quot;#full-demo&quot; aria-label=&quot;Anchor link for: full-demo&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2023&#x2F;09&#x2F;spark-on-kubernetes&#x2F;images&#x2F;demo.gif&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;regarding-pricing&quot;&gt;Regarding pricing&lt;a class=&quot;zola-anchor&quot; href=&quot;#regarding-pricing&quot; aria-label=&quot;Anchor link for: regarding-pricing&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Since spark-submit on kubernetes is akin to serverless spark, we will be comparing costs with serverless spark runtime.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Setup&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;CPU: 8&lt;&#x2F;li&gt;
&lt;li&gt;Memory: 16&lt;&#x2F;li&gt;
&lt;li&gt;Runtime: 15 Hours&lt;&#x2F;li&gt;
&lt;li&gt;Ephemeral storage: 20 GB&lt;&#x2F;li&gt;
&lt;li&gt;Region: Singapore&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Remarks: spark on kubernetes in this article assumes you&#x27;re using GKE Autopilot, which has a management fee of $60&#x2F;month (unless it&#x27;s your only cluster). Compute is spot.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Serverless Runtime&lt;&#x2F;th&gt;&lt;th&gt;Reference&lt;&#x2F;th&gt;&lt;th&gt;Total Cost&lt;&#x2F;th&gt;&lt;th&gt;Break even point if you run at least 33x workloads&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;AWS EMR Serverless&lt;&#x2F;td&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;aws.amazon.com&#x2F;emr&#x2F;pricing&#x2F;&quot;&gt;https:&#x2F;&#x2F;aws.amazon.com&#x2F;emr&#x2F;pricing&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;9.61 USD&lt;&#x2F;td&gt;&lt;td&gt;317.22 USD&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;GCP Dataproc Serverless&lt;&#x2F;td&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cloud.google.com&#x2F;products&#x2F;calculator&quot;&gt;https:&#x2F;&#x2F;cloud.google.com&#x2F;products&#x2F;calculator&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;4.26 USD&lt;&#x2F;td&gt;&lt;td&gt;140.58 USD&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Azure Databricks Serverless&lt;&#x2F;td&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.databricks.com&#x2F;product&#x2F;pricing&#x2F;product-pricing&#x2F;instance-types&quot;&gt;https:&#x2F;&#x2F;www.databricks.com&#x2F;product&#x2F;pricing&#x2F;product-pricing&#x2F;instance-types&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;5.61 USD&lt;&#x2F;td&gt;&lt;td&gt;185.13 USD&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;(Bonus) spark on kubernetes&lt;&#x2F;td&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cloud.google.com&#x2F;kubernetes-engine&#x2F;pricing&quot;&gt;https:&#x2F;&#x2F;cloud.google.com&#x2F;kubernetes-engine&#x2F;pricing&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;2.417 USD&lt;&#x2F;td&gt;&lt;td&gt;139.76 USD (Including cluster management fee)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;The script I used to find a break event point:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;aws&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 9.61272&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gcp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 4.26&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;databricks&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 5.61&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;k8s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2.417&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;found_break_even_point&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; False&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;multiplier&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;while&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; not&lt;&#x2F;span&gt;&lt;span&gt; found_break_even_point&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    multiplier&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;    print&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;multiplier&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    aws_multiplied&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; aws&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; multiplier&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    gcp_multiplied&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; gcp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; multiplier&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    databricks_multiplied&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; databricks&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; multiplier&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    k8s_reference&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;k8s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; multiplier&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 60&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; add gke autopilot management fee&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; k8s_reference&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; min&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;aws_multiplied&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; gcp_multiplied&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; databricks_multiplied&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        found_break_even_point&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; True&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;why-gke-autopilot&quot;&gt;Why GKE Autopilot&lt;a class=&quot;zola-anchor&quot; href=&quot;#why-gke-autopilot&quot; aria-label=&quot;Anchor link for: why-gke-autopilot&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Traditionally, when you&#x27;re creating a kubernetes cluster, you&#x27;ll have to attach nodes yourself. This means, if you&#x27;re running spark jobs where the compute requirement exceeds the available capacity, your jobs won&#x27;t be able to start. By using GKE Autopilot, GCP automatically provision nodes and attach to your GKE cluster automatically, which means you won&#x27;t ever face &quot;insufficient cpu &#x2F; memory&quot; errors.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;closing&quot;&gt;Closing&lt;a class=&quot;zola-anchor&quot; href=&quot;#closing&quot; aria-label=&quot;Anchor link for: closing&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;If you&#x27;re already using kubernetes, and also use spark for data processing, migrating workloads to k8s can reduce a significant amount of cost. For our case, existing spark jobs are run on a 4vCPU&#x2F;16GB VM (&lt;code&gt;109.79 USD &#x2F; Month&lt;&#x2F;code&gt;), and this cause a lot of dent in our bills. But if we migrate to spark on k8s, it would only cost us around&lt;code&gt;16.41 USD &#x2F; month&lt;&#x2F;code&gt; 😱. So that&#x27;s a whopping 85% price reduction 🤯.&lt;&#x2F;p&gt;
&lt;p&gt;For more advanced use cases, check out &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kahnwong&#x2F;spark-on-k8s&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;kahnwong&#x2F;spark-on-k8s&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Data Engineering Resources</title>
          <pubDate>Sat, 09 Sep 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2023/09/data-engineering-resources/</link>
          <guid>https://karnwong.me/posts/2023/09/data-engineering-resources/</guid>
          <description xml:base="https://karnwong.me/posts/2023/09/data-engineering-resources/">&lt;p&gt;Note: if you&#x27;ve seen the list elsewhere, it was probably me. I first posted this list on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;invite.gg&#x2F;dataengineering&quot;&gt;Data Engineering Discord&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;discuss.dataengineercafe.io&quot;&gt;Data Engineer Cafe&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;books&quot;&gt;Books&lt;a class=&quot;zola-anchor&quot; href=&quot;#books&quot; aria-label=&quot;Anchor link for: books&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;data-fundamentals-good-entrypoint&quot;&gt;Data fundamentals (good entrypoint)&lt;a class=&quot;zola-anchor&quot; href=&quot;#data-fundamentals-good-entrypoint&quot; aria-label=&quot;Anchor link for: data-fundamentals-good-entrypoint&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Fundamentals of Data Engineering - Joe Reis &amp;amp; Matt Housley&lt;&#x2F;li&gt;
&lt;li&gt;Seven Databases in Seven Weeks - Luc Perkins &amp;amp; Eric Redmond &amp;amp; Jim Wilson&lt;&#x2F;li&gt;
&lt;li&gt;Designing Data-Intensive Applications - Martin Kleppmann&lt;&#x2F;li&gt;
&lt;li&gt;The Data Warehouse Toolkit - Ralph Kimball &amp;amp; Margy Ross&lt;&#x2F;li&gt;
&lt;li&gt;Data Science for Business - Foster Provost &amp;amp; Tom Fawcett&lt;&#x2F;li&gt;
&lt;li&gt;Practical Statistics for Data Scientists - Peter Gedeck &amp;amp; Peter Bruce &amp;amp; Andrew Bruce&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;software-engineering&quot;&gt;Software engineering&lt;a class=&quot;zola-anchor&quot; href=&quot;#software-engineering&quot; aria-label=&quot;Anchor link for: software-engineering&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Python Crash Course - Eric Matthes&lt;&#x2F;li&gt;
&lt;li&gt;The Pragmatic Programmer - Andrew Hunt &amp;amp; David Thomas&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;platform&quot;&gt;Platform&lt;a class=&quot;zola-anchor&quot; href=&quot;#platform&quot; aria-label=&quot;Anchor link for: platform&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Terraform: Up &amp;amp; Running - Yevgeniy Brikman&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;management&quot;&gt;Management&lt;a class=&quot;zola-anchor&quot; href=&quot;#management&quot; aria-label=&quot;Anchor link for: management&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Team Topologies - Matthew Skelton &amp;amp; Manuel Pais&lt;&#x2F;li&gt;
&lt;li&gt;Radical Candor - Kim Scott&lt;&#x2F;li&gt;
&lt;li&gt;Data Teams - Jesse Anderson&lt;&#x2F;li&gt;
&lt;li&gt;Practical DataOps - Harvinder Atwal&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;a class=&quot;zola-anchor&quot; href=&quot;#resources&quot; aria-label=&quot;Anchor link for: resources&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;brendanthompson.com&#x2F;posts&#x2F;2021&#x2F;11&#x2F;my-terraform-development-workflow&quot;&gt;https:&#x2F;&#x2F;brendanthompson.com&#x2F;posts&#x2F;2021&#x2F;11&#x2F;my-terraform-development-workflow&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.terraform-best-practices.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.terraform-best-practices.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;open-guides&#x2F;og-aws&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;open-guides&#x2F;og-aws&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;awesomedataengineering.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;awesomedataengineering.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;opendatadiscovery&#x2F;awesome-data-catalogs&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;opendatadiscovery&#x2F;awesome-data-catalogs&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;datastacktv&#x2F;data-engineer-roadmap&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;datastacktv&#x2F;data-engineer-roadmap&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.moderndatastack.xyz&#x2F;stacks&quot;&gt;https:&#x2F;&#x2F;www.moderndatastack.xyz&#x2F;stacks&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.secoda.co&#x2F;glossary&quot;&gt;https:&#x2F;&#x2F;www.secoda.co&#x2F;glossary&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.gentlydownthe.stream&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.gentlydownthe.stream&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;b-greve.gitbook.io&#x2F;beginners-guide-to-clean-data&#x2F;&quot;&gt;https:&#x2F;&#x2F;b-greve.gitbook.io&#x2F;beginners-guide-to-clean-data&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</description>
      </item>
      <item>
          <title>A networking God tale: all I want is to run a speedtest behind a firewall</title>
          <pubDate>Sun, 27 Aug 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2023/08/a-networking-god-tale--all-i-want-is-to-run-a-speedtest-behind-a-firewall/</link>
          <guid>https://karnwong.me/posts/2023/08/a-networking-god-tale--all-i-want-is-to-run-a-speedtest-behind-a-firewall/</guid>
          <description xml:base="https://karnwong.me/posts/2023/08/a-networking-god-tale--all-i-want-is-to-run-a-speedtest-behind-a-firewall/">&lt;p&gt;Imagine going to your client&#x27;s site to deploy a software. During the deployment process, you notice that the speed is atrociously slow. You have a suspicion that your client&#x27;s network bandwidth is the issue.&lt;&#x2F;p&gt;
&lt;p&gt;To test this theory, you go to a speedtest website and run a test. Turns out you can&#x27;t because it&#x27;s blocked at the firewall level. Then you try another speedtest website, oops still got blocked. Then you try a few more, still no dice.&lt;&#x2F;p&gt;
&lt;p&gt;At this point you&#x27;re pretty sure that your client downloaded a hostfile blocklist and apply it to their firewall. But you need to know that the issue is at your client&#x27;s network bandwidth, so you can tell them with confidence that the issue is them, not you.&lt;&#x2F;p&gt;
&lt;p&gt;Stepping back a bit, a speedtest is just network performance on download and upload. So technically if you have a server that allows you to download and upload files, you can also measure the transfer speed.&lt;&#x2F;p&gt;
&lt;p&gt;With this insight, you spin up a cheap VPS, then deploy a file sharing server. On your client&#x27;s machine, you download a large binary from somewhere, maybe a linux ISO installer image. Then you upload it to your VPS. You write down the upload speed. Then you download the same file from the VPS, this should give you the download speed.&lt;&#x2F;p&gt;
&lt;p&gt;Now you have what you need to tell your client that the issue is on their end!&lt;&#x2F;p&gt;
&lt;p&gt;Maybe not really a happy ending, but at least you know your code works fine (for now).&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Spatial data to QGIS server playbook (yes, this is for prod)</title>
          <pubDate>Thu, 10 Aug 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2023/08/spatial-data-to-qgis-server-playbook-yes-this-is-for-prod/</link>
          <guid>https://karnwong.me/posts/2023/08/spatial-data-to-qgis-server-playbook-yes-this-is-for-prod/</guid>
          <description xml:base="https://karnwong.me/posts/2023/08/spatial-data-to-qgis-server-playbook-yes-this-is-for-prod/">&lt;p&gt;Some of you might be familiar with geoserver for serving spatial data as consumable WMS&#x2F;WFS layers. The issue is that as far as I know, you have to manually manage assets upload and specifying styles manually. Also the tool is a bit dated.&lt;&#x2F;p&gt;
&lt;p&gt;One modern alternative is QGIS server, you can find pre-made docker image online, and it also syncs with the Desktop version. The good thing about QGIS server is that you can create a QGIS project via the desktop application, then upload it wholesale to Postgres instance as QGIS server backend.&lt;&#x2F;p&gt;
&lt;p&gt;Assuming we&#x27;re starting with raw spatial data as hardfiles, and you want to use Postgres as data store backend, and that you don&#x27;t want to expose the database to public:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;playbook&quot;&gt;Playbook&lt;a class=&quot;zola-anchor&quot; href=&quot;#playbook&quot; aria-label=&quot;Anchor link for: playbook&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Import data to QGIS desktop.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Fix geometries&lt;&#x2F;code&gt; &amp;gt; save to Postgres.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Collect geometries&lt;&#x2F;code&gt; &amp;gt; save to Postgres. (This is for some cases where the raw data contain both &lt;code&gt;Polygon&lt;&#x2F;code&gt; and &lt;code&gt;MultiPolygon&lt;&#x2F;code&gt; in the same file, Postgres backend doesn&#x27;t allow mixed geometry type).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;DB Manager&lt;&#x2F;code&gt; &amp;gt; &lt;code&gt;Import Layer&#x2F;File&lt;&#x2F;code&gt;, and set desired &lt;code&gt;CRS&lt;&#x2F;code&gt; + spatial index here.&lt;&#x2F;li&gt;
&lt;li&gt;Import uploaded layers into current QGIS project.&lt;&#x2F;li&gt;
&lt;li&gt;Import geoserver styles (in SLD format) in QGIS via python console, then attach to layers.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;layer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; iface&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;activeLayer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;layer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;loadSldStyle&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;style.sld&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;7&quot;&gt;
&lt;li&gt;&lt;code&gt;Properties&lt;&#x2F;code&gt; &amp;gt; set &lt;code&gt;rendering&lt;&#x2F;code&gt; to &lt;code&gt;3&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Enable &lt;code&gt;WMS&lt;&#x2F;code&gt; and &lt;code&gt;WFS&lt;&#x2F;code&gt; under &lt;code&gt;project properties&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Save current project as &lt;code&gt;*.qgz&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Unzip &lt;code&gt;*.qgz&lt;&#x2F;code&gt;, manually replace &lt;code&gt;database hostname&lt;&#x2F;code&gt; with &lt;code&gt;private ip address&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Re-zip the assets into &lt;code&gt;*.qgz&lt;&#x2F;code&gt;. Important: have to use command-line on MacOS.&lt;&#x2F;li&gt;
&lt;li&gt;Turn on airplane mode, then open the modified QGIS project. (This is so that it won&#x27;t keep reaching Postgres via private ip.)&lt;&#x2F;li&gt;
&lt;li&gt;Disable airplane mode, then write the project to Postgres. (Need to whitelist your home ip so that you can reach prod db behind vpc.)&lt;&#x2F;li&gt;
&lt;li&gt;Voila 🎉&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;notes&quot;&gt;Notes&lt;a class=&quot;zola-anchor&quot; href=&quot;#notes&quot; aria-label=&quot;Anchor link for: notes&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;To be sure, restart the server every time you update the project.&lt;&#x2F;li&gt;
&lt;li&gt;Need to use private ip for database hostname.&lt;&#x2F;li&gt;
&lt;li&gt;On M1, need to use QGIS installed via mamba. (Otherwise you&#x27;ll have missing requirements for &lt;code&gt;Fix geometries&lt;&#x2F;code&gt;).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</description>
      </item>
      <item>
          <title>Create Kubernetes service accounts with Terraform</title>
          <pubDate>Tue, 01 Aug 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2023/08/create-kubernetes-service-accounts-with-terraform/</link>
          <guid>https://karnwong.me/posts/2023/08/create-kubernetes-service-accounts-with-terraform/</guid>
          <description xml:base="https://karnwong.me/posts/2023/08/create-kubernetes-service-accounts-with-terraform/">&lt;p&gt;Sometimes you&#x27;ll have to grant other people (or entities) access to your Kubernetes cluster. Easiest is you can give them your admin credentials, but this is similar to giving your house key to a friend, when they only need access to your living room.&lt;&#x2F;p&gt;
&lt;p&gt;You can give them different keys, depending on access level required. Those could be &lt;code&gt;readonly&lt;&#x2F;code&gt; access to view services status, or &lt;code&gt;deploy&lt;&#x2F;code&gt; service account that can create&#x2F;update services.&lt;&#x2F;p&gt;
&lt;p&gt;You can mix and match these terraform configs, but most importantly, you should read up on Kubernetes RBAC before diving in further. You&#x27;ve been warned!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;deploy-service-account&quot;&gt;Deploy service account&lt;a class=&quot;zola-anchor&quot; href=&quot;#deploy-service-account&quot; aria-label=&quot;Anchor link for: deploy-service-account&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;hcl&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ------------------------ service account ------------------------ #&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; https:&#x2F;&#x2F;github.com&#x2F;hashicorp&#x2F;terraform-provider-kubernetes&#x2F;issues&#x2F;1943#issuecomment-1369546028&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;kubernetes_secret&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;sa_github&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  metadata&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    annotations&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;kubernetes.io&#x2F;service-account.name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; kubernetes_service_account.sa_github.metadata.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;.name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    namespace&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;default&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;kubernetes_service_account&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;sa_github&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;metadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-token&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;                           =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;kubernetes.io&#x2F;service-account-token&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  wait_for_service_account_token&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;kubernetes_service_account&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;sa_github&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  metadata&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;sa-github&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    namespace&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;default&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ------------------------ cluster role ------------------------ #&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;kubernetes_cluster_role&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;allow_deploy&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  metadata&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;cr-allow-deploy&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; https:&#x2F;&#x2F;stackoverflow.com&#x2F;a&#x2F;70669341&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  rule&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    api_groups&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    resources&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;pods&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    verbs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;list&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;watch&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;create&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;delete&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  rule&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    api_groups&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    resources&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;pods&#x2F;exec&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    verbs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;create&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  rule&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    api_groups&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    resources&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;pods&#x2F;log&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    verbs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  rule&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    api_groups&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    resources&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;pods&#x2F;attach&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    verbs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;list&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;create&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;delete&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;update&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  rule&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    api_groups&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    resources&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;secrets&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    verbs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;list&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;create&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;delete&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;update&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  rule&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    api_groups&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    resources&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;configmaps&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    verbs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;list&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;create&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;delete&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;update&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  rule&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    api_groups&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    resources&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;services&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    verbs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;list&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;create&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;delete&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;update&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;patch&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  rule&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    api_groups&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;apps&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    resources&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;deployments&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    verbs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;list&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;create&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;delete&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;update&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;patch&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ------------------------ cluster role binding ------------------------ #&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;kubernetes_cluster_role_binding&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;allow_deploy&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; https:&#x2F;&#x2F;github.com&#x2F;kubernetes&#x2F;kubernetes&#x2F;issues&#x2F;30924#issuecomment-240887810&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  metadata&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;crb-allow-deploy-default&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  role_ref&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    api_group&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;rbac.authorization.k8s.io&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    kind&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ClusterRole&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span&gt; kubernetes_cluster_role&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;allow_deploy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;metadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  subject&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    kind&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ServiceAccount&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span&gt; kubernetes_service_account&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;sa_github&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;metadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    namespace&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;default&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;readonly-service-account&quot;&gt;Readonly service account&lt;a class=&quot;zola-anchor&quot; href=&quot;#readonly-service-account&quot; aria-label=&quot;Anchor link for: readonly-service-account&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;hcl&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ------------------------ service account ------------------------ #&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; https:&#x2F;&#x2F;github.com&#x2F;hashicorp&#x2F;terraform-provider-kubernetes&#x2F;issues&#x2F;1943#issuecomment-1369546028&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;kubernetes_secret&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;foo&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  metadata&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    annotations&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;kubernetes.io&#x2F;service-account.name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; kubernetes_service_account.foo.metadata.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;.name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    namespace&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;default&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;kubernetes_service_account&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;foo&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;metadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-token&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;                           =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;kubernetes.io&#x2F;service-account-token&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  wait_for_service_account_token&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;kubernetes_service_account&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;foo&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  metadata&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;sa-foo&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    namespace&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;default&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ------------------------ cluster role ------------------------ #&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;kubernetes_cluster_role&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;readonly&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  metadata&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;cr-readonly&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  rule&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    api_groups&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    resources&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;namespaces&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;pods&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;pods&#x2F;log&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    verbs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;list&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;watch&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ------------------------ cluster role binding ------------------------ #&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;kubernetes_cluster_role_binding&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;readonly&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  metadata&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;crb-readonly&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  role_ref&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    api_group&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;rbac.authorization.k8s.io&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    kind&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ClusterRole&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span&gt; kubernetes_cluster_role&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;readonly&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;metadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  subject&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    kind&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ServiceAccount&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span&gt; kubernetes_service_account&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;foo&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;metadata&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    namespace&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;default&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</description>
      </item>
      <item>
          <title>pglogical setup</title>
          <pubDate>Thu, 20 Jul 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2023/07/pglogical-setup/</link>
          <guid>https://karnwong.me/posts/2023/07/pglogical-setup/</guid>
          <description xml:base="https://karnwong.me/posts/2023/07/pglogical-setup/">&lt;p&gt;In certain cases, you can&#x27;t do a full postgres replication to another instance, or you prefer a fine-grained control on what to replicate, pglogical is one way to achieve partial replication, albeit this requires more manual setup.&lt;&#x2F;p&gt;
&lt;p&gt;Below are steps I used to do a pglogical replication from AWS RDS to on-premise database.&lt;&#x2F;p&gt;
&lt;p&gt;Note: If a subscriber (from the above example, the on-premise database) is offline, postgres WAL would balloon up. You&#x27;ll have to remove all traces of pglogical extension, including uninstalling pglogical extension, then reinitialize everything again to resolve the problem.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;1-on-provider-instance-create-a-role-for-subscriber-to-fetch-data-from-provider-instance&quot;&gt;1. ON PROVIDER INSTANCE: Create a role for subscriber to fetch data from provider instance&lt;a class=&quot;zola-anchor&quot; href=&quot;#1-on-provider-instance-create-a-role-for-subscriber-to-fetch-data-from-provider-instance&quot; aria-label=&quot;Anchor link for: 1-on-provider-instance-create-a-role-for-subscriber-to-fetch-data-from-provider-instance&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;CREATE&lt;&#x2F;span&gt;&lt;span&gt; USER $SUBSCRIBER_ROLE_NAME &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;WITH&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ENCRYPTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; PASSWORD&lt;&#x2F;span&gt;&lt;span&gt; $SUBSCRIBER_ROLE_PASSWORD;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;GRANT&lt;&#x2F;span&gt;&lt;span&gt; rds_superuser &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;TO&lt;&#x2F;span&gt;&lt;span&gt; $SUBSCRIBER_ROLE_NAME; &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; RDS specific&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;GRANT&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; CONNECT&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ON&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; DATABASE&lt;&#x2F;span&gt;&lt;span&gt; $DATABASE_TO_BE_REPLICATED &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;TO&lt;&#x2F;span&gt;&lt;span&gt; $SUBSCRIBER_ROLE_NAME;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;GRANT&lt;&#x2F;span&gt;&lt;span&gt; USAGE &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;ON&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; SCHEMA&lt;&#x2F;span&gt;&lt;span&gt; public &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;TO&lt;&#x2F;span&gt;&lt;span&gt; $SUBSCRIBER_ROLE_NAME;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;GRANT&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; SELECT&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ON&lt;&#x2F;span&gt;&lt;span&gt; ALL TABLES &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;IN&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; SCHEMA&lt;&#x2F;span&gt;&lt;span&gt; public &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;TO&lt;&#x2F;span&gt;&lt;span&gt; $SUBSCRIBER_ROLE_NAME;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;GRANT&lt;&#x2F;span&gt;&lt;span&gt; rds_replication &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;TO&lt;&#x2F;span&gt;&lt;span&gt; $SUBSCRIBER_ROLE_NAME; &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; RDS specific&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;2-on-provider-instance-init-pglogical-extension&quot;&gt;2. ON PROVIDER INSTANCE: Init pglogical extension&lt;a class=&quot;zola-anchor&quot; href=&quot;#2-on-provider-instance-init-pglogical-extension&quot; aria-label=&quot;Anchor link for: 2-on-provider-instance-init-pglogical-extension&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;CREATE&lt;&#x2F;span&gt;&lt;span&gt; EXTENSION pglogical;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;GRANT&lt;&#x2F;span&gt;&lt;span&gt; ALL &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;ON&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; SCHEMA&lt;&#x2F;span&gt;&lt;span&gt; pglogical &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;TO&lt;&#x2F;span&gt;&lt;span&gt; $SUBSCRIBER_ROLE_NAME;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;3-on-provider-instance-define-provider-node&quot;&gt;3. ON PROVIDER INSTANCE: Define provider node&lt;a class=&quot;zola-anchor&quot; href=&quot;#3-on-provider-instance-define-provider-node&quot; aria-label=&quot;Anchor link for: 3-on-provider-instance-define-provider-node&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;SELECT&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; pglogical&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;create_node&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  node_name :&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;provider&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  dsn :&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;host=$PROVIDER_INSTANCE_HOSTNAME port=5432 user=$SUBSCRIBER_ROLE_NAME dbname=$DATABASE_TO_BE_REPLICATED password=$SUBSCRIBER_ROLE_PASSWORD&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;4-on-provider-instance-define-tables-to-be-replicated&quot;&gt;4. ON PROVIDER INSTANCE: Define tables to be replicated&lt;a class=&quot;zola-anchor&quot; href=&quot;#4-on-provider-instance-define-tables-to-be-replicated&quot; aria-label=&quot;Anchor link for: 4-on-provider-instance-define-tables-to-be-replicated&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;select&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; pglogical&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;create_replication_set&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;replication_set&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;select&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; pglogical&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;replication_set_add_table&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  set_name :&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;replication_set&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  relation :&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;$TABLE_NAME&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  synchronize_data :&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;5-on-subscriber-instance-init-pglogical-extension&quot;&gt;5. ON SUBSCRIBER INSTANCE: Init pglogical extension&lt;a class=&quot;zola-anchor&quot; href=&quot;#5-on-subscriber-instance-init-pglogical-extension&quot; aria-label=&quot;Anchor link for: 5-on-subscriber-instance-init-pglogical-extension&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;CREATE&lt;&#x2F;span&gt;&lt;span&gt; EXTENSION pglogical;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;6-on-subscriber-instance-define-table-schemas-for-replicated-tables&quot;&gt;6. ON SUBSCRIBER INSTANCE: Define table schemas for replicated tables&lt;a class=&quot;zola-anchor&quot; href=&quot;#6-on-subscriber-instance-define-table-schemas-for-replicated-tables&quot; aria-label=&quot;Anchor link for: 6-on-subscriber-instance-define-table-schemas-for-replicated-tables&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;pglogical does not transmit schema definition. Basically you need to do the equivalent of schema migration.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;create&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; table&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt;.$TABLE_NAME&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    subject_id                   &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt;varchar&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; not null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    foo                          &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt;integer&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bar                          &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt;varchar&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;    primary key&lt;&#x2F;span&gt;&lt;span&gt; (id)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; also define indexes as well,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;7-on-subscriber-instance-define-subscriber-node&quot;&gt;7. ON SUBSCRIBER INSTANCE: Define subscriber node&lt;a class=&quot;zola-anchor&quot; href=&quot;#7-on-subscriber-instance-define-subscriber-node&quot; aria-label=&quot;Anchor link for: 7-on-subscriber-instance-define-subscriber-node&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;$SUBSCRIBER_INSTANCE_HOSTNAME&lt;&#x2F;code&gt; can be &lt;code&gt;localhost&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;SELECT&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; pglogical&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;create_node&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  node_name :&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;subscriber&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  dsn :&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;host=$SUBSCRIBER_INSTANCE_HOSTNAME port=5432 user=$SUBSCRIBER_INSTANCE_ROLE_NAME dbname=$DATABASE_TO_BE_REPLICATED password=$SUBSCRIBER_INSTANCE_ROLE_PASSWORD&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;8-on-subscriber-instance-define-subscription&quot;&gt;8. ON SUBSCRIBER INSTANCE: Define subscription&lt;a class=&quot;zola-anchor&quot; href=&quot;#8-on-subscriber-instance-define-subscription&quot; aria-label=&quot;Anchor link for: 8-on-subscriber-instance-define-subscription&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;SELECT&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; pglogical&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;create_subscription&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    subscription_name :&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;aws_sub&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    provider_dsn :&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;host=$PROVIDER_INSTANCE_HOSTNAME port=5432 dbname=$DATABASE_TO_BE_REPLICATED user=$SUBSCRIBER_ROLE_NAME password=$SUBSCRIBER_ROLE_PASSWORD&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    replication_sets :&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ARRAY&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-bracketed&quot;&gt;[&amp;#39;replication_set&amp;#39;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;9-on-provider-instance-verify-that-pglogical-is-working&quot;&gt;9. ON PROVIDER INSTANCE: Verify that pglogical is working&lt;a class=&quot;zola-anchor&quot; href=&quot;#9-on-provider-instance-verify-that-pglogical-is-working&quot; aria-label=&quot;Anchor link for: 9-on-provider-instance-verify-that-pglogical-is-working&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;SELECT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  subscription_name,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;  status&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;FROM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  pglogical&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;show_subscription_status&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</description>
      </item>
      <item>
          <title>Book Highlights - Atlas of the Heart by Brene Brown</title>
          <pubDate>Thu, 06 Jul 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2023/07/book-highlights---atlas-of-the-heart-by-brene-brown/</link>
          <guid>https://karnwong.me/posts/2023/07/book-highlights---atlas-of-the-heart-by-brene-brown/</guid>
          <description xml:base="https://karnwong.me/posts/2023/07/book-highlights---atlas-of-the-heart-by-brene-brown/">&lt;p&gt;People will do almost anything to not feel pain, including causing pain and abusing power.&lt;&#x2F;p&gt;
&lt;p&gt;Very few people can handle being held accountable without rationalizing, blaming, or shutting down.&lt;&#x2F;p&gt;
&lt;p&gt;Without understanding how our feelings, thoughts, and behaviors work together, it’s almost impossible to find our way back to ourselves and each other. When we don’t understand how our emotions shape our thoughts and decisions, we become disembodied from our own experiences and disconnected from each other.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Book Highlights - Build by Tony Fadell</title>
          <pubDate>Thu, 06 Jul 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2023/07/book-highlights---build--by-tony-fadell/</link>
          <guid>https://karnwong.me/posts/2023/07/book-highlights---build--by-tony-fadell/</guid>
          <description xml:base="https://karnwong.me/posts/2023/07/book-highlights---build--by-tony-fadell/">&lt;p&gt;Asshole assholes: They suck at work and everything else. These are the mean, jealous, insecure jerks who you’d avoid at a party, but who inevitably sit immediately next to you at the office. They cannot deliver, are deeply unproductive, so they do everything possible to deflect attention away from themselves. They will lie, craft gossip, and manipulate others to get people off their scent. The only good thing about these assholes is that they’re generally out the door pretty quickly—they can only deflect for so long before people start noticing that they bring zero value. And nobody likes working with them.&lt;&#x2F;p&gt;
&lt;p&gt;Mission-driven &quot;assholes&quot;: The people who are crazy passionate—and a little crazy. They speak most frankly, trampling the politics of the modern office, and steamroll right over the delicate social order of &quot;how things are done around here.&quot; Much like true assholes, they are neither easygoing nor easy to work with. Unlike true assholes, they care. They give a damn. They listen. They work incredibly hard and push their team to be better—often against their will. They are unrelenting when they know they’re right, but are open to changing their minds and will praise other people’s efforts if they’re genuinely great. A good way to know if you’re working with a mission-driven &quot;asshole&quot; is to listen to the mythos around them—there are always a few choice stories floating around about some crazy thing they’ve done, and the people who’ve worked with them closely are always telling everyone that they’re not that bad, really. Most tellingly, the team ultimately trusts them, respects what they do, and looks back at the experience of working with them fondly, because they pushed the team to do the best work of their lives.&lt;&#x2F;p&gt;
&lt;p&gt;It’s the assholes who are focused on people—on controlling people—who make work miserable. Real assholes always make it personal. Their motivation is their ego, not the work. As long as they’re winning, they don’t give a shit about what’s happening to the product or what the customer has to deal with. These are the assholes who make it progressively more difficult to create something you’re proud of.&lt;&#x2F;p&gt;
&lt;p&gt;She rolled her eyes and completely ignored his order. But she had to deal with this guy to get her project shipped. So she did the only thing you can do when faced with a controlling asshole:&lt;br &#x2F;&gt;
Kill ’em with kindness.&lt;br &#x2F;&gt;
Ignore them.&lt;br &#x2F;&gt;
Try to get around them.&lt;br &#x2F;&gt;
Quit.&lt;&#x2F;p&gt;
&lt;p&gt;Political assholes thrive in large organizations where they can pull the kind of Machiavellian BS that makes you sound crazy and paranoid when you’re describing it. They find people who aren’t exceptional at their jobs and protect them in exchange for their allegiance. They get dirt on their peers—who’s having an affair with his admin? Can we get HR to cover it up?—then those people are indebted for life.&lt;&#x2F;p&gt;
&lt;p&gt;That’s when your team needs to have a counternarrative. The bullshit-asymmetry theory, Brandolini’s law, will be at play here: &quot;The amount of energy needed to refute bullshit is an order of magnitude higher than to produce it.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;I’ve seen way too many people come out of the corporate world, decide to start a company, and be completely unprepared for what it takes. If they’ve never been on a small team starting from scratch, they’re often a fish out of water. They spend too much money too fast. Hire too many people. Don’t put in the time, don’t have the startup mentality, can’t make hard decisions, are buried by consensus thinking. They end up making mediocre products or nothing at all.&lt;&#x2F;p&gt;
&lt;p&gt;Steve Jobs was clear about the lesson he’d learned and made sure we all learned it, too: any company that tries to do both B2B and B2C will fail.&lt;&#x2F;p&gt;
&lt;p&gt;My dad was on commission but he would often sacrifice a sale in order to build a personal connection. The best salespeople are the ones who maintain relationships even if it means not making money that day.&lt;&#x2F;p&gt;
&lt;p&gt;To be clear, I fully support massages. I love massages. I get them all the time. Everyone should get massages. But at no point should your company culture be formed around the idea that massages are your due. At no point should you promise employees that they’ll get massages forever. At no point should perks define your business or drag it down.&lt;br &#x2F;&gt;
Perks are frosting. High-fructose corn syrup. And nobody will begrudge you a little sugar—everyone likes sweets from time to time. But stuffing your face full of them from morning to night isn’t exactly a recipe for happiness. Just as dessert shouldn’t come before dinner, perks shouldn’t come before the mission you’re there to achieve. The mission should fill and fuel your company. The perks should be a sprinkle of sugar on top.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Hassle-free Kubernetes monitoring with Coroot</title>
          <pubDate>Fri, 09 Jun 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2023/06/hassle-free-kubernetes-monitoring-with-coroot/</link>
          <guid>https://karnwong.me/posts/2023/06/hassle-free-kubernetes-monitoring-with-coroot/</guid>
          <description xml:base="https://karnwong.me/posts/2023/06/hassle-free-kubernetes-monitoring-with-coroot/">&lt;p&gt;Successfully deploying services are not the end, maintenance is coming to town! When you want to see how your system works, usually people rely on SaaS like Datadog or New Relic to do the heavy lifting. Also a lot of $$$ is required.&lt;&#x2F;p&gt;
&lt;p&gt;Also with SaaS like these, usually you have to config your application to forward metrics&#x2F;logs to your monitoring provider, this could mean a few months of engineering man-days.&lt;&#x2F;p&gt;
&lt;p&gt;In contrast, what if you can install a single service that lives locally on your Kubernetes cluster, and it can provide almost everything Datadog can offer, without having to configure your applications to access the metrics&#x2F;logs? Spoiler: everyone is happy and you save a lot more money!&lt;&#x2F;p&gt;
&lt;p&gt;Utilizing eBPF, Coroot can access telemetry data at the Linux Kernel level.&lt;&#x2F;p&gt;
&lt;p&gt;Installation is as easy as:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;helm&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; repo&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; add&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; coroot&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; https:&#x2F;&#x2F;coroot.github.io&#x2F;helm-charts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;helm&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; repo&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; update&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;helm&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; install&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-namespace&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; coroot&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-create-namespace&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; coroot&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; coroot&#x2F;coroot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And access via &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;localhost:8080&quot;&gt;http:&#x2F;&#x2F;localhost:8080&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;kubectl&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; port-forward&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; coroot&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; service&#x2F;coroot&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; 8080:8080&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Most of my services are on Kubernetes installed via &lt;code&gt;k3s&lt;&#x2F;code&gt;.
&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2023&#x2F;06&#x2F;hassle-free-kubernetes-monitoring-with-coroot&#x2F;images&#x2F;2023-06-09-20-16-36.webp&quot; alt=&quot;applications overview&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Since I am installing Coroot on my home server, only a single node is reported, and it&#x27;s mostly stay idle because I&#x27;m the only user.
&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2023&#x2F;06&#x2F;hassle-free-kubernetes-monitoring-with-coroot&#x2F;images&#x2F;2023-06-09-20-18-24.webp&quot; alt=&quot;nodes overview&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;When you access each service, it would display overview status for each observability metrics.
&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2023&#x2F;06&#x2F;hassle-free-kubernetes-monitoring-with-coroot&#x2F;images&#x2F;2023-06-09-20-21-23.webp&quot; alt=&quot;application detail&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Hello four golden signals!
&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2023&#x2F;06&#x2F;hassle-free-kubernetes-monitoring-with-coroot&#x2F;images&#x2F;2023-06-09-20-22-16.webp&quot; alt=&quot;four golden signals&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Under &lt;code&gt;tracing&lt;&#x2F;code&gt;, you can see which routes are being requested and you can see that Coroot is tailor-made for SRE disciplines because they also provide a quick-access button to see &lt;code&gt;error traces&lt;&#x2F;code&gt; and &lt;code&gt;latency SLO violations&lt;&#x2F;code&gt;.
&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2023&#x2F;06&#x2F;hassle-free-kubernetes-monitoring-with-coroot&#x2F;images&#x2F;2023-06-09-20-24-22.webp&quot; alt=&quot;tracing page&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;You can tinker much more with Coroot, so head over to their &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;coroot.com&#x2F;&quot;&gt;official website&lt;&#x2F;a&gt; and let me know how it works with your setup!&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Book Highlights - Managing Transitions: Making the Most of Change by William Bridges</title>
          <pubDate>Thu, 27 Apr 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2023/04/book-highlights---managing-transitions-making-the-most-of-change-by-william-bridges/</link>
          <guid>https://karnwong.me/posts/2023/04/book-highlights---managing-transitions-making-the-most-of-change-by-william-bridges/</guid>
          <description xml:base="https://karnwong.me/posts/2023/04/book-highlights---managing-transitions-making-the-most-of-change-by-william-bridges/">&lt;p&gt;It isn’t the changes themselves that the people in these cases resist. It’s the losses and endings that they have experienced and the transition that they are resisting.&lt;&#x2F;p&gt;
&lt;p&gt;A large university reassigned one of its vice presidents to a far less important area than the one he had previously headed, and although no one called it a demotion, it was hard to see it as anything else. Everyone knew that he had been ineffective in his previous job, and his new job actually fit his talents far better, but he was deeply hurt by the move. Discussing the situation, we discovered that the man was less troubled by the fact of the move than by how he thought it would be perceived by his colleagues.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;“I told the supervisors. It’s their job to tell their teams.”&lt;&#x2F;strong&gt; The supervisors are likely to be in transition themselves, and they may not even sufficiently understand the information to convey it accurately. Maybe they’re still in denial. Information is power, so they may not want to share it yet. Don’t assume that accurate information trickles down reliably.&lt;&#x2F;p&gt;
&lt;p&gt;There may be times when information must be withheld temporarily. The Securities and Exchange Commission (SEC) may require it, for example, or you may not be able to talk about a strategic move because competitors will learn of it. But most of the time information is withheld because leaders or managers are uncomfortable giving it. That discomfort often arises not from the anticipated long-term effects but simply from the short-term impact—the setting off of the “grieving” emotions discussed earlier.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Self-absorption.&lt;&#x2F;strong&gt; Anxious people become preoccupied with their own situations and lose their concern for fellow workers or customers. In a game of musical chairs, the only real questions are, “When is the music going to stop?” and “Will there be a chair left for me?” Larger issues of teamwork, good service, and high quality get lost. Inspirational pep talks on the values of teamwork, good service, and high quality don’t do much good when people are self-absorbed.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Use SQL against CSV (or other hard files) without CLI</title>
          <pubDate>Tue, 25 Apr 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2023/04/use-sql-against-csv-(or-other-hard-files)-without-cli/</link>
          <guid>https://karnwong.me/posts/2023/04/use-sql-against-csv-(or-other-hard-files)-without-cli/</guid>
          <description xml:base="https://karnwong.me/posts/2023/04/use-sql-against-csv-(or-other-hard-files)-without-cli/">&lt;p&gt;CSV as a file format is very versatile, almost any programs can parse it. The only issue is you can&#x27;t use SQL against CSV files directly.&lt;&#x2F;p&gt;
&lt;p&gt;This is a major pain point, since using SQL is so much faster than firing up a jupyter notebook and wrangle the data in python, or use Excel and apply transformations until you get desired results.&lt;&#x2F;p&gt;
&lt;p&gt;But the question is how do we use SQL against CSV files in the first place. Many people want this to become a reality, so a few tools exist on github:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;mithrandie&#x2F;csvq&quot;&gt;csvq&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;harelba&#x2F;q&quot;&gt;q&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;noborus&#x2F;trdsql&quot;&gt;trdsql&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Only issue is these tools require you to use CLI interface. Your analysts would be screaming at the top of their lungs because they are afraid of a black box with a blinking cursor 😱.&lt;&#x2F;p&gt;
&lt;p&gt;But you can also standing up a postgres database, and import data as a table and use SQL against it, but guess how many analysts want to learn how to spin up a database and config a database client to connect to a database instance?&lt;&#x2F;p&gt;
&lt;p&gt;Interestingly enough, you can use in-memory &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;duckdb.org&#x2F;&quot;&gt;DuckDB&lt;&#x2F;a&gt; against local files, and the best part about this is you can use GUI-based database IDE! I only tested against &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dbeaver.io&#x2F;&quot;&gt;DBeaver&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.jetbrains.com&#x2F;datagrip&#x2F;&quot;&gt;DataGrip&lt;&#x2F;a&gt;, but any tools that use &lt;code&gt;JDBC&lt;&#x2F;code&gt; driver to talk to DuckDB should also works.&lt;&#x2F;p&gt;
&lt;p&gt;As for &lt;code&gt;JDBC URI&lt;&#x2F;code&gt;, set it as &lt;code&gt;jdbc:duckdb::memory:&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;DBeaver:
&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2023&#x2F;04&#x2F;use-sql-against-csv-(or-other-hard-files)-without-cli&#x2F;images&#x2F;2023-04-25-19-38-55.webp&quot; alt=&quot;duckdb on dbeaver&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;DataGrip:
&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2023&#x2F;04&#x2F;use-sql-against-csv-(or-other-hard-files)-without-cli&#x2F;images&#x2F;2023-04-25-19-40-34.webp&quot; alt=&quot;duckdb on datagrip&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The whole process takes less than 5 minutes. Give it a try and let me know how it goes!&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>DevX starts at your local machine</title>
          <pubDate>Sat, 22 Apr 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2023/04/devx-starts-at-your-local-machine/</link>
          <guid>https://karnwong.me/posts/2023/04/devx-starts-at-your-local-machine/</guid>
          <description xml:base="https://karnwong.me/posts/2023/04/devx-starts-at-your-local-machine/">&lt;p&gt;Platform engineering is all the rage these days. Often, you&#x27;ll often hear this term with the keyword &lt;code&gt;DevX&lt;&#x2F;code&gt;. How are they related?&lt;&#x2F;p&gt;
&lt;p&gt;Imagine you are working on a microservice backend. You are just starting out, so you don&#x27;t have much features to work on yet. But as a PoC, you only need to [fetch data] and [return aggregated price]. You can do microservices on Kubernetes, but you are not familiar with DevOps so you turn to a cloud provider - AWS.&lt;&#x2F;p&gt;
&lt;p&gt;AWS has a service known as Lambda, a serverless computing platform. This basically means &quot;hey we can run your code, and you don&#x27;t have to manage the infra at all.&quot; You go check it out, and you are very pleased to see that Lambda supports a lot of runtime.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2023&#x2F;04&#x2F;devx-starts-at-your-local-machine&#x2F;images&#x2F;2023-04-22-20-00-57.webp&quot; alt=&quot;lambda runtime&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-honeymoon-period&quot;&gt;The honeymoon period&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-honeymoon-period&quot; aria-label=&quot;Anchor link for: the-honeymoon-period&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;You go through the setup wizard, at the end you see a Lambda function goes live, and it also gives you a code editor!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2023&#x2F;04&#x2F;devx-starts-at-your-local-machine&#x2F;images&#x2F;2023-04-22-20-03-54.webp&quot; alt=&quot;lambda code editor&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You really love this, because you don&#x27;t have to go through the &lt;code&gt;edit code &amp;gt; zip &amp;gt; upload to Lambda &amp;gt; test on Lambda&lt;&#x2F;code&gt; loop for eternity. You add more lines of code, getting closer to your end product. Then you hit a block because a calculation function you need to use is very hard to do manually, you need to use a library for that. You go looking for a library, and fortune is on your side because you found it. Then you froze, because you just realize that you can&#x27;t install packages in Lambda, since it doesn&#x27;t give you a terminal console 😱.&lt;&#x2F;p&gt;
&lt;p&gt;You are a web developer, so you are very familiar with nodejs. Luckily, this is a language you chose for this api, and you also remember that you can just pack &lt;code&gt;node_modules&lt;&#x2F;code&gt; folder in your deployment zip image and upload it to Lambda 🎉.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s almost the end of day, and you are almost done with an MVP. Then you got a call from your project manager, who informed you that you need to add a few features before they can show it to the client. You are not very happy about it, but you understand since you can&#x27;t go forward with unfinished MVP.&lt;&#x2F;p&gt;
&lt;p&gt;You don&#x27;t have a lot of time on your hand, since the feature requests were at the last minute. You know this will be a tech debt, but given the time frame, it&#x27;s the best course of action, so you decide to add more features to existing Lambda function.&lt;&#x2F;p&gt;
&lt;p&gt;These features, it&#x27;s quite interesting, because they do completely different things, requiring different libraries. You installed a few more packages locally, so you can init new environment on Lambda. You do your usual workflow: &lt;code&gt;zip &amp;gt; upload &amp;gt; test&lt;&#x2F;code&gt;, but this time it wouldn&#x27;t deploy! It says the package size is too large. But you can still upload the zip package to s3 and submit it as a deployment artifact on Lambda, so you&#x27;re good for now. You can tell that this project is going to be a success!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reality-hits&quot;&gt;Reality hits&lt;a class=&quot;zola-anchor&quot; href=&quot;#reality-hits&quot; aria-label=&quot;Anchor link for: reality-hits&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;This product did indeed become a success, and you have a few people to help you out on this project. Suddenly you have a realization that &quot;wait the existing &lt;code&gt;zip &amp;gt; upload &amp;gt; test&lt;&#x2F;code&gt;&quot; isn&#x27;t going to work, because you can&#x27;t collaborate 😥.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;devx-to-the-rescue&quot;&gt;DevX to the rescue&lt;a class=&quot;zola-anchor&quot; href=&quot;#devx-to-the-rescue&quot; aria-label=&quot;Anchor link for: devx-to-the-rescue&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;You remember you have a friend who&#x27;s an ops wizard, she told you of a magical tool known as Docker - a ship shipping ship shipping ship 🐳. You wine and dined your friend, and she spilled this workflow setup:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Develop your app like you would locally&lt;&#x2F;li&gt;
&lt;li&gt;Define &lt;code&gt;Dockerfile&lt;&#x2F;code&gt; for deployment, where the base image is &lt;code&gt;FROM public.ecr.aws&#x2F;lambda&#x2F;python:3.9&lt;&#x2F;code&gt;, or other runtime of your choice.&lt;&#x2F;li&gt;
&lt;li&gt;Setup CI&#x2F;CD to build image to ECR and deploy to Lambda&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;She also told you that given this setup, you literally don&#x27;t have to touch the AWS console, and you can also emulate Lambda via docker as a local endpoint and test it with Postman.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;platform-engineering-enters-the-chat&quot;&gt;Platform engineering enters the chat&lt;a class=&quot;zola-anchor&quot; href=&quot;#platform-engineering-enters-the-chat&quot; aria-label=&quot;Anchor link for: platform-engineering-enters-the-chat&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Your friend&#x27;s secret sauce works well, but over time you have more teams and services to cover. You also notice that a lot of steps are boilerplates. Your friend was also facing similar issues with her own team. During your weekend hangout, she told you that there&#x27;s a way out of this: to provide a [base repository for serverless service], in which it contains boilerplate project init, and [base docker image] with common tools installed, so you don&#x27;t have to waste CI minutes and rebuild it from scratch every time.&lt;&#x2F;p&gt;
&lt;p&gt;Happy ending I think 🤠.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>The mythical ChatOps in action</title>
          <pubDate>Tue, 18 Apr 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2023/04/the-mythical-chatops-in-action/</link>
          <guid>https://karnwong.me/posts/2023/04/the-mythical-chatops-in-action/</guid>
          <description xml:base="https://karnwong.me/posts/2023/04/the-mythical-chatops-in-action/">&lt;p&gt;Imagine having multiple services running, each has its own logs. Most people don&#x27;t read them, and they shouldn&#x27;t, because services emit a lot of logs! But we need them, because it&#x27;s the only way to diagnose and troubleshoot system errors. But you might say &quot;my service is not a system! It&#x27;s only doing tiny stuff!&quot; Gotta break it to you, your small part is a piece in a large system networks stitched together! So your seemingly-tiny service is also important!&lt;&#x2F;p&gt;
&lt;p&gt;So how do people monitor logs? Actually they don&#x27;t. To actually do that, you need to do a lot of mouse-scrolling, and reading a lot of redundant logs but with different identifiers - which doesn&#x27;t sound glamorous. What usually happens is, people set up alerts on logs, so when alerts are triggered, someone would be going through the logs to investigate the issue. Now it&#x27;s more like a murder mystery!&lt;&#x2F;p&gt;
&lt;p&gt;What if it&#x27;s not with applications logs but services status? Say, your service deployments on AWS ECS. Luckily you can still utilize the same concept as above: intercept the logs and sent out alerts based on a trigger.&lt;&#x2F;p&gt;
&lt;p&gt;One instance where you might want to send alerts on services status is for services autoscaling, so you know when there&#x27;s a spike in traffic. The issue isn&#x27;t with the increased cost for your compute, rather to monitor related services to make sure they are operational. Hello databases, api endpoints, etc.&lt;&#x2F;p&gt;
&lt;p&gt;This is important because, your service on autoscaling might be your backend. You can have multiple instances of backend services, but they might be pointing to the same database or api endpoints. Service health on auxiliary services are important, since this is your backend service&#x27;s bottleneck.&lt;&#x2F;p&gt;
&lt;p&gt;If you&#x27;re on AWS, you can utilize Cloudwatch Events to send out messages based on a trigger via Lambda. Basically:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;ECS emits metrics &#x2F; logs to Cloudwatch&lt;&#x2F;li&gt;
&lt;li&gt;Alerts (Cloudwatch Alarms) are set to trigger on specific events (e.g. service {scale up | scale down | stop})&lt;&#x2F;li&gt;
&lt;li&gt;Alert events are sent to SNS, so it can trigger actions we want after receiving alerts&lt;&#x2F;li&gt;
&lt;li&gt;Actions are defined via a Lambda function to send out messages&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;There&#x27;s a lot of jumps there, so to recap: ECS -&amp;gt; Cloudwatch Alarms -&amp;gt; SNS -&amp;gt; Lambda.&lt;&#x2F;p&gt;
&lt;p&gt;So what about ChatOps? Let&#x27;s say the whole point of this setup is to send out alerts, where do you think people would have the most chance to see?&lt;&#x2F;p&gt;
&lt;p&gt;Yup, in their work slack, or discord, or whatever people use. This way, service alerts are public, and everyone can see it. It&#x27;s even better than email because it&#x27;s not really made for real-time communication... Which means for critical alerts we might want to work with latest alerts, and collaborate to help mitigate the issue. And one of the biggest benefits is that you don&#x27;t have to seek out the alerts, instead they come to you! (Now you can&#x27;t use excuses like &quot;I forgot to monitor the alerts!&quot;)&lt;&#x2F;p&gt;
&lt;p&gt;For my organization&#x27;s workspace, we have set up alerts for ECS services status, to see when scaling or service termination happens. This especially comes in handy during a new service deployment, when if we see service termination alerts for the same service in succession, it means there&#x27;s issues with this deployment, this limits the blast radius so we can pinpoint the likely root cause.&lt;&#x2F;p&gt;
&lt;p&gt;One time, someone merged a PR and suddenly we see a lot of service termination alerts. Turns out, this commit introduced a new feature that requires a new environment variable, but it wasn&#x27;t added in the deployment specs yet. This also allows for fast feedback cycle, so you have an easier to time to trace your steps for likely event(s) that caused a service disruption.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2023&#x2F;04&#x2F;the-mythical-chatops-in-action&#x2F;images&#x2F;d3db35924b0a0d68a22b3821305f21ab0c4856781e1d3876c10af95776b531f2.webp&quot; alt=&quot;ecs error logs&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Ops is easy, said no one, I think 😅.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>DuckDB vs Polars vs Spark!</title>
          <pubDate>Fri, 07 Apr 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2023/04/duckdb-vs-polars-vs-spark/</link>
          <guid>https://karnwong.me/posts/2023/04/duckdb-vs-polars-vs-spark/</guid>
          <description xml:base="https://karnwong.me/posts/2023/04/duckdb-vs-polars-vs-spark/">&lt;p&gt;I think everyone who has worked with data, in any role or function, used pandas 🐼 at certain point. I first used pandas in 2017, so it&#x27;s 6 years already. Things have come a long way, and so is data size I&#x27;m working with!&lt;&#x2F;p&gt;
&lt;p&gt;Pandas has its own issues, namely no native support for nested schema. In addition, it&#x27;s very heavy-handed regarding data types inference. It can be a blessing, but it&#x27;s a bane for data engineering work, where you have to make sure that your data conforms to agreed-upon schema (hello data contracts!). But the worst issue? Pandas can&#x27;t open data that doesn&#x27;t fit into memory. So if you have a 16 GB RAM machine, you can&#x27;t read 12GB data with pandas 😭.&lt;&#x2F;p&gt;
&lt;p&gt;Rust is all the rage these days, so it&#x27;s only natural that a dataframe framework would also exist in rust. Polars 🐻‍❄️ is a new kid in town, and it does pack a punch 🥊! Under the hood it uses apache arrow format, so there&#x27;s no extra overhead for serialization&#x2F;deserialization. Still, polars isn&#x27;t a distributed framework. And why is this an issue? Because at certain point, your data would grow larger and larger, and it would no longer be economical to add more resources and &lt;del&gt;hope&lt;&#x2F;del&gt; pray that your polars job won&#x27;t fail.&lt;&#x2F;p&gt;
&lt;p&gt;But what if your analysts are only comfortable with sql? Then there&#x27;s DuckDB where it&#x27;s like SQLite, but on steroids! But then this also pose the same issue as polars, that it doesn&#x27;t work in a distributed manner.&lt;&#x2F;p&gt;
&lt;p&gt;And we&#x27;re back to spark, where it&#x27;s not that easy to setup, but if you get it to work, you pretty much don&#x27;t have to worry about scaling, since you can have a cluster of spark working in tandem to crunch your pipelines ✨.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;benchmark-result&quot;&gt;Benchmark result&lt;a class=&quot;zola-anchor&quot; href=&quot;#benchmark-result&quot; aria-label=&quot;Anchor link for: benchmark-result&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Enough talking, here&#x27;s the benchmark:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2023&#x2F;04&#x2F;duckdb-vs-polars-vs-spark&#x2F;images&#x2F;e22cca514a40af13328884eede1bfbcf2cee2e103f4230307d5859e5b444d8ff.webp&quot; alt=&quot;dataframe showdown result&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If you see a small green bar chart for duckdb, the reason there&#x27;s no values at &amp;gt; 30M rows is because it&#x27;s been running for 14 minutes, and I would guess it would take much longer to finish the task. For comparison, a spark job against 270M rows only take &lt;code&gt;400 seconds &#x2F; 60 seconds = 6.5 minutes&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Also, notice that the swap usage for spark is almost constant, whereas with polars, it spikes up exponentially post 120M rows 😱. Interestingly, it also parallels spark job runtime. But most pipelines are run in batches at night, so compute time might not be as important in relation to required compute.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;experiment-design&quot;&gt;Experiment design&lt;a class=&quot;zola-anchor&quot; href=&quot;#experiment-design&quot; aria-label=&quot;Anchor link for: experiment-design&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Contrast with most dataframe benchmarks, I intentionally abuse each framework by:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Create a timestamp diff column &lt;code&gt;trip_length_minute&lt;&#x2F;code&gt;, converted to minute&lt;&#x2F;li&gt;
&lt;li&gt;Create percentile on &lt;code&gt;trip_length_minute&lt;&#x2F;code&gt; as &lt;code&gt;trip_length_minute_percentile&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Filter only &lt;code&gt;trip_length_minute_percentile&lt;&#x2F;code&gt; between (0.2, 0.8)&lt;&#x2F;li&gt;
&lt;li&gt;Group by on &lt;code&gt;VendorID&lt;&#x2F;code&gt;, &lt;code&gt;payment_type&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Aggregate min, max, avg on &lt;code&gt;passenger_count&lt;&#x2F;code&gt;, &lt;code&gt;trip_distance&lt;&#x2F;code&gt;, &lt;code&gt;total_amount&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Input data is equally partitioned into 8 chunks.&lt;&#x2F;p&gt;
&lt;p&gt;Repo is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kahnwong&#x2F;dataframe-frameworks-showdown&quot;&gt;here&lt;&#x2F;a&gt; if you want run it against different parameters. Please drop me a chart if you see something interesting!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;update-2023-04-10&quot;&gt;Update 2023-04-10&lt;a class=&quot;zola-anchor&quot; href=&quot;#update-2023-04-10&quot; aria-label=&quot;Anchor link for: update-2023-04-10&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;What if you Window on multi-key partitions?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2023&#x2F;04&#x2F;duckdb-vs-polars-vs-spark&#x2F;images&#x2F;9ad99e712d172b8964bbde490cf19c15a0056961ba9dc3e137c4bd397cc87f99.webp&quot; alt=&quot;dataframe showdown result 2&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Spark wins! Makes sense, since spark can do parallel processing on each partition independently of each other. Also apparently a certain polar bear is very hungry!&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Cost optimization with Kubernetes</title>
          <pubDate>Sat, 01 Apr 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2023/04/cost-optimization-with-kubernetes/</link>
          <guid>https://karnwong.me/posts/2023/04/cost-optimization-with-kubernetes/</guid>
          <description xml:base="https://karnwong.me/posts/2023/04/cost-optimization-with-kubernetes/">&lt;p&gt;Correction 2023-07-02: fix homelab specs and corresponding AWS EC2 instance class (it&#x27;s actually 32GB RAM, not 64GB)&lt;&#x2F;p&gt;
&lt;p&gt;Congratulations, you managed to successfully deployed a few services on kubernetes! But this is not the end 👀. Unfortunately money doesn&#x27;t grow on trees, and if you can&#x27;t justify your infra expenses, finance department won&#x27;t be happy.&lt;&#x2F;p&gt;
&lt;p&gt;If you&#x27;re using Terraform, you can use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.infracost.io&#x2F;&quot;&gt;Infracost&lt;&#x2F;a&gt; to create a cost report. Pretty nifty. But what about kubernetes? Given cost reporting is a basic feature, kubernetes is no exception.&lt;&#x2F;p&gt;
&lt;p&gt;Enter &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.opencost.io&#x2F;&quot;&gt;OpenCost&lt;&#x2F;a&gt;, a vendor-neutral open source project for measuring and allocating infrastructure and container costs in real time. This also means it is vendor-agnostic. Meaning as long as it&#x27;s kubernetes, it would work regardless of which cloud it&#x27;s on (and it works with on-prem setup as well 😉).&lt;&#x2F;p&gt;
&lt;p&gt;Under the hood, it utilizes [prometheus metrics], in conjunction with [provisioned resources for containers - defined in deployment manifest], to calculate cost based on [cloud pricing per compute unit - you can adjust this later].&lt;&#x2F;p&gt;
&lt;p&gt;You can follow OpenCost install instructions &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.opencost.io&#x2F;docs&#x2F;install&quot;&gt;here&lt;&#x2F;a&gt;. Wait for a few days for prometheus to collect usage metrics, and check out OpenCost dashboard. This is what mine looks like:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2023&#x2F;04&#x2F;cost-optimization-with-kubernetes&#x2F;images&#x2F;4d695173c90ef2db997019774a93863847a39368e35bfdaf48d79b76acca515b.webp&quot; alt=&quot;picture 1&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Notice &lt;code&gt;efficiency&lt;&#x2F;code&gt; column, this tells how well your resources are being utilized. If you see a low number here, consider using function-as-a-service or other cloud compute where pricing is calculated per usage, not active time (something like gcp&#x27;s cloud run).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;boring-math-part-sleeping&quot;&gt;Boring math part 😴&lt;a class=&quot;zola-anchor&quot; href=&quot;#boring-math-part-sleeping&quot; aria-label=&quot;Anchor link for: boring-math-part-sleeping&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;So that&#x27;s &lt;code&gt;$35.57 &#x2F; 6 days&lt;&#x2F;code&gt;, which would be around &lt;code&gt;$5.9 &#x2F; day&lt;&#x2F;code&gt;. Per year this would cost &lt;code&gt;$5.9 * 52 = $306.8 &#x2F; year&lt;&#x2F;code&gt; 😱.&lt;&#x2F;p&gt;
&lt;p&gt;My current home server setup is around &lt;code&gt;$880&lt;&#x2F;code&gt;, so that&#x27;s around &lt;code&gt;3 years&lt;&#x2F;code&gt; before it would break even 🤣.&lt;&#x2F;p&gt;
&lt;p&gt;But what if we&#x27;re talking about raw compute price? My server is &lt;code&gt;8 cores, 32GB RAM, 1TB SSD&lt;&#x2F;code&gt;, cheapest compute on AWS with similar specs per year is &lt;code&gt;t3a.2xlarge&lt;&#x2F;code&gt;, which is &lt;code&gt;$3307 &#x2F; year&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Pricing is hard...&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Kubernetes with Grafana Cloud</title>
          <pubDate>Sat, 01 Apr 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2023/04/kubernetes-with-grafana-cloud/</link>
          <guid>https://karnwong.me/posts/2023/04/kubernetes-with-grafana-cloud/</guid>
          <description xml:base="https://karnwong.me/posts/2023/04/kubernetes-with-grafana-cloud/">&lt;p&gt;Kubernetes is awesome, I think this is obvious if you have more than a handful of services to manage. If you use cloud, either VM or container-based runtime, it would provide you a dashboard to see the metrics. But what about kubernetes? Since you would have multiple services inside a single cluster, in which it&#x27;s backed by VMs, at best you would only see into your VMs&#x27; metrics, but doesn&#x27;t provide separate metrics per each service.&lt;&#x2F;p&gt;
&lt;p&gt;In the end, what metrics dashboards are is just visualizations on collected metrics, which are stored somewhere. On open source front, usually people store metrics in prometheus, and visualize it via grafana.&lt;&#x2F;p&gt;
&lt;p&gt;To try this out, you can use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;artifacthub.io&#x2F;packages&#x2F;helm&#x2F;prometheus-community&#x2F;kube-prometheus-stack&quot;&gt;this&lt;&#x2F;a&gt; to install grafana+prometheus on your kubernetes cluster. Just port forward the grafana pod and you should be able to see the metrics.&lt;&#x2F;p&gt;
&lt;p&gt;But there&#x27;s a catch: if you were to tear this down, all the collected metrics are gone. This might be ideal if you&#x27;re in the development phase, where you want to make sure things are actually reproducible. But for prod this is a liability.&lt;&#x2F;p&gt;
&lt;p&gt;There is a way of out this though - use managed grafana (via &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;grafana.com&#x2F;&quot;&gt;grafana cloud&lt;&#x2F;a&gt;), and ship your cluster metrics to it via &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;grafana.com&#x2F;docs&#x2F;grafana-cloud&#x2F;kubernetes-monitoring&#x2F;configuration&#x2F;config-k8s-agent-guide&#x2F;&quot;&gt;grafana agent&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If you follow the instructions successfully, head to your grafana cloud dashboard, and you should see your cluster metrics pop up:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2023&#x2F;04&#x2F;kubernetes-with-grafana-cloud&#x2F;images&#x2F;89ab6ea8ef3397a80470c0e75dcd5e3f3885b6e124c0d68a44dce806f082c7be.webp&quot; alt=&quot;picture 1&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;And the best part is it&#x27;s the same dashboards you get from installing &lt;code&gt;kube-prometheus-stack&lt;&#x2F;code&gt; above! And you can access the dashboard from anywhere as well, instead of doing a port forward every time you want to see the dashboard.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Bare metal works, until it doesn&#x27;t. Hello, cloud.</title>
          <pubDate>Fri, 24 Mar 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2023/03/bare-metal-works-until-it-doesnt-hello-cloud/</link>
          <guid>https://karnwong.me/posts/2023/03/bare-metal-works-until-it-doesnt-hello-cloud/</guid>
          <description xml:base="https://karnwong.me/posts/2023/03/bare-metal-works-until-it-doesnt-hello-cloud/">&lt;!-- # challenge you dealt with as a developer but later overcame it by using AWS --&gt;
&lt;h2 id=&quot;background&quot;&gt;Background&lt;a class=&quot;zola-anchor&quot; href=&quot;#background&quot; aria-label=&quot;Anchor link for: background&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Ever wonder how websites (and everything in between) work? Chances are you can create a project running on your local machine. It works as you expected, but to let other people access it, you have to &quot;deploy&quot; it. For many years, to support a lot of request volumes you need to run your applications in a data center. These days this setup is known as on-premise.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;architecture&quot;&gt;Architecture&lt;a class=&quot;zola-anchor&quot; href=&quot;#architecture&quot; aria-label=&quot;Anchor link for: architecture&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Let&#x27;s take a look at a simple e-commerce website architecture. This would involve frontend, backend, database. But if you have a feature where you allow users to batch update catalogs, you have to add redis &#x2F; pub-sub as not to overload your backend.&lt;&#x2F;p&gt;
&lt;p&gt;This continues to work, except your website grew so popular that your cpu and memory usage is always at max capacity. You tried vertical scaling, but it&#x27;s gotten to the point where it&#x27;s no longer feasible for your budget. Oops. But wait, you can use a load balancer to spread requests throughout the nodes. This would work nicely, but it takes a lot of time to set it up properly. But you figured it out, so yay.&lt;&#x2F;p&gt;
&lt;p&gt;And you just happened to secured a major deal for your website, and they want a few customized features. You crank out a lot of features, but because it takes quite a while to deploy (manually) you made a lot of mistakes along the way, and you wish you can go back to release-once-a-month cycle.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cloud-enters-the-chat&quot;&gt;Cloud enters the chat&lt;a class=&quot;zola-anchor&quot; href=&quot;#cloud-enters-the-chat&quot; aria-label=&quot;Anchor link for: cloud-enters-the-chat&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;All these challenges are well known among on-premise users, and there are ways to overcome these. But using cloud reduce ops overhead and allows for faster time-to-market.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s break them down one-by-one to see how cloud can help:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;1-frontend-backend-database-etc&quot;&gt;1. Frontend, backend, database, etc&lt;a class=&quot;zola-anchor&quot; href=&quot;#1-frontend-backend-database-etc&quot; aria-label=&quot;Anchor link for: 1-frontend-backend-database-etc&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;If you have to develop against local resources, you would need to spin up each component separately, but this means more context to management. Using cloud means you can develop against some resources that were already deployed on cloud.&lt;&#x2F;p&gt;
&lt;p&gt;For example, you can iterate on a UI change against a development instance of backend and database, so you can focus on developing the UI instead of worrying about setting up other components properly.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;2-scaling&quot;&gt;2. Scaling&lt;a class=&quot;zola-anchor&quot; href=&quot;#2-scaling&quot; aria-label=&quot;Anchor link for: 2-scaling&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;It is a well-known fact with on-prem setup that you can&#x27;t scale beyond your physical capacity, this essentially means if one fateful day, your marketing campaign works really well that a lot of people use your website, your traffic would spike up, in turn increasing resources consumption. If you&#x27;re on-prem, your options are limited to either waiting it out or disable your website temporarily. But this would be catastrophic for your website&#x27;s reputation.&lt;&#x2F;p&gt;
&lt;p&gt;If you use cloud, there are many ways to set up (auto) scaling, namely using container-based runtime and link running instances to a load balancer to spread out traffic. You can also temporarily increase your compute&#x27;s provisioned resources during peak hours, then scale down later for cost optimization.&lt;&#x2F;p&gt;
&lt;p&gt;On AWS, you can use ECS for compute and define a load balancer. On GCP, Cloud Run can achieve the same thing.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;3-ci-cd&quot;&gt;3. CI&#x2F;CD&lt;a class=&quot;zola-anchor&quot; href=&quot;#3-ci-cd&quot; aria-label=&quot;Anchor link for: 3-ci-cd&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;From my experience and a lot of people I&#x27;ve talked to, deploying with on-prem setup usually means &quot;copy deploy artifacts over to the server (manually).&quot; Obviously this process is prone to human errors. You can set up Jenkins to achieve CI&#x2F;CD, but this requires more overhead than using a cloud-managed build solutions.&lt;&#x2F;p&gt;
&lt;p&gt;With AWS, you can sync a repo with AWS Code Build - for building deploy artifacts, and deploy it via Code Pipeline. On GCP, similar services also available as well. Additionally, you can also do all this with your VCS providers (GitHub, Gitlab, etc) if you prefer it. Personally I would do CI&#x2F;CD with via VCS providers. It requires more ops overhead, but yields better observability.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;closing&quot;&gt;Closing&lt;a class=&quot;zola-anchor&quot; href=&quot;#closing&quot; aria-label=&quot;Anchor link for: closing&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;A lot of people ask me which cloud to use. My answer would be: &quot;use what other people around you use, so you can ask them when you have issues.&quot; Some clouds do certain things better than other clouds, that&#x27;s up for you to evaluate. But if you&#x27;re just starting out and don&#x27;t have people who you can ask for support, AWS would be a better choice since it has significantly more users than other cloud providers. GCP is also good, but there&#x27;s not as many users, which means unless you can understand official documentations, you&#x27;re pretty much on your own.&lt;&#x2F;p&gt;
&lt;p&gt;Also, I did not mention Kubernetes. This is because unless you have a lot of services to manage or an ops team to support, Kubernetes&#x27; ops overhead would be too much for your scale.&lt;&#x2F;p&gt;
&lt;p&gt;And you can definitely achieve what you can do with cloud on on-premise system. But do you have enough people to setup and maintain it?&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Google Analytics v4 ingestion via BigQuery</title>
          <pubDate>Sun, 19 Mar 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2023/03/google-analytics-v4-ingestion-via-bigquery/</link>
          <guid>https://karnwong.me/posts/2023/03/google-analytics-v4-ingestion-via-bigquery/</guid>
          <description xml:base="https://karnwong.me/posts/2023/03/google-analytics-v4-ingestion-via-bigquery/">&lt;h2 id=&quot;background&quot;&gt;Background&lt;a class=&quot;zola-anchor&quot; href=&quot;#background&quot; aria-label=&quot;Anchor link for: background&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;You want to track who access your site, Google Analytics can do that. To see the data, you can use Google Analytics dashboard, the default settings is good enough for most use cases. But what if you have a lot of tracking data, and you want to streamline a way to analyze it? You could use Data Studio for this, so it&#x27;s cool for the moment. But what if you want to use Google Analytics data in conjunction with other data? Say, product SKUs? There are multiple ways to achieve that, but one approach that provides a lot of flexibility and allow for long-term maintenance is to write a custom pipeline yourself.&lt;&#x2F;p&gt;
&lt;p&gt;So we&#x27;re back to grabbing the tracking data and store it somewhere. Google Analytics provide APIs that you can call to obtain the data. This works, with a few caveats... One being that if you have a lot of data, you would run into API rate-limiting 🥲.&lt;&#x2F;p&gt;
&lt;p&gt;But you probably are not the only one who amassed a lot of tracking data, and luckily there&#x27;s a solution to this problem: dunk Google Analytics data into BigQuery, then you can use Spark to ingest it ✨. (You can set it to &quot;streaming&quot; mode as well, if you want near real-time data.)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;setup&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;support.google.com&#x2F;analytics&#x2F;answer&#x2F;9823238?hl=en&amp;amp;ref_topic=9359001#zippy=%2Cin-this-article&quot;&gt;Setup&lt;&#x2F;a&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#setup&quot; aria-label=&quot;Anchor link for: setup&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Create a new project in GCP console.&lt;&#x2F;li&gt;
&lt;li&gt;Enable &lt;code&gt;BigQuery API&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Go to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;analytics.google.com&#x2F;&quot;&gt;Google Analytics console&lt;&#x2F;a&gt; &amp;gt; admin &amp;gt; product links &amp;gt; BigQuery links.&lt;&#x2F;li&gt;
&lt;li&gt;Click &lt;code&gt;Link&lt;&#x2F;code&gt; &amp;gt; select your BigQuery project where you want to store Google Analytics data.&lt;&#x2F;li&gt;
&lt;li&gt;Fill in information as required.&lt;&#x2F;li&gt;
&lt;li&gt;Wait for a day. (Initial setup only.)&lt;&#x2F;li&gt;
&lt;li&gt;Head back to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;console.cloud.google.com&#x2F;bigquery&quot;&gt;BigQuery console&lt;&#x2F;a&gt; and you should see the results.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2023&#x2F;03&#x2F;google-analytics-v4-ingestion-via-bigquery&#x2F;images&#x2F;1faf596d55d0b74a522f327ff9849190c4afc76bbef2a0fd9ac36e1d6c80f8d5.webp&quot; alt=&quot;picture 1&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ingestion&quot;&gt;Ingestion&lt;a class=&quot;zola-anchor&quot; href=&quot;#ingestion&quot; aria-label=&quot;Anchor link for: ingestion&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;You can use any tools you want to read data off BigQuery. Personally I would go with &lt;code&gt;Spark&lt;&#x2F;code&gt;, because you can do fine-grained ingestion control that way, and it plays nicely with &lt;code&gt;s3a&lt;&#x2F;code&gt; or &lt;code&gt;gs&lt;&#x2F;code&gt; protocol for write destination.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;spark&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    SparkSession&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;builder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;config&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;spark.executor.memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;4g&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;config&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;spark.driver.memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;4g&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;config&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;spark.jars.packages&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;com.google.cloud.spark:spark-bigquery-with-dependencies_2.12:0.29.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;    )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;getOrCreate&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    spark&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;read&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;format&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bigquery&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;option&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;table&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ga4-to-bigquery-xxxxxx.analytics_xxxxxxxxx.events_20230318&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;load&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now you&#x27;ll get data that looks like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-RECORD 0---------------------------------------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; event_date                    | 20230318&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; event_timestamp               | 1679110653461084&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; event_name                    | session_start&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; event_params                  | [{engaged_session...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; event_previous_timestamp      | null&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; event_value_in_usd            | null&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; event_bundle_sequence_id      | 1779024476&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; event_server_timestamp_offset | null&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; user_id                       | null&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; user_pseudo_id                | 653547550.1673451049&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; privacy_info                  | {null, null, No}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; user_properties               | []&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; user_first_touch_timestamp    | 1673451049581992&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; user_ltv                      | {0.0, USD}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; device                        | {mobile, Samsung,...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; geo                           | {Asia, Thailand, ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; app_info                      | null&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; traffic_source                | {(referral), refe...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; stream_id                     | 4111827120&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; platform                      | WEB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; event_dimensions              | null&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; ecommerce                     | null&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; items                         | []&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-RECORD 1---------------------------------------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; event_date                    | 20230318&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; event_timestamp               | 1679110653461084&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; event_name                    | page_view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; event_params                  | [{medium, {referr...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; event_previous_timestamp      | null&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; event_value_in_usd            | null&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; event_bundle_sequence_id      | 1779024476&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; event_server_timestamp_offset | null&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; user_id                       | null&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; user_pseudo_id                | 653547550.1673451049&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; privacy_info                  | {null, null, No}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; user_properties               | []&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; user_first_touch_timestamp    | 1673451049581992&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; user_ltv                      | {0.0, USD}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; device                        | {mobile, Samsung,...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; geo                           | {Asia, Thailand, ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; app_info                      | null&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; traffic_source                | {(referral), refe...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; stream_id                     | 4111827120&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; platform                      | WEB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; event_dimensions              | null&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; ecommerce                     | null&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; items                         | []&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-RECORD 2---------------------------------------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; event_date                    | 20230318&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; event_timestamp               | 1679110659760543&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; event_name                    | scroll&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; event_params                  | [{campaign, {(ref...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; event_previous_timestamp      | null&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; event_value_in_usd            | null&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; event_bundle_sequence_id      | 1785323935&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; event_server_timestamp_offset | null&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; user_id                       | null&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; user_pseudo_id                | 653547550.1673451049&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; privacy_info                  | {null, null, No}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; user_properties               | []&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; user_first_touch_timestamp    | 1673451049581992&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; user_ltv                      | {0.0, USD}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; device                        | {mobile, Samsung,...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; geo                           | {Asia, Thailand, ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; app_info                      | null&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; traffic_source                | {(referral), refe...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; stream_id                     | 4111827120&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; platform                      | WEB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; event_dimensions              | null&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; ecommerce                     | null&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; items                         | []&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And nice thing about spark is that it supports nested schema!&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;root&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |-- event_date: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |-- event_timestamp: long (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |-- event_name: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |-- event_params: array (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- element: struct (containsNull = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- key: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- value: struct (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |    |-- string_value: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |    |-- int_value: long (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |    |-- float_value: double (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |    |-- double_value: double (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |-- event_previous_timestamp: long (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |-- event_value_in_usd: double (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |-- event_bundle_sequence_id: long (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |-- event_server_timestamp_offset: long (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |-- user_id: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |-- user_pseudo_id: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |-- privacy_info: struct (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- analytics_storage: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- ads_storage: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- uses_transient_token: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |-- user_properties: array (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- element: struct (containsNull = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- key: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- value: struct (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |    |-- string_value: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |    |-- int_value: long (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |    |-- float_value: double (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |    |-- double_value: double (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |    |-- set_timestamp_micros: long (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |-- user_first_touch_timestamp: long (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |-- user_ltv: struct (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- revenue: double (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- currency: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |-- device: struct (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- category: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- mobile_brand_name: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- mobile_model_name: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- mobile_marketing_name: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- mobile_os_hardware_model: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- operating_system: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- operating_system_version: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- vendor_id: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- advertising_id: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- language: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- is_limited_ad_tracking: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- time_zone_offset_seconds: long (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- browser: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- browser_version: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- web_info: struct (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- browser: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- browser_version: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- hostname: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |-- geo: struct (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- continent: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- country: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- region: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- city: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- sub_continent: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- metro: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |-- app_info: struct (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- id: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- version: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- install_store: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- firebase_app_id: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- install_source: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |-- traffic_source: struct (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- name: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- medium: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- source: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |-- stream_id: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |-- platform: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |-- event_dimensions: struct (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- hostname: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |-- ecommerce: struct (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- total_item_quantity: long (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- purchase_revenue_in_usd: double (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- purchase_revenue: double (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- refund_value_in_usd: double (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- refund_value: double (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- shipping_value_in_usd: double (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- shipping_value: double (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- tax_value_in_usd: double (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- tax_value: double (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- unique_items: long (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- transaction_id: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |-- items: array (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |-- element: struct (containsNull = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- item_id: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- item_name: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- item_brand: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- item_variant: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- item_category: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- item_category2: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- item_category3: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- item_category4: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- item_category5: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- price_in_usd: double (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- price: double (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- quantity: long (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- item_revenue_in_usd: double (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- item_revenue: double (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- item_refund_in_usd: double (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- item_refund: double (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- coupon: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- affiliation: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- location_id: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- item_list_id: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- item_list_name: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- item_list_index: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- promotion_id: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- promotion_name: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- creative_name: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |    |    |-- creative_slot: string (nullable = true)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Neato!&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>SecretOps with Teller</title>
          <pubDate>Sun, 19 Mar 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2023/03/secretops-with-teller/</link>
          <guid>https://karnwong.me/posts/2023/03/secretops-with-teller/</guid>
          <description xml:base="https://karnwong.me/posts/2023/03/secretops-with-teller/">&lt;p&gt;Raise your hands if you normally have to send &lt;code&gt;.env&lt;&#x2F;code&gt; files to your team members so they can start a project in dev environment.&lt;&#x2F;p&gt;
&lt;p&gt;While there is nothing wrong with this approach, it could introduce a lot of security risks, namely sharing secrets via plaintext protocol. Sure, you can share them on Slack, Discord, etc. But unless it&#x27;s encrypted with your own keys, it could be leaked if the said communication platform were to be breached.&lt;&#x2F;p&gt;
&lt;p&gt;You could uses a one-time pastebin to share the secrets. This would be a step up, but you still have to manually send each team member the secrets.&lt;&#x2F;p&gt;
&lt;p&gt;Some might say there are services like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;keybase.io&quot;&gt;https:&#x2F;&#x2F;keybase.io&lt;&#x2F;a&gt; where you can send messages encrypted with PGP key. Yay for security, but it has the same issue as above.&lt;&#x2F;p&gt;
&lt;p&gt;You use cloud, right? So most if not all cloud providers provide their own secrets management solution, so let&#x27;s use that. But then developers have to somehow fetch the secrets, and set it as environment variable so they can start a project. This would work until you update the dev secrets, and some developers would eventually forget to pull a new set of secrets before starting a project. This could result in half a day of wack-a-mole hunt for why it&#x27;s not working on their machine, but works on their friends&#x27;. Or you don&#x27;t, if you fetch secrets during a project initialization. But the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;12factor.net&#x2F;&quot;&gt;twelve-factor-app&lt;&#x2F;a&gt; would like a word.&lt;&#x2F;p&gt;
&lt;p&gt;I stumbled upon &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;tellerops&#x2F;teller&quot;&gt;teller&lt;&#x2F;a&gt; accidentally, but it seems to be able to do what I want: abstracting away secrets fetching and populate it as environment variable in one command.&lt;&#x2F;p&gt;
&lt;p&gt;Setting up is as easy as: &lt;code&gt;brew tap spectralops&#x2F;tap &amp;amp;&amp;amp; brew install teller&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To populate secrets as environment variables: &lt;code&gt;eval &quot;$(teller sh)&quot;&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I have a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kahnwong&#x2F;teller-demo&quot;&gt;repo&lt;&#x2F;a&gt; here you can tinker with. Please let me know if you find some quirks, since I plan to use this with my team next year 🎊.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Data transformation - Python vs SQL showdown</title>
          <pubDate>Sat, 18 Mar 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2023/03/data-transformation-python-vs-sql-showdown/</link>
          <guid>https://karnwong.me/posts/2023/03/data-transformation-python-vs-sql-showdown/</guid>
          <description xml:base="https://karnwong.me/posts/2023/03/data-transformation-python-vs-sql-showdown/">&lt;p&gt;For most people, using SQL to transform data is a no-brainer, seeing it&#x27;s a very versatile language, and doesn&#x27;t have quite a steep learning curve compared to python. There are some cases where SQL is more suitable for a task, but the reverse can also happen as well.&lt;&#x2F;p&gt;
&lt;p&gt;For instance, given a string conversion problem:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;if a string occurs only one time, replace it with &lt;code&gt;#&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;if a string occurs multiple times, replace it with &lt;code&gt;&amp;amp;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;gt; one&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;###&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;gt; three&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;###&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;gt; Heartbreak hotel&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;#&amp;amp;&amp;amp;&amp;amp;##&amp;amp;#&amp;amp;&amp;amp;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A solution in python would be:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; collections&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; Counter&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;three&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;s_counter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; Counter&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;output_str&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; char&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; s&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; s_counter&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;char&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        output_str&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    elif&lt;&#x2F;span&gt;&lt;span&gt; s_counter&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;char&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        output_str&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But a solution in SQL is...(thanks Emily @data-engineering-discord!):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;CREATE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; TABLE&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt; (string_value &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt;TEXT&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;INSERT INTO&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;  data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;VALUES&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;one&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;three&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Heartbreak hotel&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;select&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  string_value,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;  translate&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;    lower&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;string_value),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;    string_agg&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      chr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;      &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;      order by&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        chr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;    string_agg&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      subs,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;      &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;      order by&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        chr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;from&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    select&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      string_value,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      chr,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;      case&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        when&lt;&#x2F;span&gt;&lt;span&gt; count &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; then&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;      end&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; subs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    from&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        select&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          p.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;          count&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        from&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;            select&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              string_value,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              regexp_split_to_table (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;lower&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;string_value), &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;as&lt;&#x2F;span&gt;&lt;span&gt; chr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;            from&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;              data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          ) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;as&lt;&#x2F;span&gt;&lt;span&gt; p&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        group by&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;          1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;          2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      ) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;as&lt;&#x2F;span&gt;&lt;span&gt; q&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;as&lt;&#x2F;span&gt;&lt;span&gt; r&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;group by&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;  1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;😱😱😱😱😱😱😱😱😱&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Terraform RDS module with DNS setup</title>
          <pubDate>Fri, 17 Mar 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2023/03/terraform-rds-module-with-dns-setup/</link>
          <guid>https://karnwong.me/posts/2023/03/terraform-rds-module-with-dns-setup/</guid>
          <description xml:base="https://karnwong.me/posts/2023/03/terraform-rds-module-with-dns-setup/">&lt;p&gt;I love not having to manage databases. Hosting it on your compute is guaranteed to be cheaper, but I don&#x27;t want to be constantly worrying about backups and database upgrade &#x2F; maintenance.&lt;&#x2F;p&gt;
&lt;p&gt;AWS offers managed databases, known as RDS. Mostly I use postgres, which works well for most use cases. (It&#x27;s also a given that - if you don&#x27;t really need NoSQL database, then don&#x27;t use it).&lt;&#x2F;p&gt;
&lt;p&gt;If I spin up RDS postgres, I can reach it assuming I have set up the correct networking pathways. (And you shouldn&#x27;t expose your database to public, unless it&#x27;s for playground with no sensitive data.)&lt;&#x2F;p&gt;
&lt;p&gt;RDS itself returns a hostname with following format: &lt;code&gt;mydb.123456789012.us-east-1.rds.amazonaws.com&lt;&#x2F;code&gt;. This works well for all intent and purposes, but there are some cases where you might want it to be easy to remember, or that you want to switch database instance without incurring downtime. A simple solution is to setup a DNS record, but it would be nice if you can set it all up during database creation!&lt;&#x2F;p&gt;
&lt;p&gt;Enough intro, below is the terraform code (and yes, this works for a replica as well):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;hcl&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_db_instance&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;db&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  engine&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;            =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;engine&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  allocated_storage&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;allocated_storage&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  engine_version&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;    =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;engine_version&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  instance_class&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;    =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;instance_class&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  identifier&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;identifier&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  db_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;    =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;db_name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  username&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;   =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;username&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  password&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;   =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;password&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  replicate_source_db&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;source_db_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; for replica&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  parameter_group_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;parameter_group_name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  performance_insights_enabled&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;    =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  performance_insights_kms_key_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;performance_insights_kms_key_id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  deletion_protection&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;deletion_protection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;## networking&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  vpc_security_group_ids&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;vpc_security_group_ids&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  db_subnet_group_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;   =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;db_subnet_group_name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;## backup (in UTC)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  maintenance_window&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;maintenance_window&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  backup_window&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;           =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;backup_window&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  backup_retention_period&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;backup_window&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; null&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Backups are required in order to create a replica&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  skip_final_snapshot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;     =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;skip_final_snapshot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  apply_immediately&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;apply_immediately&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_route53_record&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;db&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  zone_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;zone_id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;    =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;dns_name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;    =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;CNAME&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  ttl&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;     =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  records&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;aws_db_instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;db&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</description>
      </item>
      <item>
          <title>Book Highlights - Engineering Management for the Rest of Us by Sarah Drasner</title>
          <pubDate>Thu, 16 Mar 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2023/03/book-highlights---engineering-management-for-the-rest-of-us-by-sarah-drasner/</link>
          <guid>https://karnwong.me/posts/2023/03/book-highlights---engineering-management-for-the-rest-of-us-by-sarah-drasner/</guid>
          <description xml:base="https://karnwong.me/posts/2023/03/book-highlights---engineering-management-for-the-rest-of-us-by-sarah-drasner/">&lt;p&gt;Organizational health lies in being able to work together.&lt;&#x2F;p&gt;
&lt;p&gt;As a manager, our job is to try as much as we can to drive balance and clarity.&lt;&#x2F;p&gt;
&lt;p&gt;A happy, driven team sees the wider purpose of their work and also feels empowered to execute tasks individually.&lt;&#x2F;p&gt;
&lt;p&gt;“You can’t call yourself a leader by coming into a situation that is by nature uncertain, ambiguous—and create confusion. You have to create clarity where none exists.” —Satya Nadella, CEO of Microsoft&lt;&#x2F;p&gt;
&lt;p&gt;I have never seen employees more demoralized than when they’re unsure where their career is headed and whether their title or compensation is fair. It’s frustrating, exhausting, and can lead to burnout. It’s also incredibly distracting. Who can get their job done when they have no clue if what they’re doing is valued?&lt;&#x2F;p&gt;
&lt;p&gt;Our collective aim as managers should be taking the careers of our employees as seriously as we do the team’s technical&#x2F;work processes.&lt;&#x2F;p&gt;
&lt;p&gt;If you’re strong and care about your team as people, it can feel unnatural to teach someone to advocate for themselves instead of moving things out of their way.&lt;&#x2F;p&gt;
&lt;p&gt;The first part of building healthy teams is admitting you won’t know everything, and this may be a time where you need to listen more than you talk.&lt;&#x2F;p&gt;
&lt;p&gt;The culture of your team is only as strong as the worst behavior it tolerates. It’s your job to speak up.&lt;&#x2F;p&gt;
&lt;p&gt;It’s best if a manager learns an employee’s Ultimate Goals early on. Where do they see themselves in five years? What kind of work do they like to do most? What environments do they work in best and which ones are the most difficult? A manager can’t always facilitate the ideal situation, but having this information is still extremely valuable for cultivating a person’s career trajectory, for the work that needs to be done, and for a general understanding of what will keep people working well together.&lt;&#x2F;p&gt;
&lt;p&gt;Career ladders alone will not create clarity—as managers, we need to put them into action.&lt;&#x2F;p&gt;
&lt;p&gt;On career ladders:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;To get to “senior,” you’re the best “you” you can be — you perform your role exceedingly well, and you’ve reached a high potential for your own output.&lt;&#x2F;li&gt;
&lt;li&gt;To get to “staff,” your focus is really to expand beyond yourself. You start teaching people the great things you’ve learned and help serve their needs.&lt;&#x2F;li&gt;
&lt;li&gt;To get to “principal,” you’re creating systems that scale beyond yourself. You’re no longer helping folks operate like you — you’re helping them where they are. A lot of your activities are related to enabling the success of everyone around you.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I typically have an employee read aloud every list item in their current role to me, then self-assess the progress they’ve made on each item. I sound off a bit. We generally align; people tend to be fair and honest about their progress. I personally think it’s important that the employee read their list to me instead of the other way around. There’s a sense of ownership that way.&lt;&#x2F;p&gt;
&lt;p&gt;It’s tempting to think that over-performers need less guidance, but I’ve found that they tend to need more clarity on tasks, not less, in order to define scope and help point them in a good direction.&lt;&#x2F;p&gt;
&lt;p&gt;I’ve also seen underperformers turn around after the career laddering process. What one might see as a lazy quality in a person might actually be a symptom of misalignment with the purpose of the tasks. A career ladder helps them recognize what, when, why, and how the things they’re working on fit into the bigger picture.&lt;&#x2F;p&gt;
&lt;p&gt;Ask your team members how they prefer to get feedback, and listen to the answer. The more they are in tune with their own state of mind, the better they think critically and communicate.&lt;&#x2F;p&gt;
&lt;p&gt;If you’re inviting everyone to meetings out of fear of hurt feelings, it’s likely not a problem with your meetings, and more a sign that roles and responsibilities aren’t clear for everyone.&lt;&#x2F;p&gt;
&lt;p&gt;It’s the job of a manager to disambiguate healthy conflict from attack, so that respectful discourse is encouraged.&lt;&#x2F;p&gt;
&lt;p&gt;“You have to know your preferences well, because no matter what you do, someone will tell you you’re wrong.”&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Book Highlights - The Staff Engineer&#x27;s Path by Tanya Reilly</title>
          <pubDate>Wed, 15 Mar 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2023/03/book-highlights---the-staff-engineers-path/</link>
          <guid>https://karnwong.me/posts/2023/03/book-highlights---the-staff-engineers-path/</guid>
          <description xml:base="https://karnwong.me/posts/2023/03/book-highlights---the-staff-engineers-path/">&lt;h2 id=&quot;opportunity-cost&quot;&gt;Opportunity cost&lt;a class=&quot;zola-anchor&quot; href=&quot;#opportunity-cost&quot; aria-label=&quot;Anchor link for: opportunity-cost&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Staff engineers’ skills are usually in high demand. If you’re assigned to a single team, you may not be top of mind for solving a problem elsewhere in the org, or your manager may be unwilling to let you go.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;losing-empathy&quot;&gt;Losing empathy&lt;a class=&quot;zola-anchor&quot; href=&quot;#losing-empathy&quot; aria-label=&quot;Anchor link for: losing-empathy&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;It’s easy to overfocus and forget that the rest of the world exists, or start thinking of other technology areas as trivial compared to your rich, nuanced domain.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;escaping-the-echo-chamber&quot;&gt;Escaping the echo chamber&lt;a class=&quot;zola-anchor&quot; href=&quot;#escaping-the-echo-chamber&quot; aria-label=&quot;Anchor link for: escaping-the-echo-chamber&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;When you find yourself in an echo chamber where everyone you meet holds the same set of opinions, it can be a shock when you connect with peers in other groups and discover that some of their views are just…different.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-staff-engineer-navigating-tricky-terrain&quot;&gt;A staff engineer navigating tricky terrain&lt;a class=&quot;zola-anchor&quot; href=&quot;#a-staff-engineer-navigating-tricky-terrain&quot; aria-label=&quot;Anchor link for: a-staff-engineer-navigating-tricky-terrain&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2023&#x2F;03&#x2F;book-highlights---the-staff-engineers-path&#x2F;images&#x2F;20230218170349.webp&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;secret-or-open&quot;&gt;Secret or open?&lt;a class=&quot;zola-anchor&quot; href=&quot;#secret-or-open&quot; aria-label=&quot;Anchor link for: secret-or-open&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;How much does everyone know? In secret organizations, information is currency and nobody gives it away easily. Everyone’s calendars are private. Slack channels are invite-only. Often you can get access to something if you ask for it, but you have to know it exists! When all information is need-to-know, it’s harder to come up with creative solutions or really understand why something’s not working.&lt;&#x2F;p&gt;
&lt;p&gt;In open organizations, you’ll have access to everything (even messy first drafts!). You might get decision fatigue from choosing which information to consume. You might not know which documents are official and need action, and which are just early ideas. And open information can lead to more drama: it’s harder for bad ideas to be quietly shut down.&lt;&#x2F;p&gt;
&lt;p&gt;Knowing the cultural expectations around sharing is crucial. In a culture that keeps knowledge locked down, you’ll lose your boss’s trust if you reshare something they told you in confidence. In a more open company, you’ll be considered political or untrustworthy if you withhold information or don’t make sure everyone knows what’s going on.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;most-companies-will-be-somewhere-in-the-middle-on-each-of-these-attributes&quot;&gt;Most companies will be somewhere in the middle on each of these attributes&lt;a class=&quot;zola-anchor&quot; href=&quot;#most-companies-will-be-somewhere-in-the-middle-on-each-of-these-attributes&quot; aria-label=&quot;Anchor link for: most-companies-will-be-somewhere-in-the-middle-on-each-of-these-attributes&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2023&#x2F;03&#x2F;book-highlights---the-staff-engineers-path&#x2F;images&#x2F;20230218170520.webp&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;pathological&quot;&gt;Pathological&lt;a class=&quot;zola-anchor&quot; href=&quot;#pathological&quot; aria-label=&quot;Anchor link for: pathological&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;A low-cooperation culture where power and status are the goal and people hoard information; in Westrum’s words, “a preoccupation with personal power, needs, and glory”&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-chasm-between-an-infrastructure-and-a-product-engineering-organization&quot;&gt;The chasm between an infrastructure and a product engineering organization&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-chasm-between-an-infrastructure-and-a-product-engineering-organization&quot; aria-label=&quot;Anchor link for: the-chasm-between-an-infrastructure-and-a-product-engineering-organization&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2023&#x2F;03&#x2F;book-highlights---the-staff-engineers-path&#x2F;images&#x2F;20230218170659.webp&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;disputed-territory&quot;&gt;Disputed territory&lt;a class=&quot;zola-anchor&quot; href=&quot;#disputed-territory&quot; aria-label=&quot;Anchor link for: disputed-territory&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;It’s very hard to draw team boundaries in a way that lets each team work autonomously. No matter how opinionated your APIs, contracts, or team charters, there will inevitably be some pieces of work that multiple teams think they own, and navigating those disputes can feel risky.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-new-paved-road-is-beautiful-but-most-of-the-places-people-actually-want-to-go-are-deep-in-the-marsh&quot;&gt;The new paved road is beautiful, but most of the places people actually want to go are deep in the marsh&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-new-paved-road-is-beautiful-but-most-of-the-places-people-actually-want-to-go-are-deep-in-the-marsh&quot; aria-label=&quot;Anchor link for: the-new-paved-road-is-beautiful-but-most-of-the-places-people-actually-want-to-go-are-deep-in-the-marsh&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2023&#x2F;03&#x2F;book-highlights---the-staff-engineers-path&#x2F;images&#x2F;20230218170803.webp&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;asking-to-join-in&quot;&gt;Asking to join in&lt;a class=&quot;zola-anchor&quot; href=&quot;#asking-to-join-in&quot; aria-label=&quot;Anchor link for: asking-to-join-in&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Once you discover a meeting where important decisions get made, it’s natural to want to be part of it. But you’ll need a compelling story for why that should happen. It seems obvious, but your reasons should be about impact to your organization, not to you personally. No matter how much your peer managers like you, framing your exclusion as being bad for your career advancement will be unlikely to change hearts and minds. Show how including you will make your organization better at achieving its goals. Show what you can bring that’s not already there. Have a clear narrative about why you need access, practice your talking points, and go ask to join.&lt;&#x2F;p&gt;
&lt;p&gt;You will probably get some resistance. Adding someone to a group is rarely free for the people who are already there. Every extra person in any meeting slows it down, extends discussions, and reduces attendees’ willingness to be vulnerable or brutally honest. If the group is used to working together, every new person resets the dynamic; to some extent, attendees have to learn to work together again.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;shadow-org-chart&quot;&gt;Shadow org chart&lt;a class=&quot;zola-anchor&quot; href=&quot;#shadow-org-chart&quot; aria-label=&quot;Anchor link for: shadow-org-chart&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Shadow org chart: the unwritten structures through which power and influence flow. The shadow org chart helps you understand who the influencers of the group are, and it’s probably not the same as the actual org chart. These influencers are the people you need to convince before a change can happen.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;engineers-stop-growing&quot;&gt;Engineers stop growing&lt;a class=&quot;zola-anchor&quot; href=&quot;#engineers-stop-growing&quot; aria-label=&quot;Anchor link for: engineers-stop-growing&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Focusing only on short-term goals limits the way you think about and frame your work, and how much ownership you take of the work that falls into the cracks between tasks. If the team is trying to achieve a big project, they’ll have to identify the gaps between the assigned tasks and figure out how to fill them, building skills in the process. A team that’s used to iterating on short, clearly specified goals won’t build muscle for bigger, more difficult projects and won’t be able to tell the story of why they did what they did.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-story-of-where-you-were-and-how-much-progress-you-ve-made-as-well-as-where-you-re-going&quot;&gt;The story of where you were and how much progress you’ve made as well as where you’re going&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-story-of-where-you-were-and-how-much-progress-you-ve-made-as-well-as-where-you-re-going&quot; aria-label=&quot;Anchor link for: the-story-of-where-you-were-and-how-much-progress-you-ve-made-as-well-as-where-you-re-going&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2023&#x2F;03&#x2F;book-highlights---the-staff-engineers-path&#x2F;images&#x2F;20230218171015.webp&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;tragedy-of-the-commons&quot;&gt;Tragedy of the commons&lt;a class=&quot;zola-anchor&quot; href=&quot;#tragedy-of-the-commons&quot; aria-label=&quot;Anchor link for: tragedy-of-the-commons&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Teams pursuing their own best action without coordinating with others leads to an outcome that is bad for everyone. There’s that local maximum again.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;depending-on-the-size-of-the-problem-you-might-start-with-an-engineering-wide-vision-a-team-scoped-vision-or-something-in-between-don-t-create-a-vision-strategy-etc-unless-you-need-it&quot;&gt;Depending on the size of the problem, you might start with an engineering-wide vision, a team-scoped vision, or something in between. Don’t create a vision, strategy, etc., unless you need it&lt;a class=&quot;zola-anchor&quot; href=&quot;#depending-on-the-size-of-the-problem-you-might-start-with-an-engineering-wide-vision-a-team-scoped-vision-or-something-in-between-don-t-create-a-vision-strategy-etc-unless-you-need-it&quot; aria-label=&quot;Anchor link for: depending-on-the-size-of-the-problem-you-might-start-with-an-engineering-wide-vision-a-team-scoped-vision-or-something-in-between-don-t-create-a-vision-strategy-etc-unless-you-need-it&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2023&#x2F;03&#x2F;book-highlights---the-staff-engineers-path&#x2F;images&#x2F;20230218171109.webp&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;embrace-the-boring-ideas&quot;&gt;Embrace the Boring Ideas&lt;a class=&quot;zola-anchor&quot; href=&quot;#embrace-the-boring-ideas&quot; aria-label=&quot;Anchor link for: embrace-the-boring-ideas&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;I kind of think writing about engineering strategy is hard because good strategy is pretty boring, and it’s kind of boring to write about. Also I think when people hear “strategy” they think “innovation.” If you write something interesting, it’s probably wrong. This seems directionally correct, certainly most strategy is synthesis and that point isn’t often made!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;step-away&quot;&gt;Step away&lt;a class=&quot;zola-anchor&quot; href=&quot;#step-away&quot; aria-label=&quot;Anchor link for: step-away&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Tech companies’ promotion systems can incentivize engineers to feel like they need to “win” a technical direction or be the face of a project. This competition can lead to “ape games”: dominance plays and politicking, where each person tries to establish themselves as the leader in the space, considering other people’s ideas to be threatening. It’s toxic to collaboration and makes success much harder to achieve.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;robert-konigsberg&quot;&gt;Robert Konigsberg&lt;a class=&quot;zola-anchor&quot; href=&quot;#robert-konigsberg&quot; aria-label=&quot;Anchor link for: robert-konigsberg&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;“Don’t forget that just because something came from your brain doesn’t make it the best idea.”&lt;&#x2F;p&gt;
&lt;h2 id=&quot;set-scope&quot;&gt;Set Scope&lt;a class=&quot;zola-anchor&quot; href=&quot;#set-scope&quot; aria-label=&quot;Anchor link for: set-scope&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Be practical about what’s possible. If your vision of the future involves something entirely out of your control, like a change of CEO or an adjustment in your customers’ buying patterns, you’ve crossed into magical thinking. Work around your fixed constraints, rather than ignoring them or wishing they were different.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;nemawashi&quot;&gt;Nemawashi&lt;a class=&quot;zola-anchor&quot; href=&quot;#nemawashi&quot; aria-label=&quot;Anchor link for: nemawashi&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;If you keep your stakeholders aligned as you go along, your document won’t ever have a point where you’re sharing a finished document with a group of people who are learning about it for the first time. When I spoke with Zach Millman, pillar tech lead at Asana, about creating a strategy there, he told me that he used the process of nemawashi, one of the pillars of the Toyota Production System. It means sharing information and laying the foundations so that by the time a decision is made, there’s already a consensus of opinion.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;recruiting-people&quot;&gt;Recruiting people&lt;a class=&quot;zola-anchor&quot; href=&quot;#recruiting-people&quot; aria-label=&quot;Anchor link for: recruiting-people&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Try to avoid relying on one person’s very specific skill set. People move between companies often, and you don’t want a single point of failure.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;blocked-by-a-single-button-click&quot;&gt;Blocked by a Single &lt;code&gt;$%@$%&lt;&#x2F;code&gt; Button Click&lt;a class=&quot;zola-anchor&quot; href=&quot;#blocked-by-a-single-button-click&quot; aria-label=&quot;Anchor link for: blocked-by-a-single-button-click&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Why did we insist on a week’s notice? Because these configurations weren’t our only work. Hundreds of teams used our banks of balancers, and load balancing was just one of the four critical services my team supported. We didn’t want to react constantly: we wanted to plan out our weeks, and to make these configuration changes in batches rather than continually restarting services every time. As a result, we had little sympathy for people who came in hot and angry about why we hadn’t done the thing they’d told us about only a few hours ago. Our team motto became “lack of planning on your part is not an emergency on mine.”&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-are-you-asking-for&quot;&gt;What Are You Asking For?&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-are-you-asking-for&quot; aria-label=&quot;Anchor link for: what-are-you-asking-for&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;I love the “Three Bullets and a Call to Action” method that Brian Fitzpatrick and Ben Collins-Sussman outline in their book, Debugging Teams (O’Reilly). As they write: “A good Three Bullets and a Call to Action email contains (at most) three bullet points detailing the issue at hand, and one—and only one—call to action. That’s it, nothing more—you need to write an email that can be easily forwarded along. If you ramble or put four completely different things in the email, you can be certain that they’ll pick only one thing to respond to, and it will be the item that you care least about. Or worse, the mental overhead is high enough that your mail will get dropped entirely.”&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-team-declared-victory-and-went-home-but-there-was-another-better-treasure-they-never-got-to&quot;&gt;The team declared victory and went home—but there was another, better treasure they never got to&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-team-declared-victory-and-went-home-but-there-was-another-better-treasure-they-never-got-to&quot; aria-label=&quot;Anchor link for: the-team-declared-victory-and-went-home-but-there-was-another-better-treasure-they-never-got-to&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2023&#x2F;03&#x2F;book-highlights---the-staff-engineers-path&#x2F;images&#x2F;20230218171842.webp&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;it-s-built-on-a-shaky-foundation&quot;&gt;It’s Built on a Shaky Foundation&lt;a class=&quot;zola-anchor&quot; href=&quot;#it-s-built-on-a-shaky-foundation&quot; aria-label=&quot;Anchor link for: it-s-built-on-a-shaky-foundation&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;I used to work in a data center, a long time ago, and one thing I learned there is that there’s no such thing as a temporary solution. If someone ran a cable from one rack to another without neatly cabling and labeling it, it would stay there until the server was decommissioned. The same is true for every temporary hack: if you don’t have it in good shape by the end of the project, it’s going to take extraordinary effort to clean it up later.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;know-things&quot;&gt;Know Things&lt;a class=&quot;zola-anchor&quot; href=&quot;#know-things&quot; aria-label=&quot;Anchor link for: know-things&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;No matter how good your leadership, you can’t be a technical leader without the “technical” part. Your big-picture thinking, project execution, credibility, and influence are underpinned by knowledge and experience. A big part of the value proposition of hiring you is your knowledge: you have seen some things.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;build-experience&quot;&gt;Build experience&lt;a class=&quot;zola-anchor&quot; href=&quot;#build-experience&quot; aria-label=&quot;Anchor link for: build-experience&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;It may feel like a compliment when someone offers you the job of manager—hell, take the compliment —but they are not doing you any favors when it comes to your career or your ability to be effective.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;admit-what-you-don-t-know&quot;&gt;Admit what you don’t know&lt;a class=&quot;zola-anchor&quot; href=&quot;#admit-what-you-don-t-know&quot; aria-label=&quot;Anchor link for: admit-what-you-don-t-know&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Admitting ignorance is one of the most important things we can do as tech leads, senior engineers, mentors, managers, and other influencers of team culture.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;understand-your-own-context&quot;&gt;Understand your own context&lt;a class=&quot;zola-anchor&quot; href=&quot;#understand-your-own-context&quot; aria-label=&quot;Anchor link for: understand-your-own-context&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;A huge part of self-awareness is understanding that you have a perspective, that your context is not the universal context, and that your opinions and knowledge are specific to you. You’ll need to escape your echo chamber every time you talk to teams in other areas or explain technical topics to nonengineers. You’ll know what information you have that they might not, so you can bridge that gap.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;don-t-delegate-through-neglect&quot;&gt;Don’t delegate through neglect&lt;a class=&quot;zola-anchor&quot; href=&quot;#don-t-delegate-through-neglect&quot; aria-label=&quot;Anchor link for: don-t-delegate-through-neglect&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;If glue work is needed for your organization or your project, recognize it and understand who is doing it. Be aware that managers, promotion committees, and future employers might consider this work to be leadership when a staff engineer does it, but dismiss it when a more junior engineer does. So take ownership and do a lot of the work that’s not anybody’s job but that furthers your goals. Redirect your junior colleagues toward tasks that will develop their careers instead.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;remember-there-s-a-team&quot;&gt;Remember There’s a Team&lt;a class=&quot;zola-anchor&quot; href=&quot;#remember-there-s-a-team&quot; aria-label=&quot;Anchor link for: remember-there-s-a-team&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;The final thought in focusing on the mission: remember you’re not doing this work alone. While you may be the best coder on the team, the most experienced engineer, or the fastest problem solver, that doesn’t mean you should jump on all of the problems. You’re working as part of a team, not a collection of competing individuals. Don’t become a single point of failure where the team can’t get anything done when you’re not available. It’s not sustainable. It hides problems.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;create-future-leaders&quot;&gt;Create Future Leaders&lt;a class=&quot;zola-anchor&quot; href=&quot;#create-future-leaders&quot; aria-label=&quot;Anchor link for: create-future-leaders&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;The degree to which other people want to work with you is a direct indication of how successful you’ll be in your career as an engineer. Be the engineer that everyone wants to work with.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;peer-reviews&quot;&gt;Peer reviews&lt;a class=&quot;zola-anchor&quot; href=&quot;#peer-reviews&quot; aria-label=&quot;Anchor link for: peer-reviews&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;It’s a common joke in tech women circles that you know you’re acting at senior level when you get your first peer review saying you’re “abrasive.”&lt;&#x2F;p&gt;
&lt;h2 id=&quot;process-preamble&quot;&gt;Process Preamble&lt;a class=&quot;zola-anchor&quot; href=&quot;#process-preamble&quot; aria-label=&quot;Anchor link for: process-preamble&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;If you write down every edge case, you end up with a three-ring binder of policy and legalese, and it probably still won’t cover every situation. And everyone still hates it!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;lara-hogan&quot;&gt;Lara Hogan&lt;a class=&quot;zola-anchor&quot; href=&quot;#lara-hogan&quot; aria-label=&quot;Anchor link for: lara-hogan&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Your colleagues won’t learn as much if you only delegate the work after you’ve turned it into “beautifully packaged, cleanly wrapped gifts.” If you instead give them “a messy, unscoped project with a bit of a safety net,” they’ll get a chance to hone their problem-solving abilities, build their own support system, and stretch their skill set. A messy project is a learning opportunity that’s hard to get otherwise.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;delegation&quot;&gt;Delegation&lt;a class=&quot;zola-anchor&quot; href=&quot;#delegation&quot; aria-label=&quot;Anchor link for: delegation&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;This pattern is common in recruiting mails: “Come do exactly the thing you’re currently doing, but at another company.” There are times when that will work, but the most successful recruitment I’ve seen is for roles that offer people a step up, something slightly scary.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;change-teams&quot;&gt;Change Teams&lt;a class=&quot;zola-anchor&quot; href=&quot;#change-teams&quot; aria-label=&quot;Anchor link for: change-teams&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Moving between teams or organizations can be an excellent way of building bridges: you’ll still have contacts on your own team, and you’ll bring knowledge and culture with you to the new one. You’ll also bring perspective: you already have an outside view of the team and how they’re perceived by the rest of the organization.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;take-a-management-role&quot;&gt;Take a Management Role&lt;a class=&quot;zola-anchor&quot; href=&quot;#take-a-management-role&quot; aria-label=&quot;Anchor link for: take-a-management-role&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;The best frontline eng managers in the world are the ones that are never more than 2-3 years removed from hands-on work, full time down in the trenches. The best individual contributors are the ones who have done time in management. And the best technical leaders in the world are often the ones who do both. Back and forth. Like a pendulum.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;charity-majors&quot;&gt;Charity Majors&lt;a class=&quot;zola-anchor&quot; href=&quot;#charity-majors&quot; aria-label=&quot;Anchor link for: charity-majors&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;“If you’re a manager, your job is to get better at management. Don’t try to cling to your former glory.”&lt;&#x2F;p&gt;
&lt;h2 id=&quot;prepare-to-reset&quot;&gt;Prepare to Reset&lt;a class=&quot;zola-anchor&quot; href=&quot;#prepare-to-reset&quot; aria-label=&quot;Anchor link for: prepare-to-reset&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Not all newly hired senior leaders are entirely committed to or feel comfortable turning themselves into the leader the organization truly needs, rather than the leader they’ve grown to be over the past years. Many leaders take the opposite approach of trying to mold the organization in their image or the image of the past workplace. Engineering leaders brought into embattled organizations tasked with stabilizing the chaos are often heavily incentivized to do this. Many a time these folks, in my experience, tend to fail harder and more often than those who try to learn the organizational ropes and tailor their leadership style to fit the organizational culture.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Load balancer 101, thou shalt not be alone</title>
          <pubDate>Sat, 10 Dec 2022 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2022/12/load-balancers-101,-thou-shalt-not-be-alone/</link>
          <guid>https://karnwong.me/posts/2022/12/load-balancers-101,-thou-shalt-not-be-alone/</guid>
          <description xml:base="https://karnwong.me/posts/2022/12/load-balancers-101,-thou-shalt-not-be-alone/">&lt;p&gt;Scaling, the dreaded word among developers, because this means more complexity. But why do we need scaling?&lt;&#x2F;p&gt;
&lt;p&gt;Imagine a super busy corner store. During early mornings, there might not be a lot of customers, so one cashier might be enough to handle all customers. But during afternoons or evenings, more customers would flock to the store, and our only cashier couldn&#x27;t checkout fast enough, and this means losing potential customers.&lt;&#x2F;p&gt;
&lt;p&gt;Is there a way to solve this? Good news is that&#x27;s a &quot;yes.&quot; However, there are a few implications. You could replace the only cashier with a cashier who can do a checkout faster. But, you could also hire more cashiers as temps during peak hours, and this means cheaper cost per customer compared to maxing out the only cashier. Maximizing a single resource is &quot;vertical scaling&quot;, whereas adding more resources of the same caliber is called &quot;horizontal scaling.&quot; Couldn&#x27;t find a more apt name myself.&lt;&#x2F;p&gt;
&lt;p&gt;I did mention about complexity. Vertical scaling is less complex than horizontal scaling, because you don&#x27;t need to coordinate the resources. Because if you have three instances of a website running, but there&#x27;s only one entrypoint (the website&#x27;s domain name) then how are you going to distribute the requests to each instance?&lt;&#x2F;p&gt;
&lt;p&gt;Load balancer to the rescue. Essentially it acts as a reception front, where it sends incoming requests to available instances. Think of a busy check-in queue in a hotel. You would be waiting in a single line, and when a counter frees up the next person would go there.&lt;&#x2F;p&gt;
&lt;p&gt;So how do we actually do this with a website? Common wisdom says using cloud, add a task to container runtime engine, set scaling policy, and route them to a load balancer.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.pulumi.com&#x2F;challenge&#x2F;holiday-shopping&#x2F;&quot;&gt;load balancer challenge from pulumi&lt;&#x2F;a&gt; you could try out, since their example is tested to be working, which would save a lot of time from stitching up stuff from online articles and official documentations. Note that in this challenge, task scaling isn&#x27;t implemented, so get your itchy fingers working and implement it!&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Cross-platform package (+env) management with Nix</title>
          <pubDate>Sat, 03 Dec 2022 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2022/12/cross-platform-package-env-management-with-nix/</link>
          <guid>https://karnwong.me/posts/2022/12/cross-platform-package-env-management-with-nix/</guid>
          <description xml:base="https://karnwong.me/posts/2022/12/cross-platform-package-env-management-with-nix/">&lt;p&gt;For many years, installing a package on linux means either:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Compiling a binary from source, then install it. -&amp;gt; I think we know why this didn&#x27;t catch on for the mass.&lt;&#x2F;li&gt;
&lt;li&gt;Downloading a compiled binary for your system&#x27;s architecture and platform. -&amp;gt; This requires you to also move the executable to something like &lt;code&gt;&#x2F;usr&#x2F;local&#x2F;bin&lt;&#x2F;code&gt; otherwise it won&#x27;t be discoverable throughout the system.&lt;&#x2F;li&gt;
&lt;li&gt;Using system&#x27;s package manager: &lt;code&gt;apt&lt;&#x2F;code&gt;, &lt;code&gt;apk&lt;&#x2F;code&gt;, &lt;code&gt;yum&lt;&#x2F;code&gt;, &lt;code&gt;brew&lt;&#x2F;code&gt;, etc. -&amp;gt; Yay finally something that&#x27;s easy to use. Phew!&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Then the dot-com era happened, and the digital transformation, you name it. This was before cloud, so companies set up their own data centers and have to administer and maintain the servers themselves. And it&#x27;s not fun if you have to perform the same machine configuration for the whole fleet. This problem was solved by tools like Ansible, Chef, Puppet, etc, to set up a machine&#x27;s configuration en masse.&lt;&#x2F;p&gt;
&lt;p&gt;So why is this still an issue? Because there are sizable amount of developers &#x2F; engineers working on a Mac, and deploy to a Unix-based system. This means those machine setup configurations don&#x27;t work with Mac, and vice versa, because they use different package managers. Technically you can create a separate set of configs for Mac, but this means maintaining two different setup scripts, which aim to do the same thing, just on different platforms. Sooner or later the configuration would get out of sync 😱.&lt;&#x2F;p&gt;
&lt;p&gt;However there are still issues with using system&#x27;s package manager in linux, namely for some bleeding edge packages, or new package versions that are not yet available in your current linux version, usually involve adding an explicit repository url, adding a keyring, or having to upgrade the system altogether so it can fetch the new repository isn&#x27;t fun. I&#x27;ve yet to see why we can&#x27;t install a new package version when its functionalities have almost nothing to do with system version. Otherwise system&#x27;s package manager is fast and reliable.&lt;&#x2F;p&gt;
&lt;p&gt;Meanwhile there&#x27;s &lt;code&gt;brew&lt;&#x2F;code&gt; for darwin. I only use it because it was one of the few options we have as close as an actual package manager. But it&#x27;s very slow and performing repo update and installing new apps can take forever, especially if you have to check multiple packages.&lt;&#x2F;p&gt;
&lt;p&gt;Not only that, once you have initialized a system, and over time you modified its configurations, how can you be sure that all the changes are populated back to your Ansible script? This would be a manual process prone to errors.&lt;&#x2F;p&gt;
&lt;p&gt;But humans are awesome, so the best and brightest came up with &lt;code&gt;nix&lt;&#x2F;code&gt;, as in &lt;code&gt;*nix&lt;&#x2F;code&gt;, a cross-platform package manager that works on both Unix and darwin (a platform name of Mac OS).&lt;&#x2F;p&gt;
&lt;p&gt;With nix, you can utilize &lt;code&gt;home-manager&lt;&#x2F;code&gt; to populate the packages&#x2F;configs on your system, in which it would symlink your configs to nix home, to be symlinked via &lt;code&gt;home-manager switch&lt;&#x2F;code&gt; to actual destination, with &lt;code&gt;read only&lt;&#x2F;code&gt; file permission. This means if you use nix to initialize &lt;code&gt;~&#x2F;.ssh&#x2F;config&lt;&#x2F;code&gt; and you want to change it by hand, it would throw &quot;this file has read-only permission&quot; error, this way the only way to update the configs is through nix.&lt;&#x2F;p&gt;
&lt;p&gt;Also with the full system configurations, it takes 6 seconds flat to apply the delta diff 😎.&lt;&#x2F;p&gt;
&lt;p&gt;Some interesting snippets from &lt;code&gt;home.nix&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;initialize-dotfiles&quot;&gt;Initialize dotfiles&lt;a class=&quot;zola-anchor&quot; href=&quot;#initialize-dotfiles&quot; aria-label=&quot;Anchor link for: initialize-dotfiles&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;nix&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;home&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;file&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.ssh&#x2F;config&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;source&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; .&#x2F;dotfiles&#x2F;.ssh&#x2F;config&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;git-config&quot;&gt;Git config&lt;a class=&quot;zola-anchor&quot; href=&quot;#git-config&quot; aria-label=&quot;Anchor link for: git-config&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Notice the &lt;code&gt;delta&lt;&#x2F;code&gt; block, this automatically populate required configs in &lt;code&gt;.gitignore&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;nix&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;programs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;git&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; git config --global --edit for raw config content&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;  enable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;  userName&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;  userEmail&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;  delta&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;    enable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;    options&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;      navigate&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;      side-by-side&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;  extraConfig&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;    diff&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;colorMoved&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;default&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;    merge&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;conflictstyle&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;diff3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;neovim-config&quot;&gt;Neovim config&lt;a class=&quot;zola-anchor&quot; href=&quot;#neovim-config&quot; aria-label=&quot;Anchor link for: neovim-config&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Nix doesn&#x27;t use &lt;code&gt;vim-plug&lt;&#x2F;code&gt; by default, and I found some plugins failed installing via nix, hence the &lt;code&gt;extraConfig&lt;&#x2F;code&gt; block for installing vim plugins. Don&#x27;t forget to run &lt;code&gt;nvim --headless +PlugInstall +qall&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;nix&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;programs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;neovim&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;  enable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;  viAlias&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;  vimAlias&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;  vimdiffAlias&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;  plugins&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; with&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; pkgs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;vimPlugins&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;    vim-plug&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ]&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;  extraConfig&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    runtime! plug.vim&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    call plug#begin()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;diff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    Plug &amp;#39;mhinz&#x2F;vim-signify&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    call plug#end()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&amp;quot; config&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    set number&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;  &amp;#39;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;conditional-package-list-for-each-platform&quot;&gt;Conditional package list for each platform&lt;a class=&quot;zola-anchor&quot; href=&quot;#conditional-package-list-for-each-platform&quot; aria-label=&quot;Anchor link for: conditional-package-list-for-each-platform&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Maybe you only use linux for servers, so you might not need GUI apps, or some packages are not available on darwin, etc.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;nix&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;home&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;packages&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt; with&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; pkgs&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;  let&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Packages to always install.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;    common&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;      fish&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;      starship&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ]&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;    linux_only&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;      iotop&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;      ntfs3g&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;      progress&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ]&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;    mac_only&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;      mpv&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ]&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;  in&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;  common&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ++&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;if&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; stdenv&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;isLinux&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; th&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;en&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; linux_only&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; el&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;se&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; mac_only&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Head over to the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kahnwong&#x2F;nix&quot;&gt;repo&lt;&#x2F;a&gt; for my full setup. And remember: great artists &lt;em&gt;steal&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Load credentials into your shell via Bitwarden CLI - Fish edition</title>
          <pubDate>Tue, 29 Nov 2022 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2022/11/load-credentials-into-your-shell-via-bitwarden-cli---fish-edition/</link>
          <guid>https://karnwong.me/posts/2022/11/load-credentials-into-your-shell-via-bitwarden-cli---fish-edition/</guid>
          <description xml:base="https://karnwong.me/posts/2022/11/load-credentials-into-your-shell-via-bitwarden-cli---fish-edition/">&lt;p&gt;Recently I work with GitHub CLI a lot, and having to constantly fire up Bitwarden app to retrieve &lt;code&gt;GITHUB_TOKEN&lt;&#x2F;code&gt; gets old real fast...&lt;&#x2F;p&gt;
&lt;p&gt;I was thinking of storing it in a gist in a password manager, luckily someone had the same idea and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.gruntwork.io&#x2F;how-to-securely-store-secrets-in-bitwarden-cli-and-load-them-into-your-zsh-shell-when-needed-f12d4d040df&quot;&gt;implemented it&lt;&#x2F;a&gt;. The only issue is that I use fish shell. But we live in a world where there are many ways to interact with the shell, so it follows that you can translate zsh syntax to fish syntax.&lt;&#x2F;p&gt;
&lt;p&gt;For the original snippet in zsh, translated as fish:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;fish&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;function&lt;&#x2F;span&gt;&lt;span&gt; unlock_bw_if_locked&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; test&lt;&#x2F;span&gt;&lt;span&gt; -z&lt;&#x2F;span&gt;&lt;span&gt; BW_SESSION&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;        echo&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bw locked - unlocking into a new session&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;        export&lt;&#x2F;span&gt;&lt;span&gt; BW_SESSION=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-meta z-embedded&quot;&gt;$(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;bw&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-meta z-embedded&quot;&gt; unlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-meta z-embedded&quot;&gt; --raw&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-meta z-embedded&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;function&lt;&#x2F;span&gt;&lt;span&gt; load_github&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;  unlock_bw_if_locked&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;  set&lt;&#x2F;span&gt;&lt;span&gt; -l&lt;&#x2F;span&gt;&lt;span&gt; github_pat_id &lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;BITWARDEN_GIST_ID&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;  set&lt;&#x2F;span&gt;&lt;span&gt; -l&lt;&#x2F;span&gt;&lt;span&gt; github_token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;  set&lt;&#x2F;span&gt;&lt;span&gt; -l&lt;&#x2F;span&gt;&lt;span&gt; github_token &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-meta z-embedded&quot;&gt;$(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;bw&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-meta z-embedded&quot;&gt; get notes &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;github_pat_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-meta z-embedded&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;  export&lt;&#x2F;span&gt;&lt;span&gt; GITHUB_OAUTH_TOKEN=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;github_token&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;  export&lt;&#x2F;span&gt;&lt;span&gt; GITHUB_TOKEN=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;github_token&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;  export&lt;&#x2F;span&gt;&lt;span&gt; GIT_TOKEN=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;github_token&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</description>
      </item>
      <item>
          <title>Cloudflare DNS management with Terraform</title>
          <pubDate>Sun, 20 Nov 2022 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2022/11/cloudflare-dns-management-with-terraform/</link>
          <guid>https://karnwong.me/posts/2022/11/cloudflare-dns-management-with-terraform/</guid>
          <description xml:base="https://karnwong.me/posts/2022/11/cloudflare-dns-management-with-terraform/">&lt;p&gt;I self hosted a lot of services, sometimes I try out a few apps that would get deleted within the same day. All this requires setting up CNAME for reverse-proxy (because I want to make sure there&#x27;s no funny reverse-proxy shenanigans going on, for future reference).&lt;&#x2F;p&gt;
&lt;p&gt;I can always log into Cloudflare console and manually add CNAME entries, but this is getting too tiresome since all I really need is another CNAME with the same config as the rest of the CNAMEs - pointing to the same DNS for my homelab. Cue lightbulb moment when I realize I can use Terraform to set it up.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s as simple as:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;terraform&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;locals&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  selfhosted_proxied&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; toset&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;service_a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;service_b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;service_c&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  selfhosted_non_proxied&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; toset&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;locals&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  proxied_dict&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;     =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt; name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-word&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt; local&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;selfhosted_proxied&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt; name&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  non_proxied_dict&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt; name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-word&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt; local&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;selfhosted_non_proxied&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt; name&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  selfhosted_dns&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;   =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; merge&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;local&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;proxied_dict&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt; local&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;non_proxied_dict&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;cloudflare_record&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;selfhosted_dns&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  for_each&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt; local&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;selfhosted_dns&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;     =&lt;&#x2F;span&gt;&lt;span&gt; each&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  proxied&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span&gt; each&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;value&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  ttl&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;     =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;CNAME&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;    =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;ddns&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  zone_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;zone_id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Told you it was really easy 😎.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Deploy more efficiently with templating</title>
          <pubDate>Sat, 05 Nov 2022 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2022/11/deploy-more-efficiently-with-templating/</link>
          <guid>https://karnwong.me/posts/2022/11/deploy-more-efficiently-with-templating/</guid>
          <description xml:base="https://karnwong.me/posts/2022/11/deploy-more-efficiently-with-templating/">&lt;p&gt;You are building a website, it&#x27;s a simple frontend that needs to call the database for [total lead drops this week]. Your website is still at an infancy stage, with only a few features. At this point, you contemplate whether you need a proper backend or not. But to deploy a backend properly, it would involve docker, backend database, persistence storage, DNS, load balancer, among other things. But it looks like you don&#x27;t have enough time, so you decide to go with serverless, since it takes less time to implement and you don&#x27;t have to worry about scaling.&lt;&#x2F;p&gt;
&lt;p&gt;So you go about creating a serverless function to fetch the information from the database. But the frontend can&#x27;t call the function directly, so you have to expose the function through an api gateway, so frontend can talk to it. You are happy with the current setup, since it relives you a lot of maintenance effort of creating a proper backend.&lt;&#x2F;p&gt;
&lt;p&gt;But your business is still trying to find its footing, so you had an idea of tweaking the query every so often. Then you are getting more annoyed at the fact that, every time you have to update the query, you have to go to the cloud console and manually update the query in your serverless app. You feel like there should be an easier way of just updating a few lines of code. You came upon a black magic called CI&#x2F;CD. You tinkered with it a bit, then you smiled because this means you don&#x27;t ever have to log in the cloud console ever again as long as you hook up the CI&#x2F;CD to your serverless code properly.&lt;&#x2F;p&gt;
&lt;p&gt;A few weeks went on, you couldn&#x27;t be happier. Then you had an idea for a few more features, but at this point you still are not ready for deploying a proper backend yet, so you have to create a few serverless functions for each feature. Suddenly you froze, having realized that you forgot how you setup the first serverless function, not to mention how to connect it to api gateway, and hook it up to CI&#x2F;CD. Sweats tricking down your forehead, bracing for the eternal doom of doing everything by hand manually every time you update the code.&lt;&#x2F;p&gt;
&lt;p&gt;Luckily it&#x27;s 2022, and the devops tooling space improved significantly compared to the dark ages of VMware. Apparently smart peoples utilize a certain form of template to spin up serverless functions, since it&#x27;s been dawned on them that most of the configuration differences are your code, not the infrastructure setup.&lt;&#x2F;p&gt;
&lt;p&gt;So basically if you wish to create a serverless api to interface with via frontend, this magical template would:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Create a serverless function&lt;&#x2F;li&gt;
&lt;li&gt;Inject your code into the function&lt;&#x2F;li&gt;
&lt;li&gt;Hook up the function with api gateway&lt;&#x2F;li&gt;
&lt;li&gt;Also sprinkle a magic CI&#x2F;CD hook so the whole flow would be triggered again from start to finish after a git push&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Most leading IaC tools have this feature, but what if you are not familiar with HashiCorp configuration language? Then you might find such tools with normal programming languagae interface more familiar, in which Pulumi is a contender in this space. HashiCorp also recently released CDK to accomplish the same thing if you want to give it a go as well. But for a start, you could check out &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.pulumi.com&#x2F;challenge&#x2F;deployments&#x2F;&quot;&gt;Pulumi&#x27;s Deployments Mini-Challenge&lt;&#x2F;a&gt; to try out deploying a serverless function with templating and CI&#x2F;CD. For Terraform CDK, check out &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cdktf&#x2F;cdktf-integration-serverless-example&quot;&gt;this repo&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>IaC is cool, until someone specified the wrong machine size 💸</title>
          <pubDate>Thu, 03 Nov 2022 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2022/11/iac-is-cool-until-someone-specified-the-wrong-machine-size/</link>
          <guid>https://karnwong.me/posts/2022/11/iac-is-cool-until-someone-specified-the-wrong-machine-size/</guid>
          <description xml:base="https://karnwong.me/posts/2022/11/iac-is-cool-until-someone-specified-the-wrong-machine-size/">&lt;p&gt;Back in the day, there was no cloud. If you want a lot of computing power, you need to build your own data center, and this is very expensive. Then cloud happened, and suddenly you can work with a lot of flexibility like you couldn&#x27;t before. Want to try out a small deployment? Sure! If your workload is heavier you can always increase the VM specs.&lt;&#x2F;p&gt;
&lt;p&gt;It would almost be the end of the story, until someone realize &quot;oh my God how did I set up VPC peering with another VPC, and which route table did I choose? I need to replicate it with another client and I forgot how&quot;. THe issue isn&#x27;t that working with the cloud&#x27;s web ui doesn&#x27;t work, rather it doesn&#x27;t leave a trail for you, so over time the knowledge of how things were set up are lost, gone forever. I&#x27;m sure you can always mitigate this by documenting things, but then it can happen that someone modified the infrastructure &lt;em&gt;without&lt;&#x2F;em&gt; updating the documentation. Can&#x27;t blame them, it&#x27;s only normal when you have to synchronize things manually.&lt;&#x2F;p&gt;
&lt;p&gt;So people came up with IaC - infrastructure as code. Basically this means, you write declarative blocks of what a resource&#x27;s configuration should be, and how it&#x27;s connected to another resources. Then you &quot;apply&quot; the configuration on your cloud provider. If you are researching or want to get something up and running fast, I wouldn&#x27;t suggest you use IaC. But if you have to modify the configuration, you might find it easier to maintain in the long run, plus you can always use &lt;code&gt;git diff&lt;&#x2F;code&gt; to show the changes between each commit.&lt;&#x2F;p&gt;
&lt;p&gt;And as how most things work, this certainly is not the end, because what if you have to create a new VM fleet, a small cluster for a research project. IaC can do this, but what if you were working late at night and you copied the wrong instance size into your IaC config - what could be 50 USD&#x2F;month small cluster could turn out to be a 2000 USD &#x2F; month large cluster, and it won&#x27;t even be utilized that much because your research workload is very light 💸💸💸💸💸.&lt;&#x2F;p&gt;
&lt;p&gt;Luckily humans excel at adaptation, so we came up with &quot;IaC policy&quot;, where you can define a set of constraints that your resources should comply to. This could be anything from &quot;only instance smaller than $x is allowed&quot;, or &quot;total monthly cost most not exceed $y&quot;. It can also be &quot;maximum storage allowed is 500GB&quot;, or even &quot;daily backup is required for $z resource&quot;. The world is not that gloomy, a lot of people made sure of that 🚀.&lt;&#x2F;p&gt;
&lt;p&gt;And I know you are eager to get your hands on at policy as code thing, so head to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.pulumi.com&#x2F;challenge&#x2F;one-quickstart&#x2F;&quot;&gt;a pulumi challenge&lt;&#x2F;a&gt; and take a stab at it!&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Deploy static site with branch preview via Cloudflare Pages</title>
          <pubDate>Wed, 05 Oct 2022 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2022/10/deploy-static-site-with-branch-preview-via-cloudflare-pages/</link>
          <guid>https://karnwong.me/posts/2022/10/deploy-static-site-with-branch-preview-via-cloudflare-pages/</guid>
          <description xml:base="https://karnwong.me/posts/2022/10/deploy-static-site-with-branch-preview-via-cloudflare-pages/">&lt;p&gt;&lt;strong&gt;Updated 2023-02-20&lt;&#x2F;strong&gt;: update terraform code&lt;&#x2F;p&gt;
&lt;p&gt;For frontends, if no server-side rendering is required, we can deploy it as a static site. If you already use GitHub, you might be familiar with GitHub Pages. One common use case is to deploy your personal landing page &#x2F; blog via GitHub Actions.&lt;&#x2F;p&gt;
&lt;p&gt;Interestingly enough, this might cause problems if you are working in a team. For example, if you are working on a UI change, and you need to have someone else approve the changes, they would need to build the site locally to do so.&lt;&#x2F;p&gt;
&lt;p&gt;Luckily, &quot;branch preview&quot; feature exists. Essentially it&#x27;s a mechanism to generate a preview site for every pull request. We are going to use Cloudflare Pages for this (alternatives are Vercel, etc.)&lt;&#x2F;p&gt;
&lt;p&gt;You should have a github repo with the source code for your site. Then,&lt;&#x2F;p&gt;
&lt;h2 id=&quot;terraform&quot;&gt;Terraform&lt;a class=&quot;zola-anchor&quot; href=&quot;#terraform&quot; aria-label=&quot;Anchor link for: terraform&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;hcl&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;cloudflare_pages_project&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;this&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  account_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;        =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;account_id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;              =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;project_name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  production_branch&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;production_branch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  lifecycle&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    ignore_changes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;deployment_configs&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt; source&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;cloudflare_record&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;this&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  depends_on&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;cloudflare_pages_project&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;    =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;subdomain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  proxied&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  ttl&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;     =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;    =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;CNAME&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;   =&lt;&#x2F;span&gt;&lt;span&gt; cloudflare_pages_project&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;this&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;subdomain&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  zone_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;zone_id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;cloudflare_pages_domain&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;this&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  depends_on&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;cloudflare_record&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  account_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;   =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;account_id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  project_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;project_name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  domain&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;       =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;domain_name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;del&gt;Notice that &lt;code&gt;cloudflare_pages_domain&lt;&#x2F;code&gt; is commented out, this is because it has a bug that would throw &quot;error creating domain&quot;. Although behind the scenes it creates a subdomain successfully (and is actually working with cloudflare pages).&lt;&#x2F;del&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;github-actions&quot;&gt;GitHub Actions&lt;a class=&quot;zola-anchor&quot; href=&quot;#github-actions&quot; aria-label=&quot;Anchor link for: github-actions&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;We are going to use github actions as a runner to build and deploy the site.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; D&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eploy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;on&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  p&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ush&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  w&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;orkflow_dispatch&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;c&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;oncurrency&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  g&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;roup&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;nvironment-${{ github.ref }}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  c&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ancel-in-progress&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nv&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  P&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ROJECT_NAME&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; P&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ROJECT_NAME&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; CHANGE ME&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  B&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;UILD_DIR&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; B&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;UILD_DIR&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; CHANGE ME&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;j&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;obs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  p&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ublish&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    r&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;uns-on&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;buntu-latest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    p&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ermissions&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      c&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ontents&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ead&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;      d&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;eployments&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; w&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;rite&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; P&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ublish to Cloudflare Pages&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;teps&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;      -&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; C&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;heckout&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;        u&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ses&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ctions&#x2F;checkout@v3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;      #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ---------- build ----------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;      -&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; S&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;etup node&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;        u&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ses&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ctions&#x2F;setup-node@v3.5.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;        w&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ith&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;          n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ode-version&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;18&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;          c&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ache&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;yarn&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;      -&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; I&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;nstall requirements&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;        r&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;un&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;arn install&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;      -&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; B&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;uild&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;        r&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;un&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;arn run build&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;      #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ---------- publish ----------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;      -&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; D&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eploy to Cloudflare Pages&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;        u&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ses&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;loudflare&#x2F;wrangler-action@v3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;        w&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ith&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;          a&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;piToken&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; $&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;{{ secrets.CLOUDFLARE_API_TOKEN }}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;          a&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ccountId&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; $&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;{{ secrets.CLOUDFLARE_ACCOUNT_ID }}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;          c&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ommand&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ages deploy ${{ env.BUILD_DIR }} --project-name=${{ env.PROJECT_NAME }}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Notice the &quot;build&quot; section, you can adjust this per your site&#x27;s setup.&lt;&#x2F;p&gt;
&lt;p&gt;This actions would work for both a push to master and a pull request&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2022&#x2F;10&#x2F;deploy-static-site-with-branch-preview-via-cloudflare-pages&#x2F;images&#x2F;2022-10-05-02-40-24.webp&quot; alt=&quot;cloudflare pages branch preview&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Terraform with ECS task on EC2 backend</title>
          <pubDate>Tue, 04 Oct 2022 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2022/10/terraform-with-ecs-task-on-ec2-backend/</link>
          <guid>https://karnwong.me/posts/2022/10/terraform-with-ecs-task-on-ec2-backend/</guid>
          <description xml:base="https://karnwong.me/posts/2022/10/terraform-with-ecs-task-on-ec2-backend/">&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2022&#x2F;10&#x2F;terraform-with-ecs-task-on-ec2-backend&#x2F;posts&#x2F;2022&#x2F;08&#x2F;minimal-ecs-task-with-fargate-backend&quot;&gt;Previously&lt;&#x2F;a&gt; I wrote about setting up ECS task on fargate backend. But we can also use EC2 as backend too, in some cases where the workload is consistent, ie scaling is not required, since EC2 would be cheaper than fargate backend, even more so if you have reserved instance on top. There&#x27;s a few modifications from the fargate version to make it work with EC2 backend, if you are curious you can try to hunt those down 😎. Repo &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kahnwong&#x2F;terraform-aws-ecs-ec2-example&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;task-definition&quot;&gt;Task definition&lt;a class=&quot;zola-anchor&quot; href=&quot;#task-definition&quot; aria-label=&quot;Anchor link for: task-definition&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;hcl&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;tfsec:ignore:aws-cloudwatch-log-group-customer-key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_cloudwatch_log_group&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;this&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  retention_in_days&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 14&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;              =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;aws&#x2F;ecs&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;service_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_ecs_task_definition&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;this&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  family&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;             =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;service_name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  cpu&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;                =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;cpu&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;             =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;memory&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  execution_role_arn&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;task_role&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  task_role_arn&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;task_role&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  container_definitions&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; jsonencode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;        name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;        =&lt;&#x2F;span&gt;&lt;span&gt; var.service_name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;        image&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;       =&lt;&#x2F;span&gt;&lt;span&gt; var.image_uri&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;        essential&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;   =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;        environment&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; []&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;        portMappings&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;            protocol&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;tcp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;            containerPort&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 80&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;            hostPort&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 80&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;        logConfiguration&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;          logDriver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;awslogs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;          options&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;            awslogs-group&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;         =&lt;&#x2F;span&gt;&lt;span&gt; aws_cloudwatch_log_group.this.name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;            awslogs-region&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;        =&lt;&#x2F;span&gt;&lt;span&gt; var.aws_region&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;            awslogs-stream-prefix&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ecs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_ecs_service&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;this&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;            =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;service_name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  cluster&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;         =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;ecs_cluster_id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  task_definition&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; aws_ecs_task_definition&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;this&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;arn&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  desired_count&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;   =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; https:&#x2F;&#x2F;github.com&#x2F;hashicorp&#x2F;terraform&#x2F;issues&#x2F;26950&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  depends_on&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;aws_lb&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt; aws_alb_target_group&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  ordered_placement_strategy&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;spread&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    field&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;instanceId&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  load_balancer&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    target_group_arn&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; aws_alb_target_group&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;this&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;arn&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    container_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;   =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;service_name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    container_port&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;   =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 80&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;ssl-certificate&quot;&gt;SSL certificate&lt;a class=&quot;zola-anchor&quot; href=&quot;#ssl-certificate&quot; aria-label=&quot;Anchor link for: ssl-certificate&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;hcl&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_acm_certificate&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;this&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  domain_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;       =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;domain_name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  validation_method&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;DNS&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  lifecycle&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    create_before_destroy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  tags&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    Name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; var.domain_name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;load-balancer&quot;&gt;Load balancer&lt;a class=&quot;zola-anchor&quot; href=&quot;#load-balancer&quot; aria-label=&quot;Anchor link for: load-balancer&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;hcl&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;tfsec:ignore:aws-elb-alb-not-public&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;tfsec:ignore:aws-elb-drop-invalid-headers&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_lb&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;this&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;               =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;service_name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;           =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  load_balancer_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;application&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  security_groups&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;    =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;alb_id&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  subnets&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;            =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;subnet_id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_alb_target_group&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;this&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;        =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;service_name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  port&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;        =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 80&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  protocol&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;    =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;HTTP&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  vpc_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;vpc_id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  target_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;instance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  health_check&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    port&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;    =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;traffic-port&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;    =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;health_check_path&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    matcher&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;200-499&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;tfsec:ignore:aws-elb-http-not-used&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_alb_listener&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;http&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  load_balancer_arn&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; aws_lb&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;this&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  port&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;              =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 80&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  protocol&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;          =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;HTTP&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  default_action&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;redirect&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;    redirect&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;      port&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;        =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;443&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;      protocol&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;    =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;HTTPS&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;      status_code&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;HTTP_301&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;tfsec:ignore:aws-elb-use-secure-tls-policy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_alb_listener&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;https&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  load_balancer_arn&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; aws_lb&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;this&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  port&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;              =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 443&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  protocol&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;          =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;HTTPS&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  ssl_policy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ELBSecurityPolicy-2016-08&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  certificate_arn&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; aws_acm_certificate&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;this&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;arn&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  default_action&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;             =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;forward&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    target_group_arn&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; aws_alb_target_group&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;this&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</description>
      </item>
      <item>
          <title>Intro to Dagster Cloud</title>
          <pubDate>Tue, 27 Sep 2022 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2022/09/intro-to-dagster-cloud/</link>
          <guid>https://karnwong.me/posts/2022/09/intro-to-dagster-cloud/</guid>
          <description xml:base="https://karnwong.me/posts/2022/09/intro-to-dagster-cloud/">&lt;p&gt;Imagine you have a few data pipelines to schedule. Simplest solution would be cronjob. Time goes by and next thing you know, you have around 50 pipelines to manage. The fun starts when you have to hunt down which pipeline doesn&#x27;t run normally. And by then it would be super hard to do tracing if you haven&#x27;t set up logging and monitoring.&lt;&#x2F;p&gt;
&lt;p&gt;Luckily there are tools we can use to improve the situation. Task orchestrators are born exactly for this, to schedule and monitor pipelines. These days there are more bells and whistles, such as backfilling and sensor triggers. Some also integrate with data catalog tools and provide table specs and data lineage.&lt;&#x2F;p&gt;
&lt;p&gt;Sounds familiar? If you have been looking into Airflow, this is exactly what it does. But there are other alternatives too, and in this post we&#x27;re going to find out what Dagster Cloud can do. (Spoiler: yay CI&#x2F;CD).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;dagster-architecture&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.dagster.io&#x2F;deployment&#x2F;overview&quot;&gt;Dagster architecture&lt;&#x2F;a&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#dagster-architecture&quot; aria-label=&quot;Anchor link for: dagster-architecture&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2022&#x2F;09&#x2F;intro-to-dagster-cloud&#x2F;images&#x2F;2022-09-27-19-27-01.webp&quot; alt=&quot;dagster architecture&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is how dagster work. But to set all this up yourself, you need to at least:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Package each dagster repository into its own image&lt;&#x2F;li&gt;
&lt;li&gt;Setup dagit container for UI&lt;&#x2F;li&gt;
&lt;li&gt;Set up dagster daemon instance to trigger tasks&lt;&#x2F;li&gt;
&lt;li&gt;Set up postgres for dagster metastore&lt;&#x2F;li&gt;
&lt;li&gt;Set I&#x2F;O manager to use blob storage&lt;&#x2F;li&gt;
&lt;li&gt;Set up default executors and concurrent run limits&lt;&#x2F;li&gt;
&lt;li&gt;CI&#x2F;CD to update code and base dagster image&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;And if you have multiple users, you need to set up the auth yourself too.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;enter-dagster-cloud&quot;&gt;Enter Dagster Cloud&lt;a class=&quot;zola-anchor&quot; href=&quot;#enter-dagster-cloud&quot; aria-label=&quot;Anchor link for: enter-dagster-cloud&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;But folks at Dagster know people are finding it very tricky to set it up, so they provide a few cloud offerings, one of which is serverless. This essentially means you only need to supply the code and set up CI&#x2F;CD, and Dagster would provide a VM to run your tasks.&lt;&#x2F;p&gt;
&lt;p&gt;To test it out, you can &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dagster.cloud&#x2F;signup&quot;&gt;sign up on Dagster Cloud&lt;&#x2F;a&gt; and follow instructions &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.dagster.io&#x2F;dagster-cloud&#x2F;getting-started&#x2F;getting-started-with-serverless-deployment&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cool-dagster-features&quot;&gt;Cool dagster features&lt;a class=&quot;zola-anchor&quot; href=&quot;#cool-dagster-features&quot; aria-label=&quot;Anchor link for: cool-dagster-features&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;branch-preview&quot;&gt;Branch preview&lt;a class=&quot;zola-anchor&quot; href=&quot;#branch-preview&quot; aria-label=&quot;Anchor link for: branch-preview&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Frontend usually set up CI&#x2F;CD to return a preview of a PR, now you can do the same with dagster!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2022&#x2F;09&#x2F;intro-to-dagster-cloud&#x2F;images&#x2F;2022-09-27-19-35-47.webp&quot; alt=&quot;dagster pr branch deployment&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This means your team can preview what the DAG would look like, or give it a spin before deploying to prod 🚀.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;multiple-teams-you-say&quot;&gt;Multiple teams you say?&lt;a class=&quot;zola-anchor&quot; href=&quot;#multiple-teams-you-say&quot; aria-label=&quot;Anchor link for: multiple-teams-you-say&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Imagine working in an organization with many teams. Some teams might use dbt, another might use spark. Sometimes each team has different virtual environment. Even if you can use the same setup for multiple teams, over time the number of pipelines would grow significantly, which means it&#x27;s harder to manage. But we can set up a dagster repo for each team, then link them together via Dagster Cloud for a single control plane.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2022&#x2F;09&#x2F;intro-to-dagster-cloud&#x2F;images&#x2F;2022-09-27-19-41-55.webp&quot; alt=&quot;dagster workspace&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Notice each code location has attached git hash. Yay tracing!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;table-lineage&quot;&gt;Table lineage&lt;a class=&quot;zola-anchor&quot; href=&quot;#table-lineage&quot; aria-label=&quot;Anchor link for: table-lineage&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Running multiple pipelines are cool. But if you update this pipeline, do you also need to update downstream pipelines? I&#x27;m sure you can have a list of pipelines dependency somewhere, but it&#x27;s so much more convenient to see it right from dagster.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2022&#x2F;09&#x2F;intro-to-dagster-cloud&#x2F;images&#x2F;2022-09-27-19-45-20.webp&quot; alt=&quot;dagster table lineage&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Notice the &lt;code&gt;Materialize&lt;&#x2F;code&gt; button on top right. This means you can trigger run on an upstream table, and it would automatically update downstream tables.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Dagster has more features, don&#x27;t forget to check out their &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.dagster.io&#x2F;&quot;&gt;docs&lt;&#x2F;a&gt; (it&#x27;s well written)!&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Intro to Pulumi</title>
          <pubDate>Mon, 26 Sep 2022 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2022/09/intro-to-pulumi/</link>
          <guid>https://karnwong.me/posts/2022/09/intro-to-pulumi/</guid>
          <description xml:base="https://karnwong.me/posts/2022/09/intro-to-pulumi/">&lt;p&gt;For IaC, no doubt that Terraform is the leader. But there are other alternatives too, one of them is Pulumi. Currently Pulumi provides fun challenges to get started with their services. Best of all, they give you swags too! We are going to create a simple Pulumi project for hosting a static site through Cloudfront CDN.&lt;&#x2F;p&gt;
&lt;p&gt;Challenge url: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.pulumi.com&#x2F;challenge&#x2F;startup-in-a-box&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.pulumi.com&#x2F;challenge&#x2F;startup-in-a-box&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;pre-requisites&quot;&gt;Pre-requisites&lt;a class=&quot;zola-anchor&quot; href=&quot;#pre-requisites&quot; aria-label=&quot;Anchor link for: pre-requisites&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;app.pulumi.com&#x2F;signup&quot;&gt;Pulumi&lt;&#x2F;a&gt; account&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.checklyhq.com&#x2F;&quot;&gt;Checkly&lt;&#x2F;a&gt; account&lt;&#x2F;li&gt;
&lt;li&gt;AWS account&lt;&#x2F;li&gt;
&lt;li&gt;Install Pulumi cli: &lt;code&gt;brew install pulumi&#x2F;tap&#x2F;pulumi&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;steps&quot;&gt;Steps&lt;a class=&quot;zola-anchor&quot; href=&quot;#steps&quot; aria-label=&quot;Anchor link for: steps&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;init&quot;&gt;Init&lt;a class=&quot;zola-anchor&quot; href=&quot;#init&quot; aria-label=&quot;Anchor link for: init&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Init pulumi project&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;mkdir&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; pulumi-challenge-startup-in-a-box&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pulumi&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; new&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; aws-typescript&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;create-s3-bucket&quot;&gt;Create S3 bucket&lt;a class=&quot;zola-anchor&quot; href=&quot;#create-s3-bucket&quot; aria-label=&quot;Anchor link for: create-s3-bucket&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Then we are going to create an s3 bucket to host static website, your &lt;code&gt;index.ts&lt;&#x2F;code&gt; should look like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-import-export-all z-ts z-constant&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-as z-ts z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-alias z-ts z-variable z-other z-readwrite&quot;&gt; pulumi&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;@pulumi&#x2F;pulumi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-import-export-all z-ts z-constant&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-as z-ts z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-alias z-ts z-variable z-other z-readwrite&quot;&gt; aws&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;@pulumi&#x2F;aws&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-import-export-all z-ts z-constant&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-as z-ts z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-alias z-ts z-variable z-other z-readwrite&quot;&gt; awsx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;@pulumi&#x2F;awsx&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-ts z-variable z-other z-constant&quot;&gt; bucket&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-new z-ts z-keyword z-operator z-new&quot;&gt; new&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt; aws&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-object&quot;&gt;s3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;BucketV2&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bucketV2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;  tags&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;    Name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;pulumi-challenge-karn-wong&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;  }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-ts z-variable z-other z-constant&quot;&gt; bucketAcl&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-new z-ts z-keyword z-operator z-new&quot;&gt; new&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt; aws&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-object&quot;&gt;s3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;BucketAclV2&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bAcl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;  bucket&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt; bucket&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;  acl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt; aws&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-object&quot;&gt;s3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;PublicReadAcl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;set-mime-type&quot;&gt;Set MIME type&lt;a class=&quot;zola-anchor&quot; href=&quot;#set-mime-type&quot; aria-label=&quot;Anchor link for: set-mime-type&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;To set MIME type, we could leverage Node API:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;npm&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; install&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; mime&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; @types&#x2F;mime&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then append this to &lt;code&gt;index.ts&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-import-export-all z-ts z-constant&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-as z-ts z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-alias z-ts z-variable z-other z-readwrite&quot;&gt; fs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;fs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-import-export-all z-ts z-constant&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-as z-ts z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-alias z-ts z-variable z-other z-readwrite&quot;&gt; mime&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;mime&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-ts z-variable z-other z-constant&quot;&gt; staticWebsiteDirectory&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;website&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt;fs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;readdirSync&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-ts z-variable z-other z-readwrite&quot;&gt;staticWebsiteDirectory&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;forEach&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;file&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;  const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-ts z-variable z-other z-constant&quot;&gt; filePath&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; `&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-punctuation z-definition z-template-expression z-begin&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-ts z-variable z-other z-readwrite&quot;&gt;staticWebsiteDirectory&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-punctuation z-definition z-template-expression z-end&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-punctuation z-definition z-template-expression z-begin&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-ts z-variable z-other z-readwrite&quot;&gt;file&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-punctuation z-definition z-template-expression z-end&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;  const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-ts z-variable z-other z-constant&quot;&gt; fileContent&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt; fs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;readFileSync&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-ts z-variable z-other z-readwrite&quot;&gt;filePath&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;toString&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-new z-ts z-keyword z-operator z-new&quot;&gt;  new&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt; aws&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-object&quot;&gt;s3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;BucketObject&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-ts z-variable z-other z-readwrite&quot;&gt;file&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;    bucket&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt; bucket&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;    source&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-new z-ts z-keyword z-operator z-new&quot;&gt; new&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt; pulumi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-object&quot;&gt;asset&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;FileAsset&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-ts z-variable z-other z-readwrite&quot;&gt;filePath&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;    contentType&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt; mime&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;getType&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-ts z-variable z-other z-readwrite&quot;&gt;filePath&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-logical&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; undefined&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;    acl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt; aws&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-object&quot;&gt;s3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;PublicReadAcl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;  }&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;create-static-assets&quot;&gt;Create static assets&lt;a class=&quot;zola-anchor&quot; href=&quot;#create-static-assets&quot; aria-label=&quot;Anchor link for: create-static-assets&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;But we are going to serve a static website, so we need to provide static assets:&lt;&#x2F;p&gt;
&lt;h4 id=&quot;website-index-html&quot;&gt;&lt;code&gt;website&#x2F;index.html&lt;&#x2F;code&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#website-index-html&quot; aria-label=&quot;Anchor link for: website-index-html&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;html&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;lt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;doctype&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; html&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;html&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;  &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;head&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;meta&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; charset&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag z-punctuation z-separator z-key-value&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;utf-8&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt; &#x2F;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;Pulumi Challenge&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;link&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; rel&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag z-punctuation z-separator z-key-value&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;stylesheet&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; href&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag z-punctuation z-separator z-key-value&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;style.css&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt; &#x2F;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;link&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; rel&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag z-punctuation z-separator z-key-value&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;stylesheet&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; href&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag z-punctuation z-separator z-key-value&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;normalize.css&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt; &#x2F;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;  &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;head&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;  &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;body&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;header&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;      &amp;lt;!--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The logo here is pulled from FontAwesome. Replace it with your own if you like! &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;      &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;div&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; class&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag z-punctuation z-separator z-key-value&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;logo&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;        &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ul&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;          &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;li&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; class&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag z-punctuation z-separator z-key-value&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;fas fa-feather&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;li&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;          &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;li&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;Company Name&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;li&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;        &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ul&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;      &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;div&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;      &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ul&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; class&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag z-punctuation z-separator z-key-value&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;social&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;        &amp;lt;!--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Add your GitHub and social links here! &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;        &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;li&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;          &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; href&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag z-punctuation z-separator z-key-value&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;http:&#x2F;&#x2F;github.com&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; target&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag z-punctuation z-separator z-key-value&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_blank&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;            &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; class&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag z-punctuation z-separator z-key-value&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;fab fa-github-alt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;i&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;          &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;        &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;li&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;        &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;li&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;          &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; href&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag z-punctuation z-separator z-key-value&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;http:&#x2F;&#x2F;twitter.com&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; target&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag z-punctuation z-separator z-key-value&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_blank&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;            &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; class&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag z-punctuation z-separator z-key-value&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;fab fa-twitter&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;i&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;          &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;        &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;li&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;        &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;li&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;          &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; href&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag z-punctuation z-separator z-key-value&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;http:&#x2F;&#x2F;linkedin.com&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; target&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag z-punctuation z-separator z-key-value&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_blank&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;            &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; class&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag z-punctuation z-separator z-key-value&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;fab fa-linkedin-in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;i&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;          &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;        &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;li&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;      &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ul&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;    &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;header&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;div&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; class&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag z-punctuation z-separator z-key-value&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;banner&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;      &amp;lt;!--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Fill in the blanks for your startup&amp;#39;s pitch! &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;      &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;h1&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;Your Startup Name Here&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;h1&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;      &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;h3&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;Your Tagline&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;h3&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;      &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        We&amp;#39;re $CompanyName, and we&amp;#39;re changing what it means to $Task. Our&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        innovative use of $Technology makes life easier for $JobTitles, so they&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        can focus on what they&amp;#39;re really good at instead of wasting time and&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        effort on $MenialOrDifficultTask. Streamline your $TaskProcess with&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        $Product and take to the skies!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;      &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;    &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;div&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;  &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;body&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;  &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;script&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;    src&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag z-punctuation z-separator z-key-value&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;https:&#x2F;&#x2F;kit.fontawesome.com&#x2F;b4747495ea.js&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;    crossorigin&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag z-punctuation z-separator z-key-value&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;anonymous&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;  &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;script&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;html&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;website-style-css&quot;&gt;&lt;code&gt;website&#x2F;style.css&lt;&#x2F;code&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#website-style-css&quot; aria-label=&quot;Anchor link for: website-style-css&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;css&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; url&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;https:&#x2F;&#x2F;fonts.googleapis.com&#x2F;css?family=News+Cycle|Teko&amp;amp;display=swap&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;body&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  background-color&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-constant z-css z-punctuation z-definition z-constant&quot;&gt; #&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-color z-constant&quot;&gt;f7f7fa&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  opacity&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0.8&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  background-image&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; radial-gradient&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-constant z-css z-punctuation z-definition z-constant&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-color z-constant&quot;&gt;f79645&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0.5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;px&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-list z-comma z-css&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-constant z-css z-punctuation z-definition z-constant&quot;&gt; #&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-color z-constant&quot;&gt;f7f7fa&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0.5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;px&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  background-size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;px&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;px&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ul&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  list-style-type&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-constant z-property-value z-css&quot;&gt; none&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ul&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; li&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  display&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-constant z-property-value z-css&quot;&gt; inline-block&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;a&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  color&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-constant z-support z-constant z-color z-w3c-standard-color-name z-css&quot;&gt; white&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-support z-type z-vendored z-property-name z-css&quot;&gt;  -webkit-transition&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-constant z-property-value z-css&quot;&gt; color&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0.5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-constant z-property-value z-css&quot;&gt; ease-out&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  transition&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-constant z-property-value z-css&quot;&gt; color&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0.5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-constant z-property-value z-css&quot;&gt; ease-out&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  text-decoration&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-constant z-property-value z-css&quot;&gt; none&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name z-entity z-other z-attribute-name z-pseudo-class&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name z-entity z-other z-attribute-name z-pseudo-class&quot;&gt;hover&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-selector z-punctuation z-separator z-list z-comma z-css&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name z-entity z-other z-attribute-name z-pseudo-class&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name z-entity z-other z-attribute-name z-pseudo-class&quot;&gt;active&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  color&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; rgb&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;55&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-list z-comma z-css&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 188&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-list z-comma z-css&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 250&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;header&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  background-color&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; rgba&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;214&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-list z-comma z-css&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 73&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-list z-comma z-css&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 73&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-list z-comma z-css&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0.6&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  height&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 80&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;px&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  position&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-constant z-property-value z-css&quot;&gt; absolute&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  top&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  width&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 100&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;%&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  box-shadow&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;px&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;px&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;px&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; -1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;px&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; rgba&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-list z-comma z-css&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-list z-comma z-css&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-list z-comma z-css&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0.75&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-support z-type z-vendored z-property-name z-css&quot;&gt;  -webkit-box-shadow&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;px&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;px&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;px&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; -1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;px&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; rgba&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-list z-comma z-css&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-list z-comma z-css&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-list z-comma z-css&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0.75&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-support z-type z-vendored z-property-name z-css&quot;&gt;  -moz-box-shadow&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;px&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;px&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;px&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; -1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;px&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; rgba&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-list z-comma z-css&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-list z-comma z-css&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-list z-comma z-css&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0.75&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;header&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; li&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  color&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-constant z-support z-constant z-color z-w3c-standard-color-name z-css&quot;&gt; white&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name z-entity z-other z-attribute-name z-class z-css&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name z-entity z-other z-attribute-name z-class z-css&quot;&gt;active&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; a&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  color&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; rgb&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;255&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-list z-comma z-css&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 157&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-list z-comma z-css&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 112&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name z-entity z-other z-attribute-name z-class z-css&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name z-entity z-other z-attribute-name z-class z-css&quot;&gt;social&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  position&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-constant z-property-value z-css&quot;&gt; absolute&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  right&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 50&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;px&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  top&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; -5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;px&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  font-size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 30&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;px&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name z-entity z-other z-attribute-name z-class z-css&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name z-entity z-other z-attribute-name z-class z-css&quot;&gt;social&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; li&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  margin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;px&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;px&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name z-entity z-other z-attribute-name z-class z-css&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name z-entity z-other z-attribute-name z-class z-css&quot;&gt;logo&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  font-family&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Teko&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  position&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-constant z-property-value z-css&quot;&gt; absolute&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  left&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;px&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  top&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; -60&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;px&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  font-size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 40&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;px&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name z-entity z-other z-attribute-name z-class z-css&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name z-entity z-other z-attribute-name z-class z-css&quot;&gt;banner&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  width&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 60&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;vw&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  font-family&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Teko&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  font-size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;vw&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  text-align&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-constant z-property-value z-css&quot;&gt; center&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  margin-top&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;vw&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  margin-left&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-unit&quot;&gt;vw&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name z-entity z-other z-attribute-name z-class z-css&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name z-entity z-other z-attribute-name z-class z-css&quot;&gt;banner&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; h1&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  color&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; rgb&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;214&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-list z-comma z-css&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 73&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-list z-comma z-css&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 73&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name z-entity z-other z-attribute-name z-class z-css&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name z-entity z-other z-attribute-name z-class z-css&quot;&gt;banner&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-selector z-punctuation z-separator z-list z-comma z-css&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name z-entity z-other z-attribute-name z-class z-css&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name z-entity z-other z-attribute-name z-class z-css&quot;&gt;about&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; p&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;  font-family&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; News Cycle&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;website-normalize-css&quot;&gt;&lt;code&gt;website&#x2F;normalize.css&lt;&#x2F;code&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#website-normalize-css&quot; aria-label=&quot;Anchor link for: website-normalize-css&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h4&gt;
&lt;p&gt;Download from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;necolas&#x2F;normalize.css&#x2F;blob&#x2F;master&#x2F;normalize.css&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;necolas&#x2F;normalize.css&#x2F;blob&#x2F;master&#x2F;normalize.css&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;create-cloudfront-cdn&quot;&gt;Create Cloudfront CDN&lt;a class=&quot;zola-anchor&quot; href=&quot;#create-cloudfront-cdn&quot; aria-label=&quot;Anchor link for: create-cloudfront-cdn&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;We can always fetch the site via s3 directly, but your s3 bucket is in a single region. Users in far-away-regions might have a significant latency. To circumvent this, we could utilize CDN to reduce the site latency, since CDN would serve the content from a region nearest to users. To achieve this, append the following to &lt;code&gt;index.ts&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-ts z-variable z-other z-constant&quot;&gt; s3OriginId&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;myS3Origin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-ts z-variable z-other z-constant&quot;&gt; cloudfrontDistribution&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-new z-ts z-keyword z-operator z-new&quot;&gt; new&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt; aws&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-object&quot;&gt;cloudfront&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Distribution&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;s3Distribution&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;  {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;    origins&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-square z-ts z-meta z-brace z-square&quot;&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;      {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;        domainName&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt; bucket&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;bucketRegionalDomainName&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;        originId&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-ts z-variable z-other z-readwrite&quot;&gt; s3OriginId&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;      }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-brace z-square z-ts z-meta z-brace z-square&quot;&gt;    ]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;    enabled&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;    isIpv6Enabled&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;    comment&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Some comment&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;    defaultRootObject&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;index.html&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;    defaultCacheBehavior&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;      allowedMethods&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-square z-ts z-meta z-brace z-square&quot;&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;DELETE&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;GET&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;HEAD&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;OPTIONS&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;PATCH&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;POST&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;PUT&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-brace z-square z-ts z-meta z-brace z-square&quot;&gt;      ]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;      cachedMethods&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-square z-ts z-meta z-brace z-square&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;GET&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;HEAD&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-square z-ts z-meta z-brace z-square&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;      targetOriginId&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-ts z-variable z-other z-readwrite&quot;&gt; s3OriginId&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;      forwardedValues&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;        queryString&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;        cookies&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;          forward&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;none&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;      }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;      viewerProtocolPolicy&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;allow-all&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;      minTtl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;      defaultTtl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 3600&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;      maxTtl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 86400&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;    priceClass&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;PriceClass_200&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;    restrictions&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;      geoRestriction&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;        restrictionType&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;whitelist&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;        locations&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-square z-ts z-meta z-brace z-square&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;US&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;CA&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;GB&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;DE&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-square z-ts z-meta z-brace z-square&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;      }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;    viewerCertificate&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;      cloudfrontDefaultCertificate&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;  }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;reusable-module&quot;&gt;Reusable module&lt;a class=&quot;zola-anchor&quot; href=&quot;#reusable-module&quot; aria-label=&quot;Anchor link for: reusable-module&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Think of it as instead of creating resources manually all the time, you can call a function instead. Refactor away we go!&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Remove cloudfront block in &lt;code&gt;index.ts&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Create &lt;code&gt;cdn-website&#x2F;index.ts&lt;&#x2F;code&gt; with following content:&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-import-export-all z-ts z-constant&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-as z-ts z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-alias z-ts z-variable z-other z-readwrite&quot;&gt; pulumi&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;@pulumi&#x2F;pulumi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-import-export-all z-ts z-constant&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-as z-ts z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-alias z-ts z-variable z-other z-readwrite&quot;&gt; aws&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;@pulumi&#x2F;aws&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-import-export-all z-ts z-constant&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-as z-ts z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-alias z-ts z-variable z-other z-readwrite&quot;&gt; fs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;fs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-import-export-all z-ts z-constant&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-as z-ts z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-alias z-ts z-variable z-other z-readwrite&quot;&gt; mime&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;mime&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This is a simpler version of:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; https:&#x2F;&#x2F;github.com&#x2F;pulumi&#x2F;pulumi-aws-static-website&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;export&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; class&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-class&quot;&gt; CdnWebsite&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; extends&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-module z-ts z-entity z-name z-type z-module&quot;&gt; pulumi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-inherited-class&quot;&gt;ComponentResource&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;  private&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; bucket&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-module z-ts z-entity z-name z-type z-module&quot;&gt; aws&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-module z-ts z-entity z-name z-type z-module&quot;&gt;s3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;BucketV2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;  private&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; bucketAcl&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-module z-ts z-entity z-name z-type z-module&quot;&gt; aws&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-module z-ts z-entity z-name z-type z-module&quot;&gt;s3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;BucketAclV2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;  private&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; cloudfrontDistribution&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-module z-ts z-entity z-name z-type z-module&quot;&gt; aws&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-module z-ts z-entity z-name z-type z-module&quot;&gt;cloudfront&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Distribution&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;  private&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; s3OriginId&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-support z-type z-primitive z-ts&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;myS3Origin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;  private&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; staticWebsiteDirectory&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-support z-type z-primitive z-ts&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.&#x2F;website&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;  constructor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-support z-type z-primitive z-ts&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-parameter z-ts&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; args&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-support z-type z-primitive z-ts&quot;&gt; any&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-parameter z-ts&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; opts&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-optional&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-module z-ts z-entity z-name z-type z-module&quot;&gt; pulumi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;ComponentResourceOptions&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-language&quot;&gt;    super&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;pulumi:challenge:CdnWebsite&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-ts z-variable z-other z-readwrite&quot;&gt; name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-ts z-variable z-other z-readwrite&quot;&gt; args&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-ts z-variable z-other z-readwrite&quot;&gt; opts&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-language&quot;&gt;    this&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;bucket&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-new z-ts z-keyword z-operator z-new&quot;&gt; new&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt; aws&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-object&quot;&gt;s3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;BucketV2&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bucketV2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;      {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;        tags&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;          Name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;My bucket&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;      }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;      {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;        parent&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;      }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;    )&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-language&quot;&gt;    this&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;bucketAcl&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-new z-ts z-keyword z-operator z-new&quot;&gt; new&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt; aws&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-object&quot;&gt;s3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;BucketAclV2&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bAcl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;      {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;        bucket&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-object&quot;&gt;bucket&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;        acl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt; aws&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-object&quot;&gt;s3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;PublicReadAcl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;      }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;      {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;        parent&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;      }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;    )&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-language&quot;&gt;    this&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;cloudfrontDistribution&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-new z-ts z-keyword z-operator z-new&quot;&gt; new&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt; aws&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-object&quot;&gt;cloudfront&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Distribution&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;s3Distribution&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;      {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;        origins&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-square z-ts z-meta z-brace z-square&quot;&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;          {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;            domainName&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-object&quot;&gt;bucket&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;bucketRegionalDomainName&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;            originId&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;s3OriginId&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;          }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-brace z-square z-ts z-meta z-brace z-square&quot;&gt;        ]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;        enabled&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;        isIpv6Enabled&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;        comment&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Some comment&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;        defaultRootObject&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;index.html&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;        defaultCacheBehavior&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;          allowedMethods&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-square z-ts z-meta z-brace z-square&quot;&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;DELETE&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;GET&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;HEAD&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;OPTIONS&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;PATCH&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;POST&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;PUT&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-brace z-square z-ts z-meta z-brace z-square&quot;&gt;          ]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;          cachedMethods&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-square z-ts z-meta z-brace z-square&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;GET&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;HEAD&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-square z-ts z-meta z-brace z-square&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;          targetOriginId&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;s3OriginId&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;          forwardedValues&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;            queryString&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;            cookies&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;              forward&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;none&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;            }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;          }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;          viewerProtocolPolicy&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;allow-all&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;          minTtl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;          defaultTtl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 3600&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;          maxTtl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 86400&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;        priceClass&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;PriceClass_200&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;        restrictions&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;          geoRestriction&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;            restrictionType&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;whitelist&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;            locations&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-square z-ts z-meta z-brace z-square&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;US&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;CA&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;GB&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;DE&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-square z-ts z-meta z-brace z-square&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;          }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;        viewerCertificate&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;          cloudfrontDefaultCertificate&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;      }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;      {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;        parent&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;      }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;    )&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt;    fs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;readdirSync&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-language&quot;&gt;this&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;staticWebsiteDirectory&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;forEach&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;file&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;      const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-ts z-variable z-other z-constant&quot;&gt; filePath&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; `&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-punctuation z-definition z-template-expression z-begin&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-language&quot;&gt;this&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-meta z-embedded&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;staticWebsiteDirectory&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-punctuation z-definition z-template-expression z-end&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-punctuation z-definition z-template-expression z-begin&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-ts z-variable z-other z-readwrite&quot;&gt;file&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-punctuation z-definition z-template-expression z-end&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;      const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-ts z-variable z-other z-constant&quot;&gt; fileContent&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt; fs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;readFileSync&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-ts z-variable z-other z-readwrite&quot;&gt;filePath&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;toString&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-new z-ts z-keyword z-operator z-new&quot;&gt;      new&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt; aws&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-object&quot;&gt;s3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;BucketObject&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-ts z-variable z-other z-readwrite&quot;&gt;        file&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;          bucket&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-object&quot;&gt;bucket&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;          source&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-new z-ts z-keyword z-operator z-new&quot;&gt; new&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt; pulumi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-object&quot;&gt;asset&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;FileAsset&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-ts z-variable z-other z-readwrite&quot;&gt;filePath&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;          contentType&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt; mime&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;getType&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-ts z-variable z-other z-readwrite&quot;&gt;filePath&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-logical&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; undefined&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;          acl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt; aws&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-object&quot;&gt;s3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;PublicReadAcl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;          parent&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;bucket&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;      )&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; We also need to register all the expected outputs for this&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; component resource that will get returned by default.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-language&quot;&gt;    this&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;registerOutputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;      bucketName&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-object&quot;&gt;bucket&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;      cdnUrl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-object&quot;&gt;cloudfrontDistribution&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;domainName&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-property z-ts z-storage&quot;&gt;  get&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; url&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-module z-ts z-entity z-name z-type z-module&quot;&gt; pulumi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Output&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-typeparameters&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-support z-type z-primitive z-ts&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-typeparameters&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-language&quot;&gt; this&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-object&quot;&gt;cloudfrontDistribution&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;domainName&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;In&lt;code&gt;index.ts&lt;&#x2F;code&gt; modify the file so that it looks like this:&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Deploy Website to S3 with CloudFront&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Also shows the challenger how to build a ComponentResource&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-alias z-ts z-variable z-other z-readwrite&quot;&gt; CdnWebsite&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.&#x2F;cdn-website&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-ts z-variable z-other z-constant&quot;&gt; website&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-new z-ts z-keyword z-operator z-new&quot;&gt; new&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; CdnWebsite&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;your-startup&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;sanity-checks&quot;&gt;Sanity checks&lt;a class=&quot;zola-anchor&quot; href=&quot;#sanity-checks&quot; aria-label=&quot;Anchor link for: sanity-checks&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;If everything works correctly, we should be able to deploy the website. But it would be so much better if we can see whether the website is working normally or not. Status checks to the rescue!&lt;&#x2F;p&gt;
&lt;p&gt;Here we set up &lt;code&gt;checkly&lt;&#x2F;code&gt; provider:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;npm&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; install&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; @checkly&#x2F;pulumi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; API KEY: https:&#x2F;&#x2F;app.checklyhq.com&#x2F;settings&#x2F;account&#x2F;api-keys&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pulumi&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; config&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; set&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; checkly:apiKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-secret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; AccountID: https:&#x2F;&#x2F;app.checklyhq.com&#x2F;settings&#x2F;account&#x2F;general&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pulumi&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; config&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; set&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; checkly:accountId&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then append this to &lt;code&gt;index.ts&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;export&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-ts z-variable z-other z-constant&quot;&gt; websiteUrl&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt; website&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;url&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-import-export-all z-ts z-constant&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-as z-ts z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-alias z-ts z-variable z-other z-readwrite&quot;&gt; checkly&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;@checkly&#x2F;pulumi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-import-export-all z-ts z-constant&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-as z-ts z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-alias z-ts z-variable z-other z-readwrite&quot;&gt; fs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;fs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-new z-ts z-keyword z-operator z-new&quot;&gt;new&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt; checkly&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Check&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;index-page&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;  activated&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;  frequency&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;  type&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;BROWSER&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;  locations&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-square z-ts z-meta z-brace z-square&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eu-west-2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-square z-ts z-meta z-brace z-square&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;  script&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt; websiteUrl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;apply&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;url&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-ts z-variable z-other z-readwrite&quot;&gt;    fs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;      .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;readFileSync&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;checkly-embed.js&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;      .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;toString&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;utf8&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;      .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;replace&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;{{websiteUrl}}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-ts z-variable z-other z-readwrite&quot;&gt; url&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;  )&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But we need to supply logic for sanity checks, we can do this by creating &lt;code&gt;checkly-embed.js&lt;&#x2F;code&gt; (which the above checkly resource fetches).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-ts z-variable z-other z-constant&quot;&gt; playwright&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; require&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;playwright&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-ts z-variable z-other z-constant&quot;&gt; expect&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; require&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;expect&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-ts z-variable z-other z-constant&quot;&gt; browser&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt; playwright&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-object&quot;&gt;chromium&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;launch&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-ts z-variable z-other z-constant&quot;&gt; page&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt; browser&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;newPage&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt; page&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;goto&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;https:&#x2F;&#x2F;{{websiteUrl}}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;expect&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt; page&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;toBe&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Pulumi Challenge&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt; browser&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;close&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;cherry-on-top-who-wants-swags&quot;&gt;Cherry on top (who wants swags?)&lt;a class=&quot;zola-anchor&quot; href=&quot;#cherry-on-top-who-wants-swags&quot; aria-label=&quot;Anchor link for: cherry-on-top-who-wants-swags&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Kindly provided by folks at Pulumi, we can get cool swags by calling an API endpoint as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;npm&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; install&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; got@11.8.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then paste the following in &lt;code&gt;swag-provider&#x2F;index.ts&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-import-export-all z-ts z-constant&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-as z-ts z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-alias z-ts z-variable z-other z-readwrite&quot;&gt; pulumi&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;@pulumi&#x2F;pulumi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-ts z-variable z-other z-constant&quot;&gt; submittionUrl&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-support z-type z-primitive z-ts&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;https:&#x2F;&#x2F;hooks.airtable.com&#x2F;workflows&#x2F;v1&#x2F;genericWebhook&#x2F;apptZjyaJx5J2BVri&#x2F;wflmg3riOP6fPjCII&#x2F;wtr3RoDcz3mTizw3C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; SwagInputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-support z-type z-primitive z-ts&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  email&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-support z-type z-primitive z-ts&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  address&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-support z-type z-primitive z-ts&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;XS&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;S&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;M&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;L&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;XL&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;XXL&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;XXXL&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; SwagCreateResponse&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  success&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-support z-type z-primitive z-ts&quot;&gt; boolean&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; SwagOutputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; extends&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-inherited-class&quot;&gt; SwagInputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;  id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-support z-type z-primitive z-ts&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-class&quot;&gt; SwagProvider&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; implements&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-module z-ts z-entity z-name z-type z-module&quot;&gt; pulumi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-module z-ts z-entity z-name z-type z-module&quot;&gt;dynamic&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-inherited-class&quot;&gt;ResourceProvider&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;  private&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-support z-type z-primitive z-ts&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;  constructor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-support z-type z-primitive z-ts&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-language&quot;&gt;    this&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-ts z-variable z-other z-readwrite&quot;&gt; name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;  async&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; create&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;props&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; SwagInputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Promise&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-typeparameters&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-module z-ts z-entity z-name z-type z-module&quot;&gt;pulumi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-module z-ts z-entity z-name z-type z-module&quot;&gt;dynamic&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;CreateResult&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-typeparameters&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-ts z-variable z-other z-constant&quot;&gt; got&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;await&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-expression z-import&quot;&gt; import&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;got&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;default&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-ts z-variable z-other z-readwrite&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; await&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-ts z-variable z-other z-readwrite&quot;&gt; got&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;      .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;post&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-ts z-variable z-other z-readwrite&quot;&gt;submittionUrl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;        headers&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Content-Type&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;application&#x2F;json&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;        json&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;          ...&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-ts z-variable z-other z-readwrite&quot;&gt;props&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;      }&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;      .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;json&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-typeparameters&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;SwagCreateResponse&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-typeparameters&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt; id&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-object z-ts z-variable z-other z-object&quot;&gt; props&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;email&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt; outs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-ts z-variable z-other z-readwrite&quot;&gt; props&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;export&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; class&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-class&quot;&gt; Swag&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt; extends&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-module z-ts z-entity z-name z-type z-module&quot;&gt; pulumi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-module z-ts z-entity z-name z-type z-module&quot;&gt;dynamic&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-inherited-class&quot;&gt;Resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;  constructor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;    name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-support z-type z-primitive z-ts&quot;&gt; string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-parameter z-ts&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;    props&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; SwagInputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-parameter z-ts&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;    opts&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-optional&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-module z-ts z-entity z-name z-type z-module&quot;&gt; pulumi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;CustomResourceOptions&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-parameter z-ts&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;  )&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-language&quot;&gt;    super&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-new z-ts z-keyword z-operator z-new&quot;&gt;new&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; SwagProvider&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-ts z-variable z-other z-readwrite&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-ts z-variable z-other z-readwrite&quot;&gt; name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-ts z-variable z-other z-readwrite&quot;&gt; props&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-ts z-variable z-other z-readwrite&quot;&gt; opts&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Finally, paste this to &lt;code&gt;index.ts&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;typescript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-alias z-ts z-variable z-other z-readwrite&quot;&gt; Swag&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; from&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.&#x2F;swag-provider&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-ts z-variable z-other z-constant&quot;&gt; swag&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-new z-ts z-keyword z-operator z-new&quot;&gt; new&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; Swag&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;your-startup&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;  name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;YOUR NAME&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;  email&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;YOUR EMAIL&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;  address&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;YOUR ADDRESS&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-object-literal z-key z-ts z-meta z-object-literal z-key&quot;&gt;  size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-ts z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-ts z-variable z-other z-constant&quot;&gt; SIZE&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brace z-round z-ts&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ts&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;open-sesame&quot;&gt;Open sesame&lt;a class=&quot;zola-anchor&quot; href=&quot;#open-sesame&quot; aria-label=&quot;Anchor link for: open-sesame&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;&#x27;Nuff said&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pulumi&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; up&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If everything works correctly, your terminal should display something like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Previewing&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; update&lt;&#x2F;span&gt;&lt;span&gt; (dev&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;View&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; Live:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; https:&#x2F;&#x2F;app.pulumi.com&#x2F;kahnwong&#x2F;pulumi-challenge-startup-in-a-box&#x2F;dev&#x2F;previews&#x2F;xxxxxxxx&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;     Type&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                               Name&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                                   Plan&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   pulumi:pulumi:Stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                pulumi-challenge-startup-in-a-box-dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  create&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   ├─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; pulumi:challenge:CdnWebsite&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;     your-startup&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                           create&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  ├─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; aws:s3:BucketV2&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;              bucketV2&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                               create&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  ├─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; aws:s3:BucketObject&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;       index.html&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                             create&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  ├─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; aws:s3:BucketObject&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;       style.css&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                              create&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  └─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; aws:s3:BucketObject&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;       normalize.css&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                          create&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  ├─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; aws:s3:BucketAclV2&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;           bAcl&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                                   create&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  └─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; aws:cloudfront:Distribution&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  s3Distribution&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                         create&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   ├─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; pulumi-nodejs:dynamic:Resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  your-startup&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                           create&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   └─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; checkly:index:Check&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;             index-page&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                             create&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Outputs:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    websiteUrl:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; output&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;strin&lt;&#x2F;span&gt;&lt;span&gt;g&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Resources:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; create&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Do&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; you&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; want&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; perform&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; this&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; update?&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Updating&lt;&#x2F;span&gt;&lt;span&gt; (dev&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;View&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; Live:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; https:&#x2F;&#x2F;app.pulumi.com&#x2F;kahnwong&#x2F;pulumi-challenge-startup-in-a-box&#x2F;dev&#x2F;updates&#x2F;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;     Type&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                               Name&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                                   Status&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   pulumi:pulumi:Stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                pulumi-challenge-startup-in-a-box-dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  created&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   ├─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; pulumi:challenge:CdnWebsite&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;     your-startup&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                           created&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  ├─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; aws:s3:BucketV2&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;              bucketV2&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                               created&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  ├─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; aws:s3:BucketObject&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;       style.css&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                              created&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  ├─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; aws:s3:BucketObject&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;       index.html&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                             created&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  └─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; aws:s3:BucketObject&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;       normalize.css&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                          created&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  ├─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; aws:cloudfront:Distribution&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  s3Distribution&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                         created&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   │&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  └─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; aws:s3:BucketAclV2&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;           bAcl&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                                   created&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   ├─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; pulumi-nodejs:dynamic:Resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  your-startup&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                           created&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   └─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; checkly:index:Check&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;             index-page&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                             created&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Outputs:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    websiteUrl:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;dyacxs5ksi1r9.cloudfront.net&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Resources:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; created&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Duration:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; 3m25s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Don&#x27;t you love it when everything works as you planned 😎.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2022&#x2F;09&#x2F;intro-to-pulumi&#x2F;images&#x2F;2022-09-26-15-30-32.webp&quot; alt=&quot;checkly status checks&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;To tear down all resources, run &lt;code&gt;pulumi destroy&lt;&#x2F;code&gt;. If successful, your terminal should return:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Previewing&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; destroy&lt;&#x2F;span&gt;&lt;span&gt; (dev&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;View&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; Live:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; https:&#x2F;&#x2F;app.pulumi.com&#x2F;kahnwong&#x2F;pulumi-challenge-startup-in-a-box&#x2F;dev&#x2F;previews&#x2F;xxxxxxxx&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;     Type&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                               Name&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                                   Plan&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   pulumi:pulumi:Stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                pulumi-challenge-startup-in-a-box-dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  delete&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   ├─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; checkly:index:Check&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;             index-page&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                             delete&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   ├─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; pulumi-nodejs:dynamic:Resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  your-startup&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                           delete&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   └─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; pulumi:challenge:CdnWebsite&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;     your-startup&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                           delete&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;      ├─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; aws:cloudfront:Distribution&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  s3Distribution&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                         delete&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;      ├─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; aws:s3:BucketAclV2&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;           bAcl&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                                   delete&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;      └─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; aws:s3:BucketV2&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;              bucketV2&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                               delete&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;         ├─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; aws:s3:BucketObject&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;       normalize.css&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                          delete&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;         ├─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; aws:s3:BucketObject&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;       style.css&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                              delete&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;         └─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; aws:s3:BucketObject&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;       index.html&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                             delete&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Outputs:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; websiteUrl:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;dyacxs5ksi1r9.cloudfront.net&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Resources:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; delete&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Do&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; you&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; want&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; perform&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; this&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; destroy?&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Destroying&lt;&#x2F;span&gt;&lt;span&gt; (dev&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;View&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; Live:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; https:&#x2F;&#x2F;app.pulumi.com&#x2F;kahnwong&#x2F;pulumi-challenge-startup-in-a-box&#x2F;dev&#x2F;updates&#x2F;2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;     Type&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                               Name&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                                   Status&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   pulumi:pulumi:Stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                pulumi-challenge-startup-in-a-box-dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  deleted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   ├─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; checkly:index:Check&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;             index-page&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                             deleted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   ├─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; pulumi-nodejs:dynamic:Resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  your-startup&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                           deleted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;   └─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; pulumi:challenge:CdnWebsite&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;     your-startup&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                           deleted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;      ├─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; aws:cloudfront:Distribution&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;  s3Distribution&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                         deleted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;      ├─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; aws:s3:BucketAclV2&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;           bAcl&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                                   deleted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;      └─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; aws:s3:BucketV2&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;              bucketV2&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                               deleted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;         ├─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; aws:s3:BucketObject&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;       index.html&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                             deleted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;         ├─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; aws:s3:BucketObject&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;       normalize.css&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                          deleted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;         └─&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; aws:s3:BucketObject&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;       style.css&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                              deleted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Outputs:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; websiteUrl:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;dyacxs5ksi1r9.cloudfront.net&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Resources:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; deleted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Duration:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; 3m22s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;The&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; resources&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; the&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; have&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; been&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; deleted,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; but&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; the&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; history&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; and&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; configuration&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; associated&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; with&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; the&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; are&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; still&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; maintained.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;If&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; you&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; want&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; to&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; remove&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; the&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; completely,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; run&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; `&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pulumi&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; rm&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;`&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</description>
      </item>
      <item>
          <title>Data engineer archetypes</title>
          <pubDate>Fri, 26 Aug 2022 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2022/08/data-engineer-archtypes/</link>
          <guid>https://karnwong.me/posts/2022/08/data-engineer-archtypes/</guid>
          <description xml:base="https://karnwong.me/posts/2022/08/data-engineer-archtypes/">&lt;p&gt;I have been working in the data industry since almost half a decade ago. Over time I have noticed so-called archetypes within various data engineering roles. Below are main skills and combinations I have seen over the years. This is by no means an exhaustive list, rather what I often see.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sql-ssis&quot;&gt;SQL + SSIS&lt;a class=&quot;zola-anchor&quot; href=&quot;#sql-ssis&quot; aria-label=&quot;Anchor link for: sql-ssis&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Using SQL to manipulate data via SSIS, in which data engine is Microsoft SQL Server.&lt;&#x2F;li&gt;
&lt;li&gt;Commonly found in enterprise organizations that use Microsoft stack.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;sql-hive&quot;&gt;SQL + Hive&lt;a class=&quot;zola-anchor&quot; href=&quot;#sql-hive&quot; aria-label=&quot;Anchor link for: sql-hive&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Using SQL to manipulate data via Hive, a filesystem that support columnar data format, usually accessed via Zeppelin.&lt;&#x2F;li&gt;
&lt;li&gt;Often found in enterprise organizations that work with big data before Spark was released.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;sql-dbt&quot;&gt;SQL + DBT&lt;a class=&quot;zola-anchor&quot; href=&quot;#sql-dbt&quot; aria-label=&quot;Anchor link for: sql-dbt&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Using SQL to manipulate data via DBT, an abstraction later for data pipelines scheduler that allows users to use SQL interface with various database engines. DBT is often mentioned in Modern Data Stack.&lt;&#x2F;li&gt;
&lt;li&gt;Often found in newly established organizations in the last few years.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;python-pandas&quot;&gt;Python + pandas&lt;a class=&quot;zola-anchor&quot; href=&quot;#python-pandas&quot; aria-label=&quot;Anchor link for: python-pandas&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Using python with pandas to manipulate data, usually with data that can fit into memory (ie less than 5GB)&lt;&#x2F;li&gt;
&lt;li&gt;This is also common if you have data scientists manipulate data, since pandas is what they are familiar with. In addition, most people who write pandas are not known for writing well-optimized code, but it’s negligible for small data.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;python-pyspark&quot;&gt;Python + pyspark&lt;a class=&quot;zola-anchor&quot; href=&quot;#python-pyspark&quot; aria-label=&quot;Anchor link for: python-pyspark&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Using python with pyspark to manipulate data, can be either SQL or Spark SQL.&lt;&#x2F;li&gt;
&lt;li&gt;Usually organizations that use pyspark also does machine learning as well.&lt;&#x2F;li&gt;
&lt;li&gt;Often found in organizations that work with big data, and have established data lake platform.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;scala-spark&quot;&gt;Scala + spark&lt;a class=&quot;zola-anchor&quot; href=&quot;#scala-spark&quot; aria-label=&quot;Anchor link for: scala-spark&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Using Scala to manipulate data via spark.&lt;&#x2F;li&gt;
&lt;li&gt;Often found on enterprise organizations where they have been using spark before pyspark was released. Has more limited data ecosystem.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;python-task-orchestrator-airflow-dagster-etc&quot;&gt;Python + Task orchestrator (airflow, dagster, etc)&lt;a class=&quot;zola-anchor&quot; href=&quot;#python-task-orchestrator-airflow-dagster-etc&quot; aria-label=&quot;Anchor link for: python-task-orchestrator-airflow-dagster-etc&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Using task orchestrators to run pipelines on a regular basis, the application logic is written in python. Inside can be anything from pure python to pyspark. Or you can use bash and use any unix tools.&lt;&#x2F;li&gt;
&lt;li&gt;People who fall under this category often have software engineering background.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;platform-engineering-setting-up-data-infrastructure-etc&quot;&gt;Platform engineering (setting up data infrastructure, etc)&lt;a class=&quot;zola-anchor&quot; href=&quot;#platform-engineering-setting-up-data-infrastructure-etc&quot; aria-label=&quot;Anchor link for: platform-engineering-setting-up-data-infrastructure-etc&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;These are people that set up database, infrastructure, networking, and everything required to allow engineers&#x2F;users to create data pipelines and consume data at downstream.&lt;&#x2F;li&gt;
&lt;li&gt;Usually they are DevOps who transitioned from working with app infra to data infra.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;Updated 2022-09-02&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;gui-based-solutions&quot;&gt;GUI-based solutions&lt;a class=&quot;zola-anchor&quot; href=&quot;#gui-based-solutions&quot; aria-label=&quot;Anchor link for: gui-based-solutions&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Using GUI-based tools to create data pipelines, such as Talend, AWS Glue, Azure Data Factory, etc. May or may not use in conjunction with SQL &#x2F; python &#x2F; pyspark.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</description>
      </item>
      <item>
          <title>Minimal ECS task with Fargate backend</title>
          <pubDate>Fri, 26 Aug 2022 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2022/08/minimal-ecs-task-with-fargate-backend/</link>
          <guid>https://karnwong.me/posts/2022/08/minimal-ecs-task-with-fargate-backend/</guid>
          <description xml:base="https://karnwong.me/posts/2022/08/minimal-ecs-task-with-fargate-backend/">&lt;p&gt;To deploy a web application, there are many ways to go about it. I could spin up a bare VM and set up the environment manually. To make things easier, I could have package the app into docker image. But this still means I have to &quot;update&quot; the app manually if I add changes to it.&lt;&#x2F;p&gt;
&lt;p&gt;Things would be super cool if: after I push the changes to master branch, the app would be deployed automatically. In order to achieve this, I could use AWS ECS task to deploy the app, and add CI&#x2F;CD to it (because this is 2022 after all).&lt;&#x2F;p&gt;
&lt;p&gt;And things would be even better if I don&#x27;t have to set up the infra manually every time I want to deploy an app, enters terraform!&lt;&#x2F;p&gt;
&lt;p&gt;Below are minimal ecs task with fargate backend setup 😎. Repo &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kahnwong&#x2F;terraform-aws-ecs-fargate-example&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Updated 2022-09-02&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Notes: you might need to set up autoscaling on LB connections per target. Also this example contains two target tracking policies for the same service. Race conditions can result in undesirable scaling issues. Thanks John Mille!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;task-definition&quot;&gt;Task definition&lt;a class=&quot;zola-anchor&quot; href=&quot;#task-definition&quot; aria-label=&quot;Anchor link for: task-definition&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;This is equivalent to docker-compose.yaml&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;hcl&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_cloudwatch_log_group&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;this&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  retention_in_days&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 14&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;              =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;aws&#x2F;ecs&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;service_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_ecs_task_definition&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;this&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  family&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;                   =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;service_name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  network_mode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;             =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;awsvpc&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  requires_compatibilities&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;FARGATE&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  cpu&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;                      =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  memory&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;                   =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 512&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  execution_role_arn&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;       =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;task_role&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  task_role_arn&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;            =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;task_role&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  container_definitions&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; jsonencode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;        name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;        =&lt;&#x2F;span&gt;&lt;span&gt; var.service_name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;        image&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;       =&lt;&#x2F;span&gt;&lt;span&gt; var.image_uri&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;        essential&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;   =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;        environment&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; []&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;        portMappings&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;            protocol&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;tcp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;            containerPort&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 80&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;            hostPort&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 80&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;        logConfiguration&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;          logDriver&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;awslogs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;          options&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;            awslogs-group&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;         =&lt;&#x2F;span&gt;&lt;span&gt; aws_cloudwatch_log_group.this.name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;            awslogs-region&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;        =&lt;&#x2F;span&gt;&lt;span&gt; var.aws_region&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;            awslogs-stream-prefix&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ecs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_ecs_service&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;this&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;                               =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;service_name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  cluster&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;                            =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;ecs_cluster_id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  task_definition&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;                    =&lt;&#x2F;span&gt;&lt;span&gt; aws_ecs_task_definition&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;this&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;arn&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  desired_count&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;                      =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  deployment_minimum_healthy_percent&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 50&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  deployment_maximum_percent&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;         =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 200&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  launch_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;                        =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;FARGATE&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  scheduling_strategy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;                =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;REPLICA&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  network_configuration&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    security_groups&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;alb_id&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    subnets&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;          =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;subnet_id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    assign_public_ip&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  load_balancer&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    target_group_arn&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; aws_alb_target_group&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;this&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;arn&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    container_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;   =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;service_name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    container_port&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;   =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 80&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;ssl-certificate&quot;&gt;SSL certificate&lt;a class=&quot;zola-anchor&quot; href=&quot;#ssl-certificate&quot; aria-label=&quot;Anchor link for: ssl-certificate&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;hcl&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_acm_certificate&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;this&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  domain_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;       =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;domain_name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  validation_method&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;DNS&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  lifecycle&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    create_before_destroy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  tags&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    Name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; var.domain_name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;load-balancer&quot;&gt;Load balancer&lt;a class=&quot;zola-anchor&quot; href=&quot;#load-balancer&quot; aria-label=&quot;Anchor link for: load-balancer&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;hcl&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_lb&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;this&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;               =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;service_name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  internal&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;           =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  load_balancer_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;application&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  security_groups&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;    =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;alb_id&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  subnets&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;            =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;subnet_id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  idle_timeout&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;       =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 3600&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  enable_deletion_protection&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_alb_target_group&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;this&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;        =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;service_name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  port&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;        =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 80&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  protocol&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;    =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;HTTP&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  vpc_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;vpc_id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  target_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ip&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  health_check&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    healthy_threshold&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;   =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    interval&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;            =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;30&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    protocol&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;            =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;HTTP&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    matcher&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;             =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;200&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    timeout&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;             =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;                =&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;health_check_path&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    unhealthy_threshold&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_alb_listener&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;http&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  load_balancer_arn&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; aws_lb&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;this&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  port&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;              =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 80&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  protocol&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;          =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;HTTP&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  default_action&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;             =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;forward&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    target_group_arn&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; aws_alb_target_group&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;this&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;arn&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_alb_listener&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;https&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  load_balancer_arn&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; aws_lb&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;this&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  port&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;              =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 443&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  protocol&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;          =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;HTTPS&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  ssl_policy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ELBSecurityPolicy-2016-08&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  certificate_arn&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; aws_acm_certificate&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;this&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;arn&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  default_action&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    target_group_arn&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; aws_alb_target_group&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;this&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;             =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;forward&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;autoscaling&quot;&gt;Autoscaling&lt;a class=&quot;zola-anchor&quot; href=&quot;#autoscaling&quot; aria-label=&quot;Anchor link for: autoscaling&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Because we are using cloud, and I love taking advantage of dynamic resources allocation.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;hcl&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_appautoscaling_target&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;this&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  max_capacity&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;       =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  min_capacity&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;       =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  resource_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;        =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;service&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;ecs_cluster_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;aws_ecs_service&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;this&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  scalable_dimension&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ecs:service:DesiredCount&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  service_namespace&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ecs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_appautoscaling_policy&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;memory&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;               =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;memory-autoscaling&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  policy_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;        =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;TargetTrackingScaling&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  resource_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;        =&lt;&#x2F;span&gt;&lt;span&gt; aws_appautoscaling_target&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;this&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;resource_id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  scalable_dimension&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; aws_appautoscaling_target&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;this&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;scalable_dimension&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  service_namespace&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span&gt; aws_appautoscaling_target&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;this&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;service_namespace&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  target_tracking_scaling_policy_configuration&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;    predefined_metric_specification&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;      predefined_metric_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ECSServiceAverageMemoryUtilization&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    target_value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 40&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_appautoscaling_policy&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;cpu&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;               =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;cpu-autoscaling&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  policy_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;        =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;TargetTrackingScaling&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  resource_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;        =&lt;&#x2F;span&gt;&lt;span&gt; aws_appautoscaling_target&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;this&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;resource_id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  scalable_dimension&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; aws_appautoscaling_target&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;this&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;scalable_dimension&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  service_namespace&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span&gt; aws_appautoscaling_target&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;this&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;service_namespace&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  target_tracking_scaling_policy_configuration&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;    predefined_metric_specification&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;      predefined_metric_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ECSServiceAverageCPUUtilization&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    target_value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 60&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</description>
      </item>
      <item>
          <title>What SQL can&#x27;t do for data engineering</title>
          <pubDate>Sun, 15 May 2022 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2022/05/what-sql-cant-do-for-data-engineering/</link>
          <guid>https://karnwong.me/posts/2022/05/what-sql-cant-do-for-data-engineering/</guid>
          <description xml:base="https://karnwong.me/posts/2022/05/what-sql-cant-do-for-data-engineering/">&lt;p&gt;I often hear people ask &quot;if you can do data engineering with SQL, then what&#x27;s the point of learning spark or python?&quot;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;data-ingestion&quot;&gt;Data ingestion&lt;a class=&quot;zola-anchor&quot; href=&quot;#data-ingestion&quot; aria-label=&quot;Anchor link for: data-ingestion&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Let&#x27;s circle back at bit.&lt;&#x2F;p&gt;
&lt;p&gt;I think we all can agree that: there&#x27;s a point in time where there&#x27;s no data in the data warehouse (which DE-who-use-SQL&#x27;s use as base of operation). The source data could be anything from hard CSV&#x2F;Excel or API endpoints. No data in data warehouse, DE can&#x27;t use SQL to do stuff with the data.&lt;&#x2F;p&gt;
&lt;p&gt;So who put the data into the data warehouse? Data engineers of course! But not the kind that use SQL. These data engineers are known as &quot;data &lt;em&gt;platform&lt;&#x2F;em&gt; engineers,&quot; where their main focus is data ingestion, platform and scalability.&lt;&#x2F;p&gt;
&lt;p&gt;The confusion lies in the fact that, there seems to be different tools and skills required for platform or analytics type for data engineers, but some places still refer to both roles as data engineer.&lt;&#x2F;p&gt;
&lt;p&gt;And guess how data platform engineers write large amount of data to data warehouse. With help of spark and python&#x2F;java of course!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;data-cleaning&quot;&gt;Data cleaning&lt;a class=&quot;zola-anchor&quot; href=&quot;#data-cleaning&quot; aria-label=&quot;Anchor link for: data-cleaning&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;What if you need to perform complex data cleaning processes for your data? You might have to create multiple temp columns, then coalesce them at the end to get the final result. You can do this in SQL, with the help of jinja template, to certain extent. But the same process expressed in python would be much more concise and readable. Especially if it in involves multiple steps spanning 700 lines of code. Not to mention you might need to perform debugging somewhere in between, and setting up SQL debugging is not something I wish on my worst enemy.&lt;&#x2F;p&gt;
&lt;p&gt;Some people say &quot;but you can also create functions in SQL.&quot; Yes, you can, but it&#x27;s clunky and very fragile, and not very readable.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;optimization&quot;&gt;Optimization&lt;a class=&quot;zola-anchor&quot; href=&quot;#optimization&quot; aria-label=&quot;Anchor link for: optimization&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;When you&#x27;re writing SQL for data transformation, the actual execution logic is being translated by the database&#x27;s engine. As with all forms of translations, some information is lost, and can result in non-optimized instructions. For instance, if you need to perform longest matching against a list of string, one way to optimize this is to set a &lt;code&gt;break&lt;&#x2F;code&gt; condition after you found a match. In SQL, this most likely results in instructions to compare every string from the list, instead of stopping the matching process and move onto the next operation after a match is found.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;These are some but not all instances where SQL falls short for data engineering tasks. I hope this article sheds some light on the importance of using python&#x2F;spark for data engineering tasks.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Use SSH key during Docker Build without embedding the key via ssh-agent</title>
          <pubDate>Sun, 06 Feb 2022 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2022/02/use-ssh-key-during-docker-build-without-embedding-the-key-via-ssh-agent/</link>
          <guid>https://karnwong.me/posts/2022/02/use-ssh-key-during-docker-build-without-embedding-the-key-via-ssh-agent/</guid>
          <description xml:base="https://karnwong.me/posts/2022/02/use-ssh-key-during-docker-build-without-embedding-the-key-via-ssh-agent/">&lt;p&gt;Imagine working in a company, and they have a super cool internal module! The module works great, except that it is a private module, which means you need to install it by cloning the source repo and install it from source.&lt;&#x2F;p&gt;
&lt;p&gt;That shouldn&#x27;t be an issue if you work on your local machine. But for production usually this means you somehow need to bundle this awesome module into your docker image. You go create a Dockerfile and there&#x27;s one little problem: it couldn&#x27;t clone the module repo because it doesn&#x27;t have the required SSH key that can access the repo.&lt;&#x2F;p&gt;
&lt;p&gt;A very simple solution would just be bundling the SSH key into the docker image itself. This works great, until security comes knocking because: anyone who can access the image can also access the source repo! And we wouldn&#x27;t want that.&lt;&#x2F;p&gt;
&lt;p&gt;So what&#x27;s the solution? Luckily there&#x27;s a thing called ssh-agent forwarding. Think of it as passing an SSH key into docker during build, then poof! It&#x27;s gone.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;instructions&quot;&gt;Instructions&lt;a class=&quot;zola-anchor&quot; href=&quot;#instructions&quot; aria-label=&quot;Anchor link for: instructions&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Set up SSH key on your host machine. This essentially means you should be able to perform &lt;code&gt;git clone $REPO&lt;&#x2F;code&gt; on the module repo.&lt;&#x2F;li&gt;
&lt;li&gt;In your Dockerfile, add something like the following:&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;docker&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Authorize SSH Host&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; mkdir -p -m 700 &#x2F;root&#x2F;.ssh &amp;amp;&amp;amp; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    touch -m 600 &#x2F;root&#x2F;.ssh&#x2F;known_hosts &amp;amp;&amp;amp; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ssh-keyscan github.com &amp;gt; &#x2F;root&#x2F;.ssh&#x2F;known_hosts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; --mount=type=ssh,id=github $SOME_COMMAND_THAT_NEEDS_SSH_KEY&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;Build docker image with &lt;code&gt;docker build --ssh github=$SSH_PRIVATE_KEY_PATH -t $IMAGE_NAME .&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;github-actions&quot;&gt;GitHub Actions&lt;a class=&quot;zola-anchor&quot; href=&quot;#github-actions&quot; aria-label=&quot;Anchor link for: github-actions&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;In GitHub actions, #1 is translated as:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; S&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;etup SSH Keys and known_hosts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  r&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;un&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    mkdir -p ~&#x2F;.ssh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    ssh-keyscan github.com &amp;gt;&amp;gt; ~&#x2F;.ssh&#x2F;known_hosts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    ssh-agent -a $SSH_AUTH_SOCK &amp;gt; &#x2F;dev&#x2F;null&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    ssh-add - &amp;lt;&amp;lt;&amp;lt; &amp;quot;${{ secrets.SSH_PRIVATE_KEY }}&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  e&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nv&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    S&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;SH_AUTH_SOCK&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;tmp&#x2F;ssh_agent.sock&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; B&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;uild, tag, and push image to Amazon ECR&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  u&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ses&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ocker&#x2F;build-push-action@v2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  e&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nv&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    S&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;SH_AUTH_SOCK&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;tmp&#x2F;ssh_agent.sock&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  w&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ith&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    c&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ontext&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    p&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ush&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ags&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; $&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;{{ steps.meta.outputs.tags }}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    c&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ache-from&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ype=gha&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    c&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ache-to&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ype=gha,mode=max&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;sh&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;      github=${{ env.SSH_AUTH_SOCK }}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Voila 🎉&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Use Pyspark locally with Docker</title>
          <pubDate>Tue, 21 Dec 2021 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2021/12/use-pyspark-locally-with-docker/</link>
          <guid>https://karnwong.me/posts/2021/12/use-pyspark-locally-with-docker/</guid>
          <description xml:base="https://karnwong.me/posts/2021/12/use-pyspark-locally-with-docker/">&lt;p&gt;For data that doesn&#x27;t fit into memory, spark is often a recommended solution, since it can utilize map-reduce to work with data in a distributed manner. However, setting up local spark development from scratch involves multiple steps, and definitely not for a faint of heart. Thankfully using docker means you can skip a lot of steps 😃&lt;&#x2F;p&gt;
&lt;h2 id=&quot;instructions&quot;&gt;Instructions&lt;a class=&quot;zola-anchor&quot; href=&quot;#instructions&quot; aria-label=&quot;Anchor link for: instructions&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Install &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.docker.com&#x2F;get-started&quot;&gt;Docker Desktop&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Create &lt;code&gt;docker-compose.yml&lt;&#x2F;code&gt; in a directory somewhere&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;v&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ersion&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;3.3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ervices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  p&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;yspark&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    c&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ontainer_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;yspark&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;mage&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; j&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;upyter&#x2F;pyspark-notebook:latest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    p&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;orts&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;      -&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;8888:8888&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    v&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;olumes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;      -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; .&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;:&#x2F;home&#x2F;jovyan&#x2F;work&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;Run &lt;code&gt;docker-compose up&lt;&#x2F;code&gt; from the same folder where the above file is located.&lt;&#x2F;li&gt;
&lt;li&gt;You should see something like this. It&#x27;s the same from running &lt;code&gt;jupyter notebook&lt;&#x2F;code&gt; locally. Click the link at the end to access jupyter notebook.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;log&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Creating pyspark ... done&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Attaching to pyspark&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyspark    | &lt;&#x2F;span&gt;&lt;span class=&quot;z-markup z-deleted z-log z-warning&quot;&gt;WARNING&lt;&#x2F;span&gt;&lt;span&gt;: Jupyter Notebook deprecation notice &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;jupyter&#x2F;docker-stacks#jupyter-notebook-deprecation-notice&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyspark    | Entered &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;start.sh&lt;&#x2F;span&gt;&lt;span&gt; with args: jupyter notebook&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyspark    | &#x2F;usr&#x2F;local&#x2F;bin&#x2F;start.sh: running hooks in &#x2F;usr&#x2F;local&#x2F;bin&#x2F;before-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;notebook.d&lt;&#x2F;span&gt;&lt;span&gt; as uid &#x2F; gid: &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1000&lt;&#x2F;span&gt;&lt;span&gt; &#x2F; &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;100&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyspark    | &#x2F;usr&#x2F;local&#x2F;bin&#x2F;start.sh: running script &#x2F;usr&#x2F;local&#x2F;bin&#x2F;before-notebook.d&#x2F;spark-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;config.sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyspark    | &#x2F;usr&#x2F;local&#x2F;bin&#x2F;start.sh: done running hooks in &#x2F;usr&#x2F;local&#x2F;bin&#x2F;before-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;notebook.d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyspark    | Executing the command: jupyter notebook&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyspark    | [I &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;12:36:04.395&lt;&#x2F;span&gt;&lt;span&gt; NotebookApp] Writing notebook server cookie secret to &#x2F;home&#x2F;jovyan&#x2F;.local&#x2F;share&#x2F;jupyter&#x2F;runtime&#x2F;notebook_cookie_secret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyspark    | [W &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;2021-12-21&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 12:36:05.487&lt;&#x2F;span&gt;&lt;span&gt; LabApp] &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;ip&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt; has moved from NotebookApp to ServerApp. This config will be passed to ServerApp. Be sure to update your config before our next release.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyspark    | [W &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;2021-12-21&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 12:36:05.488&lt;&#x2F;span&gt;&lt;span&gt; LabApp] &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;port&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt; has moved from NotebookApp to ServerApp. This config will be passed to ServerApp. Be sure to update your config before our next release.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyspark    | [W &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;2021-12-21&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 12:36:05.488&lt;&#x2F;span&gt;&lt;span&gt; LabApp] &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;port&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt; has moved from NotebookApp to ServerApp. This config will be passed to ServerApp. Be sure to update your config before our next release.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyspark    | [W &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;2021-12-21&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 12:36:05.488&lt;&#x2F;span&gt;&lt;span&gt; LabApp] &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;port&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt; has moved from NotebookApp to ServerApp. This config will be passed to ServerApp. Be sure to update your config before our next release.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyspark    | [I &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;2021-12-21&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 12:36:05.497&lt;&#x2F;span&gt;&lt;span&gt; LabApp] JupyterLab extension loaded from &#x2F;opt&#x2F;conda&#x2F;lib&#x2F;python3.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;9&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;site-packages&#x2F;jupyterlab&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyspark    | [I &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;2021-12-21&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 12:36:05.498&lt;&#x2F;span&gt;&lt;span&gt; LabApp] JupyterLab application directory is &#x2F;opt&#x2F;conda&#x2F;share&#x2F;jupyter&#x2F;lab&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyspark    | [I &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;12:36:05.504&lt;&#x2F;span&gt;&lt;span&gt; NotebookApp] Serving notebooks from local directory: &#x2F;home&#x2F;jovyan&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyspark    | [I &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;12:36:05.504&lt;&#x2F;span&gt;&lt;span&gt; NotebookApp] Jupyter Notebook &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt; is running at:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyspark    | [I &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;12:36:05.504&lt;&#x2F;span&gt;&lt;span&gt; NotebookApp] &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;http:&#x2F;&#x2F;bd20652c22d3:8888&#x2F;?token=408f2020435dfb489c8d2710736a83f7a3c7cd969b3a1629&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyspark    | [I &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;12:36:05.504&lt;&#x2F;span&gt;&lt;span&gt; NotebookApp]  or &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;http:&#x2F;&#x2F;127.0.0.1:8888&#x2F;?token=408f2020435dfb489c8d2710736a83f7a3c7cd969b3a1629&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyspark    | [I &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;12:36:05.504&lt;&#x2F;span&gt;&lt;span&gt; NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyspark    | [C &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;12:36:05.509&lt;&#x2F;span&gt;&lt;span&gt; NotebookApp]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyspark    |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyspark    |     To access the notebook, open this file in a browser:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyspark    |         &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;file:&#x2F;&#x2F;&#x2F;home&#x2F;jovyan&#x2F;.local&#x2F;share&#x2F;jupyter&#x2F;runtime&#x2F;nbserver-7-open.html&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyspark    |     Or copy and paste one of these URLs:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyspark    |         &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;http:&#x2F;&#x2F;bd20652c22d3:8888&#x2F;?token=408f2020435dfb489c8d2710736a83f7a3c7cd969b3a1629&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyspark    |      or &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;http:&#x2F;&#x2F;127.0.0.1:8888&#x2F;?token=408f2020435dfb489c8d2710736a83f7a3c7cd969b3a1629&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;This snippet&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;v&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;olumes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; .&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;:&#x2F;home&#x2F;jovyan&#x2F;work&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;means that anything you put in [the folder where &lt;code&gt;docker-compose.yml&lt;&#x2F;code&gt; is] can be accessed by [jupyter notebook running inside docker], and what you do from inside jupyter notebook can be seen on the host system too.&lt;&#x2F;p&gt;
&lt;p&gt;See? Easy as a 🥧.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Reduce Docker image size with Alpine</title>
          <pubDate>Sun, 19 Dec 2021 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2021/12/reduce-docker-image-size-with-alpine/</link>
          <guid>https://karnwong.me/posts/2021/12/reduce-docker-image-size-with-alpine/</guid>
          <description xml:base="https://karnwong.me/posts/2021/12/reduce-docker-image-size-with-alpine/">&lt;p&gt;Creating scripts are easy. But creating a small docker image is not 😅.&lt;&#x2F;p&gt;
&lt;p&gt;Not all Linux flavors are created equal, some are bigger than others, etc. But this difference is very crucial when it comes to reducing docker image size.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-simple-bash-script-docker-image&quot;&gt;A simple bash script docker image&lt;a class=&quot;zola-anchor&quot; href=&quot;#a-simple-bash-script-docker-image&quot; aria-label=&quot;Anchor link for: a-simple-bash-script-docker-image&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Given a Dockerfile (change &lt;code&gt;apk&lt;&#x2F;code&gt; to &lt;code&gt;apt&lt;&#x2F;code&gt; for &lt;code&gt;ubuntu&lt;&#x2F;code&gt;):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;docker&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method&quot;&gt;FROM&lt;&#x2F;span&gt;&lt;span&gt; alpine:3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method&quot;&gt;WORKDIR&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;app&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; apk update &amp;amp;&amp;amp; apk add jq curl&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method&quot;&gt;COPY&lt;&#x2F;span&gt;&lt;span&gt; water-cut-notify.sh .&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method&quot;&gt;ENTRYPOINT&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;sh&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;app&#x2F;water-cut-notify.sh&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Base image&lt;&#x2F;th&gt;&lt;th&gt;Docker image size&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;alpine&lt;&#x2F;td&gt;&lt;td&gt;11.1MB&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;ubuntu&lt;&#x2F;td&gt;&lt;td&gt;122MB&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Ubuntu image size is &lt;code&gt;1099%&lt;&#x2F;code&gt; larger!!!!!!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-about-a-light-python-image&quot;&gt;What about a light python image?&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-about-a-light-python-image&quot; aria-label=&quot;Anchor link for: what-about-a-light-python-image&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;docker&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method&quot;&gt;FROM&lt;&#x2F;span&gt;&lt;span&gt; python:3.9-alpine&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method&quot;&gt;WORKDIR&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;app&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; pip install requests&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Base image&lt;&#x2F;th&gt;&lt;th&gt;Docker image size&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;alpine&lt;&#x2F;td&gt;&lt;td&gt;53.6MB&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;ubuntu&lt;&#x2F;td&gt;&lt;td&gt;920MB&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Ubuntu image size is &lt;code&gt;1716%&lt;&#x2F;code&gt; larger!!!!!!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;should-you-use-alpine-image-for-everything&quot;&gt;Should you use alpine image for everything?&lt;a class=&quot;zola-anchor&quot; href=&quot;#should-you-use-alpine-image-for-everything&quot; aria-label=&quot;Anchor link for: should-you-use-alpine-image-for-everything&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;From above two experiments, we get:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2021&#x2F;12&#x2F;reduce-docker-image-size-with-alpine&#x2F;images&#x2F;2021-12-19-21-21-35.webp&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s obvious that alpine has a very significant lighter footprint than ubuntu. But don&#x27;t use alpine image for everything. For bash and go, using alpine results in lighter footprint. But for python apps, it&#x27;s better to go with debian-based images. This &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pythonspeed.com&#x2F;articles&#x2F;alpine-docker-python&#x2F;&quot;&gt;article&lt;&#x2F;a&gt; explains in details why it&#x27;s so.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Secrets management with SOPS, AWS Secrets Manager and Terraform</title>
          <pubDate>Tue, 30 Nov 2021 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2021/11/secrets-management-with-sops-aws-ssm-terraform/</link>
          <guid>https://karnwong.me/posts/2021/11/secrets-management-with-sops-aws-ssm-terraform/</guid>
          <description xml:base="https://karnwong.me/posts/2021/11/secrets-management-with-sops-aws-ssm-terraform/">&lt;p&gt;Correction 2023-07-06: I only recently realized SSM and Secrets Manager are not the same.&lt;&#x2F;p&gt;
&lt;p&gt;At my organization we use sops to check in encrypted secrets into git repos. This solves plaintext credentials in version control. However, say, you have 5 repos using the same database credentials, rotating secrets means you have to go into each repo and update the SOPS credentials manually.&lt;&#x2F;p&gt;
&lt;p&gt;Also worth nothing that, for GitHub actions, authenticating AWS means you have to add repo secrets. This means for all the repos you have CI enabled, you have to populate the repo secrets with AWS credentials. When time comes for rotating the creds, you&#x27;ll encounter the same situation as above.&lt;&#x2F;p&gt;
&lt;p&gt;I did some research and consensus for AWS &#x2F; Terraform setup is to: encrypt secrets via SOPS, and use Terraform to create AWS secret entries. That way, you have a trail for credentials. This setup means:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;You don&#x27;t have to populate repos with AWS creds, instead supplying an ARN role instead.&lt;&#x2F;li&gt;
&lt;li&gt;You don&#x27;t have to change credentials in projects, since they all get the secrets from AWS Secrets Manager.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;a class=&quot;zola-anchor&quot; href=&quot;#implementation&quot; aria-label=&quot;Anchor link for: implementation&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Repo here: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kahnwong&#x2F;terraform-sops-ssm&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;kahnwong&#x2F;terraform-sops-ssm&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;1-bootstrap-terraform&quot;&gt;1. Bootstrap Terraform&lt;a class=&quot;zola-anchor&quot; href=&quot;#1-bootstrap-terraform&quot; aria-label=&quot;Anchor link for: 1-bootstrap-terraform&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;hcl&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;terraform&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  required_providers&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    sops&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;      source&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;carlpett&#x2F;sops&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;      version&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;0.6.3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;provider&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  region&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ap-southeast-1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  profile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;playground&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;provider&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;sops&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;terraform&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  required_version&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;gt;= 1.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;2-create-kms-key-for-sops&quot;&gt;2. Create KMS key for SOPS&lt;a class=&quot;zola-anchor&quot; href=&quot;#2-create-kms-key-for-sops&quot; aria-label=&quot;Anchor link for: 2-create-kms-key-for-sops&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;mozilla&#x2F;sops&#x2F;#kms-aws-profiles&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;mozilla&#x2F;sops&#x2F;#kms-aws-profiles&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;hcl&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_kms_key&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;sops&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  description&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Keys to decrypt SOPS encrypted values&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_kms_alias&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;sops&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;          =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;alias&#x2F;sops&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  target_key_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; aws_kms_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;sops&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;key_id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;3-create-secrets&quot;&gt;3. Create secrets&lt;a class=&quot;zola-anchor&quot; href=&quot;#3-create-secrets&quot; aria-label=&quot;Anchor link for: 3-create-secrets&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Create a folder named &lt;code&gt;secrets&lt;&#x2F;code&gt;, inside it create JSON files and encrypt each with sops.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;hcl&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;locals&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  secrets&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; toset&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;db-foo&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;data&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;sops_file&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;sops_secrets&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  for_each&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;    =&lt;&#x2F;span&gt;&lt;span&gt; local&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;secrets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  source_file&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;secrets&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;each&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.sops.json&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; aws keeps the secrets for 7 days before actual deletion. consider using random names during test&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_secretsmanager_secret&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;ssm_secrets&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  for_each&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; local&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;secrets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;     =&lt;&#x2F;span&gt;&lt;span&gt; each&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_secretsmanager_secret_version&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;ssm_secrets&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  for_each&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;      =&lt;&#x2F;span&gt;&lt;span&gt; local&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;secrets&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  secret_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;     =&lt;&#x2F;span&gt;&lt;span&gt; aws_secretsmanager_secret&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;ssm_secrets&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;each&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  secret_string&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; jsonencode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;sops_file&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;sops_secrets&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;each&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;4-create-iam-policy-for-ssm-access&quot;&gt;4. Create IAM policy for SSM access&lt;a class=&quot;zola-anchor&quot; href=&quot;#4-create-iam-policy-for-ssm-access&quot; aria-label=&quot;Anchor link for: 4-create-iam-policy-for-ssm-access&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;hcl&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;data&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_iam_policy_document&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;secrets_ro&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  statement&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    actions&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;secretsmanager:GetResourcePolicy&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;secretsmanager:GetSecretValue&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;secretsmanager:DescribeSecret&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;secretsmanager:ListSecretVersionIds&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    resources&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;arn:aws:secretsmanager:ap-southeast-1:$AWS_ACCOUNT_ID:secret:*&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  statement&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    actions&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;secretsmanager:ListSecrets&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    resources&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_iam_policy&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;secrets_ro&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;   =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;secrets_ro&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;   =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  policy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;aws_iam_policy_document&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;secrets_ro&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;5-create-iam-user-for-local-dev&quot;&gt;5. Create IAM user for local dev&lt;a class=&quot;zola-anchor&quot; href=&quot;#5-create-iam-user-for-local-dev&quot; aria-label=&quot;Anchor link for: 5-create-iam-user-for-local-dev&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;You shouldn&#x27;t supply AWS credentials for deployment, since you can grant access via IAM roles instead.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;hcl&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_iam_user&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;playground-prod-dev&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;playground-prod-dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;users&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_iam_access_key&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;playground-prod-dev&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  user&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; aws_iam_user&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;playground-prod-dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;grant-iam-user-access-to-secrets&quot;&gt;Grant IAM user access to Secrets&lt;a class=&quot;zola-anchor&quot; href=&quot;#grant-iam-user-access-to-secrets&quot; aria-label=&quot;Anchor link for: grant-iam-user-access-to-secrets&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;hcl&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_iam_user_policy_attachment&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;playground-prod-dev&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  user&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; aws_iam_user&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;playground-prod-dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  for_each&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; toset&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    aws_iam_policy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;secrets_ro&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;arn&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  policy_arn&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; each&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;value&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;6-create-iam-role-for-lambda&quot;&gt;6. Create IAM role for Lambda&lt;a class=&quot;zola-anchor&quot; href=&quot;#6-create-iam-role-for-lambda&quot; aria-label=&quot;Anchor link for: 6-create-iam-role-for-lambda&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;hcl&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_iam_role&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;lambda_role&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;lambda_role&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;sa&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  assume_role_policy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; jsonencode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    Version&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;2012-10-17&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    Statement&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Effect&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Allow&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Principal&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; :&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Service&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;lambda.amazonaws.com&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Action&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;sts:AssumeRole&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      }&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  managed_policy_arns&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    aws_iam_policy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;secrets_ro&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;arn&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  inline_policy&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;create_cloudwatch_logs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    policy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; jsonencode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Version&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;2012-10-17&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Statement&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; :&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Action&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; :&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;logs:CreateLogGroup&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;logs:CreateLogStream&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;logs:PutLogEvents&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Effect&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Allow&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;          &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;7-create-iam-role-for-github-actions&quot;&gt;7. Create IAM role for GitHub actions&lt;a class=&quot;zola-anchor&quot; href=&quot;#7-create-iam-role-for-github-actions&quot; aria-label=&quot;Anchor link for: 7-create-iam-role-for-github-actions&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Need to create OIDC so GitHub can assume AWS roles&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;hcl&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_iam_openid_connect_provider&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;github&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  url&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;             =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;https:&#x2F;&#x2F;token.actions.githubusercontent.com&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  client_id_list&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;  =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;sts.amazonaws.com&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  thumbprint_list&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;a031c46782e6e6c662c2c87c76da9aa62ccabd8e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Assume role policy is on per-repo basis&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;hcl&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;locals&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  repositories&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;terraform-sops-ssm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;data&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_iam_policy_document&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;github_actions_assume_role&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;  statement&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    actions&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;sts:AssumeRoleWithWebIdentity&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;    principals&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;      type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;        =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Federated&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;      identifiers&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;aws_iam_openid_connect_provider&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;github&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;arn&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;    condition&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;      test&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;     =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ForAnyValue:StringLike&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;      variable&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;token.actions.githubusercontent.com:sub&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;      values&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;   =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;for&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-word&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt; local&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;repositories&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;repo:kahnwong&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;${&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;v&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;:*&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Finally attach the above policy to role&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;hcl&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;resource&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;aws_iam_role&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; &amp;quot;playground-prod-github&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;playground-prod-github&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  path&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;sa&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  assume_role_policy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;aws_iam_policy_document&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;github_actions_assume_role&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;  managed_policy_arns&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-variable z-other z-readwrite&quot;&gt;    aws_iam_policy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;secrets_ro&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;arn&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The end 🎉&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bonus&quot;&gt;Bonus&lt;a class=&quot;zola-anchor&quot; href=&quot;#bonus&quot; aria-label=&quot;Anchor link for: bonus&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kahnwong&#x2F;terraform-sops-ssm&#x2F;blob&#x2F;master&#x2F;.github&#x2F;workflows&#x2F;deploy.yml&quot;&gt;GitHub actions with AWS login&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kahnwong&#x2F;terraform-sops-ssm&#x2F;tree&#x2F;master&#x2F;app&quot;&gt;AWS Lambda with SSM template&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</description>
      </item>
      <item>
          <title>Run GitHub Actions faster with cache for Pipenv and Docker build</title>
          <pubDate>Tue, 09 Nov 2021 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2021/11/run-github-actions-faster-with-cache-for-pipenv-and-docker-build/</link>
          <guid>https://karnwong.me/posts/2021/11/run-github-actions-faster-with-cache-for-pipenv-and-docker-build/</guid>
          <description xml:base="https://karnwong.me/posts/2021/11/run-github-actions-faster-with-cache-for-pipenv-and-docker-build/">&lt;p&gt;&lt;em&gt;Update 2021-11-29&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Recently we create more PRs, notice that there are a lot of redundant steps (env setup before triggering checks, etc). Found out you can cache steps in GitHub Actions, so I did some research. Got it working and turns out I reduce at least 60% actions time for a large docker image build (since only the later &lt;code&gt;RUN&lt;&#x2F;code&gt; directives are changed more frequently). For pipenv it shaved off 1 minute 18 seconds. Pretty neat!&lt;&#x2F;p&gt;
&lt;h3 id=&quot;pipenv-cache&quot;&gt;pipenv cache&lt;a class=&quot;zola-anchor&quot; href=&quot;#pipenv-cache&quot; aria-label=&quot;Anchor link for: pipenv-cache&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; https:&#x2F;&#x2F;github.com&#x2F;actions&#x2F;setup-python#caching-packages-dependencies&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ses&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ctions&#x2F;setup-python@v2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  w&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ith&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    p&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ython-version&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;3.9&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    c&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ache&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;pipenv&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;docker-build-cache&quot;&gt;docker build cache&lt;a class=&quot;zola-anchor&quot; href=&quot;#docker-build-cache&quot; aria-label=&quot;Anchor link for: docker-build-cache&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; S&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;et up Docker Buildx&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  u&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ses&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ocker&#x2F;setup-buildx-action@v1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; A&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;dd IMAGE_TAG to env&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  r&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;un&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;cho &amp;quot;IMAGE_TAG=`echo ${GITHUB_SHA::7}`&amp;quot; &amp;gt;&amp;gt; $GITHUB_ENV&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; B&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;uild, tag, and push image to Amazon ECR&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  u&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ses&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ocker&#x2F;build-push-action@v2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  e&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nv&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    I&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;MAGE_NAME&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ervice&#x2F;app&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  w&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ith&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    c&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ontext&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    p&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ush&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ags&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; $&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;{{ env.IMAGE_NAME }}:latest,${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    c&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ache-from&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ype=gha&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    c&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ache-to&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ype=gha,mode=max&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</description>
      </item>
      <item>
          <title>ecs-cli snippets</title>
          <pubDate>Fri, 08 Oct 2021 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2021/10/ecs-cli-snippets/</link>
          <guid>https://karnwong.me/posts/2021/10/ecs-cli-snippets/</guid>
          <description xml:base="https://karnwong.me/posts/2021/10/ecs-cli-snippets/">&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;ecs-cli&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; configure&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; profile&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-access-key&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; $&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;KEY&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-secret-key&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; $&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;SECRET&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-profile-name&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; $&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;PROFILE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;## launch mode: fargate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;ecs-cli&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; configure&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-cluster&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; $&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;CLUSTER&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-default-launch-type&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; FARGATE&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-config-name&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; $&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;NAME&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-region&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ap-southeast-1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;ecs-cli&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; up&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-cluster-config&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; $&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;NAME&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-vpc&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; $&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;VPCID&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-subnets&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; $&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;SUBNETID1&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; $&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;SUBNETID2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;## launch mode: ec2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;ecs-cli&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; configure&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-cluster&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; $&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;CLUSTER&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-region&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ap-southeast-1&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-default-launch-type&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; EC2&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-config-name&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; $&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;NAME&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;ecs-cli&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; up&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-keypair&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; $&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;KEYPAIR&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-extra-user-data&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; userData.sh&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-capability-iam&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-size&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-instance-type&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; t2.large&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-cluster-config&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; $&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;NAME&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-verbose&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-force&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-aws-profile&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; $&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;PROFILE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;ecs-cli&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; compose&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-cluster-config&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; $&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;NAME&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-file&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; docker-compose.yml&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; up&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-create-log-groups&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</description>
      </item>
      <item>
          <title>Self-hosting primer</title>
          <pubDate>Sun, 22 Aug 2021 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2021/08/self-hosting-primer/</link>
          <guid>https://karnwong.me/posts/2021/08/self-hosting-primer/</guid>
          <description xml:base="https://karnwong.me/posts/2021/08/self-hosting-primer/">&lt;p&gt;&lt;strong&gt;Updated: 2025-01-26&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Self-hosting is a practice for running and managing websites &#x2F; services using your own server. Some people do this because they are concerned about their privacy, or some services are free if they host it themselves. Below are instructions for how to do self-hosting (also applies to hosting your own website too).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;requirements&quot;&gt;Requirements&lt;a class=&quot;zola-anchor&quot; href=&quot;#requirements&quot; aria-label=&quot;Anchor link for: requirements&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Domain name&lt;&#x2F;li&gt;
&lt;li&gt;Server (can be your own computer at home or VPS)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;instructions&quot;&gt;Instructions&lt;a class=&quot;zola-anchor&quot; href=&quot;#instructions&quot; aria-label=&quot;Anchor link for: instructions&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Set up and secure the server. Don&#x27;t forget to disable password login.&lt;&#x2F;li&gt;
&lt;li&gt;Deploy a website on your server (follow instructions for each service. I recommend deploying via Docker).&lt;&#x2F;li&gt;
&lt;li&gt;If you are using a server at home which has dynamic IP, setup DDNS (I recommend &lt;del&gt;duckdns.org&lt;&#x2F;del&gt; Cloudflare DNS, since it has very fast TTL). See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;favonia&#x2F;cloudflare-ddns&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;favonia&#x2F;cloudflare-ddns&lt;&#x2F;a&gt;. Set it to update &lt;code&gt;ddns&lt;&#x2F;code&gt; CNAME.&lt;&#x2F;li&gt;
&lt;li&gt;Go to your domain name registrar, under DNS, add a CNAME record for your desired subdomain, and set the value to your DDNS  (example: &lt;code&gt;ddns.yourdomain.com&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;On your server, install a webserver for reverse-proxy. I recommend nginx or Caddy.&lt;&#x2F;li&gt;
&lt;li&gt;Create a virtual host config for your website in your webserver of choice.&lt;&#x2F;li&gt;
&lt;li&gt;On your router configuration page, under port forwarding, create two entries for port 80 and 443.&lt;&#x2F;li&gt;
&lt;li&gt;Wait for a few minutes for the DNS to be updated, and you should be able to access your website from the specified domain.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;As for actual implementation, I suggest you read a few articles for each step, so you can get the overall idea of what&#x27;s to be done. Generally, the common steps should be the same across all articles, since that&#x27;s the &quot;baseline&quot; for each process.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Python venv management</title>
          <pubDate>Fri, 02 Jul 2021 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2021/07/python-venv-management/</link>
          <guid>https://karnwong.me/posts/2021/07/python-venv-management/</guid>
          <description xml:base="https://karnwong.me/posts/2021/07/python-venv-management/">&lt;p&gt;&lt;strong&gt;Update 2023-09-09&lt;&#x2F;strong&gt;: I now revert back to plain &lt;code&gt;requirements.txt&lt;&#x2F;code&gt;, since pipenv is very poor at resolving large dependencies list. Poetry still remains funky so that&#x27;s off the table as well.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Update 2024-01-20&lt;&#x2F;strong&gt;: I&#x27;ve been using poetry in production for a few months now and so far it works great! Looks like they ironed out a lot of rough edges. Although I would still recommend people to use pre-commit to generate plain &lt;code&gt;requirements.txt&lt;&#x2F;code&gt;, this is so that in ci or dockerfile you don&#x27;t have to install poetry and set in-project venv every time.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;When you create a project in python, you should create &lt;code&gt;requirements.txt&lt;&#x2F;code&gt; to specify dependencies, so other people can have the same environment when using your project.&lt;&#x2F;p&gt;
&lt;p&gt;However, if you don’t specify module versions in &lt;code&gt;requirements.txt&lt;&#x2F;code&gt;, you could end up with people using the wrong module version, where some APIs can be deprecated or have different behaviors than older versions.&lt;&#x2F;p&gt;
&lt;p&gt;Another issue is that maybe you’re working on a few python projects, each uses different python versions (eg. projectA uses python3.6, projectB uses python3.9, etc).&lt;&#x2F;p&gt;
&lt;p&gt;Enter &lt;code&gt;pyenv&lt;&#x2F;code&gt; and &lt;code&gt;poetry&lt;&#x2F;code&gt; (&lt;code&gt;pipenv&lt;&#x2F;code&gt; is considered outdated now), where you can easily switch python versions, and have different environment (with python version locking) for projects you’re working on.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;setup-pyenv&quot;&gt;Setup pyenv&lt;a class=&quot;zola-anchor&quot; href=&quot;#setup-pyenv&quot; aria-label=&quot;Anchor link for: setup-pyenv&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Follow instructions &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;pyenv&#x2F;pyenv&quot;&gt;here&lt;&#x2F;a&gt;. For windows, use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;pyenv-win&#x2F;pyenv-win&quot;&gt;this&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;useful-commands&quot;&gt;Useful commands&lt;a class=&quot;zola-anchor&quot; href=&quot;#useful-commands&quot; aria-label=&quot;Anchor link for: useful-commands&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; list available python versions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pyenv&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; install&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-list&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; install specific version&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pyenv&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; install&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 3.8.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; list installed versions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pyenv&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; versions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; activate new env&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pyenv&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; shell&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 3.8.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; support multiple version&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; config venv&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pyenv&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; virtualenv&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 3.8.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; my-data-project&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; set env per folder&#x2F;project&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pyenv&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; local&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; my-data-project&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;setup-pipenv&quot;&gt;Setup &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;pypa&#x2F;pipenv&quot;&gt;pipenv&lt;&#x2F;a&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#setup-pipenv&quot; aria-label=&quot;Anchor link for: setup-pipenv&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;2024-01-20: See below for poetry, this only stays for reference only&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Notes: make sure &lt;code&gt;pyenv&lt;&#x2F;code&gt; is installed, and remove &lt;code&gt;anaconda &#x2F; miconda&lt;&#x2F;code&gt; &amp;amp; &lt;code&gt;python3&lt;&#x2F;code&gt; installed via official installer from your system. Then run:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; pip&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; install&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; pipenv&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; run this command every time pip installs a .exe&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; pyenv&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; rehash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;pipenv-workflow&quot;&gt;pipenv workflow&lt;a class=&quot;zola-anchor&quot; href=&quot;#pipenv-workflow&quot; aria-label=&quot;Anchor link for: pipenv-workflow&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pipenv&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-python&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 3.7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; install a specific module&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pipenv&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; install&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; jupyterlab==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2.2.9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; install from existing requirements.txt or from Pipfile definition&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pipenv&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; install&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; remove venv&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pipenv&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-rm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; running inside venv&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pipenv&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; run&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; jupyter&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; lab&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pipenv&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; run&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; python&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; main.py&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; is equivalent to `pipenv shell &amp;amp;&amp;amp; python3 main.py`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;windows-only&quot;&gt;Windows only&lt;a class=&quot;zola-anchor&quot; href=&quot;#windows-only&quot; aria-label=&quot;Anchor link for: windows-only&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;2024-01-20: See below for poetry, this only stays for reference only&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pyenv&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; install&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 3.7.7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; see Pipfile for required python version&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pyenv&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; local&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 3.7.7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; IMPORTANT. global &#x2F; shell doesn&amp;#39;t work with pipenv&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pyenv&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; rehash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pip&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; install&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; pipenv&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; done once per pyenv python version&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pyenv&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; rehash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pipenv&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-python&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 3.7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pipenv&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; install&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pipenv&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; run&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; python&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; tokenization_sandbox.py&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;setup-poetry&quot;&gt;Setup &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;python-poetry.org&#x2F;docs&#x2F;#installation&quot;&gt;poetry&lt;&#x2F;a&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#setup-poetry&quot; aria-label=&quot;Anchor link for: setup-poetry&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pipx&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; install&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; poetry&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;useful-commands-1&quot;&gt;Useful commands&lt;a class=&quot;zola-anchor&quot; href=&quot;#useful-commands-1&quot; aria-label=&quot;Anchor link for: useful-commands-1&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; init project&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;poetry&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; init&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; add deps&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;poetry&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; add&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; $&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;package&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; add dev dependencies&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;poetry&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; add&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; $&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;package&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-group&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; dev&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; activate venv&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;poetry&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; shell&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; specify python version&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;poetry&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; env&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; use&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 3.11&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt; #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; normally it picks up global python via pyenv&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;notes&quot;&gt;Notes&lt;a class=&quot;zola-anchor&quot; href=&quot;#notes&quot; aria-label=&quot;Anchor link for: notes&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;On linux&#x2F;mac, do not use system python. OS updates would mean python version upgrade, in turn making all your installed modules gone. Use python installed via pyenv instead.&lt;&#x2F;li&gt;
&lt;li&gt;On windows, start fresh with pyenv.&lt;&#x2F;li&gt;
&lt;li&gt;Do not use anaconda distribution. It does too much background magic that can make things harder to manage environment properly. In addition, venv definition from anaconda is often doesn’t work cross-platform (eg. venv def from windows wouldn’t work on mac due to different wheel binary versions).&lt;&#x2F;li&gt;
&lt;li&gt;Always create venv via pipenv per each project. Although you can have a playground venv via pyenv, so you can shell into it and do a quick analysis &#x2F; scripting on an adhoc basis.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;del&gt;I heard good things about &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;python-poetry&#x2F;poetry&quot;&gt;poetry&lt;&#x2F;a&gt; but it doesn’t integrate with &lt;code&gt;pyenv&lt;&#x2F;code&gt; natively. It would work if you use it to publish python modules, since it simplifies a lot of processes.&lt;&#x2F;del&gt;
&lt;ul&gt;
&lt;li&gt;&lt;del&gt;poetry also picks up the wrong python version from pyenv. And if you sync python version via pyenv, it has to be the same python version across all OSes, including minor version. pipenv doesn’t have this restriction, and it also picks up the correct python version from pyenv by default (via &lt;code&gt;pipenv --python 3.8&lt;&#x2F;code&gt;).&lt;&#x2F;del&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</description>
      </item>
      <item>
          <title>Don&#x27;t write large table to Postgres with Pandas</title>
          <pubDate>Sun, 27 Jun 2021 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2021/06/dont-write-large-table-to-postgres-with-pandas/</link>
          <guid>https://karnwong.me/posts/2021/06/dont-write-large-table-to-postgres-with-pandas/</guid>
          <description xml:base="https://karnwong.me/posts/2021/06/dont-write-large-table-to-postgres-with-pandas/">&lt;p&gt;We have a few tables where the data size is &amp;gt; 3GB (in parquet, so around 10 GB uncompressed). Loading it into postgres takes an hour. (Most of our tables are pretty small, hence the reason why we don&#x27;t use columnar database).&lt;&#x2F;p&gt;
&lt;p&gt;I want to explore whether there&#x27;s a faster way or not. The conclusion is writing to postgres with spark seems to be fastest, given we can&#x27;t use &lt;code&gt;COPY&lt;&#x2F;code&gt; since our data contain free text, which means it would make CSV parsing impossible.&lt;&#x2F;p&gt;
&lt;p&gt;I also found out that the write performance from pandas to postgres is excruciatingly slow because:
It first decompresses the data in-memory. For a 30MB parquet (around 100MB uncompressed) it used more than 20GB of RAM (I killed the task before it finishes, since by this time the RAM usage is climbing up)&lt;&#x2F;p&gt;
&lt;p&gt;But even with reading plain JSON line in pandas with chunksize and use &lt;code&gt;to_sql&lt;&#x2F;code&gt; with &lt;code&gt;multi&lt;&#x2F;code&gt; option, it&#x27;s still very slow.&lt;&#x2F;p&gt;
&lt;p&gt;In contrast, writing the said 30MB parquet file to postgres takes only 1 minute.&lt;&#x2F;p&gt;
&lt;p&gt;Big data is fun, said data scientists 🧪 (until they run out of RAM 😆)&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Data engineering toolset (that I use) glossary</title>
          <pubDate>Fri, 04 Jun 2021 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2021/06/data-engineering-toolset-that-i-use-glossary/</link>
          <guid>https://karnwong.me/posts/2021/06/data-engineering-toolset-that-i-use-glossary/</guid>
          <description xml:base="https://karnwong.me/posts/2021/06/data-engineering-toolset-that-i-use-glossary/">&lt;h2 id=&quot;big-data&quot;&gt;Big data&lt;a class=&quot;zola-anchor&quot; href=&quot;#big-data&quot; aria-label=&quot;Anchor link for: big-data&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Spark: Map-reduce framework for dealing with big data, especially for data that doesn&#x27;t fit into memory. Utilizes parallelization.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;cloud&quot;&gt;Cloud&lt;a class=&quot;zola-anchor&quot; href=&quot;#cloud&quot; aria-label=&quot;Anchor link for: cloud&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;AWS: Cloud platform for many tools used in software engineering.&lt;&#x2F;li&gt;
&lt;li&gt;AWS Fargate: A task launch mode for &lt;code&gt;ECS task&lt;&#x2F;code&gt;, where it automatically shuts down once a container exits. With EC2 launch mode, you&#x27;ll have to turn off the machine yourself.&lt;&#x2F;li&gt;
&lt;li&gt;AWS Lambda: Serverless function, can be used with docker image too. Can also hook this with API gateway to make it act as API endpoint.&lt;&#x2F;li&gt;
&lt;li&gt;AWS RDS: Managed databases from AWS.&lt;&#x2F;li&gt;
&lt;li&gt;ECS Task: Launch a task in ECS cluster. For long-running services, launch via EC2. For small periodical tasks, trigger via Cloudwatch. For the latter, think of cron-like schedule for a task. Essentially at specified time, it runs a predefined docker image (you should configure your &lt;code&gt;entrypoint.sh&lt;&#x2F;code&gt; accordingly).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;data&quot;&gt;Data&lt;a class=&quot;zola-anchor&quot; href=&quot;#data&quot; aria-label=&quot;Anchor link for: data&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Parquet: Columnar data blob format, very efficient due to column-based compression with schema definition baked in.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;data-engineering&quot;&gt;Data engineering&lt;a class=&quot;zola-anchor&quot; href=&quot;#data-engineering&quot; aria-label=&quot;Anchor link for: data-engineering&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Dagster: Task orchestration framework with built-in pipelines validation.&lt;&#x2F;li&gt;
&lt;li&gt;ETL: Stands for extract-transform-load. Essentially it means &quot;moving data from A to B, with optional data wrangling in the middle.&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;data-science&quot;&gt;Data science&lt;a class=&quot;zola-anchor&quot; href=&quot;#data-science&quot; aria-label=&quot;Anchor link for: data-science&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;NLP: Using machine (computer) to work on human languages. For instance, analyze whether a message is positive or negative.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;data-wrangling&quot;&gt;Data wrangling&lt;a class=&quot;zola-anchor&quot; href=&quot;#data-wrangling&quot; aria-label=&quot;Anchor link for: data-wrangling&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Pandas: Dataframe wrangler, think of programmable Excel.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;database&quot;&gt;Database&lt;a class=&quot;zola-anchor&quot; href=&quot;#database&quot; aria-label=&quot;Anchor link for: database&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Postgres: RMDBS with good performance.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;dataops&quot;&gt;DataOps&lt;a class=&quot;zola-anchor&quot; href=&quot;#dataops&quot; aria-label=&quot;Anchor link for: dataops&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Great expectations: A framework for data validation.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;devops&quot;&gt;DevOps&lt;a class=&quot;zola-anchor&quot; href=&quot;#devops&quot; aria-label=&quot;Anchor link for: devops&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Docker: Virtualization via containers.&lt;&#x2F;li&gt;
&lt;li&gt;Git: Version control.&lt;&#x2F;li&gt;
&lt;li&gt;Kubernetes: Container orchestration system.&lt;&#x2F;li&gt;
&lt;li&gt;Terraform: Infrastructure as code tool, essentially you use it to store a blueprint for your infra setup. If you were to move to another account, you can re-conjure existing infra with one command. This makes editing infra config easier too, since it automatically cleans up &#x2F; update config automatically.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;gis&quot;&gt;GIS&lt;a class=&quot;zola-anchor&quot; href=&quot;#gis&quot; aria-label=&quot;Anchor link for: gis&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;PostGIS: GIS extension for Postgres.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;mlops&quot;&gt;MLOps&lt;a class=&quot;zola-anchor&quot; href=&quot;#mlops&quot; aria-label=&quot;Anchor link for: mlops&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;MLflow: A framework to track model parameters and output. Can also store model artifact as well.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;notebook&quot;&gt;Notebook&lt;a class=&quot;zola-anchor&quot; href=&quot;#notebook&quot; aria-label=&quot;Anchor link for: notebook&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Jupyter: Python notebook, used for exploring solutions before converting it to .py.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</description>
      </item>
      <item>
          <title>Automatic Scrapy deployment with GitHub actions</title>
          <pubDate>Wed, 02 Jun 2021 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2021/06/automatic-scrapy-deployment-with-github-actions/</link>
          <guid>https://karnwong.me/posts/2021/06/automatic-scrapy-deployment-with-github-actions/</guid>
          <description xml:base="https://karnwong.me/posts/2021/06/automatic-scrapy-deployment-with-github-actions/">&lt;p&gt;Repo &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kahnwong&#x2F;scrapy-deploy-gh-actions&quot;&gt;here&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Scrapy is a nice framework for web scraping. But like all local development processes, some settings &#x2F; configs are disabled.&lt;&#x2F;p&gt;
&lt;p&gt;This wouldn&#x27;t pose an issue, but to deploy a scrapy project to zyte (a hosted scrapy platform) you need to run &lt;code&gt;shub deploy&lt;&#x2F;code&gt;, and if you run it and forget to reset the config back to prod settings, a Titan may devour your home.&lt;&#x2F;p&gt;
&lt;p&gt;You can set auto deployment from github via the UI in zyte, but it only works with github only. Plus if you want to run some extra tests during CI&#x2F;CD you&#x27;re out of luck. So here&#x27;s how to set up CI&#x2F;CD to deploy automatically:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;&#x2F;strong&gt;: I would assume that you have your scrapy project set up already.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;create-scrapinghub-yml-add-repo-secrets&quot;&gt;Create scrapinghub.yml + add repo secrets&lt;a class=&quot;zola-anchor&quot; href=&quot;#create-scrapinghub-yml-add-repo-secrets&quot; aria-label=&quot;Anchor link for: create-scrapinghub-yml-add-repo-secrets&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;roject&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; $&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;{PROJECT_ID}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;equirements&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  f&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ile&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;equirements.txt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;tack&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;crapy:${YOUR_SCRAPY_VERSION_IN_PIPFILE}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;pikey&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; null&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Notice that &lt;code&gt;apikey&lt;&#x2F;code&gt; is left blank. This is because it&#x27;s considered a good practice to not check in sensitive information &amp;amp; credentials in version control. Instead &lt;code&gt;apikey&lt;&#x2F;code&gt; will be added to github secrets, so it can be called as environment variable.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;create-github-workflow-file&quot;&gt;Create github workflow file&lt;a class=&quot;zola-anchor&quot; href=&quot;#create-github-workflow-file&quot; aria-label=&quot;Anchor link for: create-github-workflow-file&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; D&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eploy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-constant&quot;&gt;on&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  p&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ush&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    b&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ranches&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;aster&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ain&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;j&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;obs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  d&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;eploy&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    r&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;uns-on&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;buntu-latest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;    s&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;teps&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;      -&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ses&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ctions&#x2F;checkout@v2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;      -&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; S&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;et up Python 3.9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;        u&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ses&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ctions&#x2F;setup-python@v2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;        w&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ith&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;          p&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ython-version&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 3.9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;      -&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; I&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;nstall dependencies&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;        r&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;un&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;          python -m pip install --upgrade pip&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;          pip install pyyaml shub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;      -&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ame&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; D&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;eploy to zyte&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;        i&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; g&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ithub.ref == &amp;#39;refs&#x2F;heads&#x2F;master&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;        r&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;un&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ython3 utils&#x2F;edit_deploy_config.py &amp;amp;&amp;amp; shub deploy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;        e&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;nv&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;          A&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;PIKEY&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; $&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;{{ secrets.APIKEY }}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Translation:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;On push to this repo (this doesn&#x27;t work for PRs)&lt;&#x2F;li&gt;
&lt;li&gt;Download this repo&lt;&#x2F;li&gt;
&lt;li&gt;Setup python3.9&lt;&#x2F;li&gt;
&lt;li&gt;Install some pip modules&lt;&#x2F;li&gt;
&lt;li&gt;Run a script to overwrite scrapinghub.yml&#x27;s apikey value, in which the value is obtained from github secrets&lt;&#x2F;li&gt;
&lt;li&gt;Execute deploy command&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</description>
      </item>
      <item>
          <title>Elasticsearch with custom dictionary</title>
          <pubDate>Mon, 03 May 2021 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2021/05/elasticsearch-with-custom-dictionary/</link>
          <guid>https://karnwong.me/posts/2021/05/elasticsearch-with-custom-dictionary/</guid>
          <description xml:base="https://karnwong.me/posts/2021/05/elasticsearch-with-custom-dictionary/">&lt;p&gt;Elasticsearch is a search engine with built-in analyzers (combination of tokenizer and filters), which makes it easier to set it up and get it running, seeing you don’t have to implement NLP logic from scratch. However, for some languages such as Thai, the built-in Thai analyzer may not be working quite as expected.&lt;&#x2F;p&gt;
&lt;p&gt;For instance, for region name search autocomplete, it doesn’t recommend anything when I type &lt;code&gt;เชียง&lt;&#x2F;code&gt;, but it should be showing &lt;code&gt;เชียงใหม่&lt;&#x2F;code&gt; or &lt;code&gt;เชียงราย&lt;&#x2F;code&gt;. This is because these two regions are recognized as one token, which is why it doesn’t recommend anything when querying with &lt;code&gt;เชียง&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;But if I create a custom dictionary for tokenizers with &lt;code&gt;เชียง&lt;&#x2F;code&gt; as one of the tokens, it manages to recommend the two regions when querying with the prefix.&lt;&#x2F;p&gt;
&lt;p&gt;Below is an &lt;code&gt;index_config&lt;&#x2F;code&gt; for using a custom dictionary for tokenizer:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;settings&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;analysis&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;analyzer&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;thai_dictionary&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;tokenizer&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;standard&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;filter&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;char_limit_dictionary&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;filter&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;char_limit_dictionary&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;dictionary_decompounder&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;word_list&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; tokens&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &amp;lt;-- word list array here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;max_subword_size&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 22&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;mappings&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;properties&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; &amp;lt;-- search key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;text&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;analyzer&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;thai_dictionary&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;See elasticsearch documentation for more details: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.elastic.co&#x2F;guide&#x2F;en&#x2F;elasticsearch&#x2F;reference&#x2F;7.12&#x2F;analysis-dict-decomp-tokenfilter.html&quot;&gt;https:&#x2F;&#x2F;www.elastic.co&#x2F;guide&#x2F;en&#x2F;elasticsearch&#x2F;reference&#x2F;7.12&#x2F;analysis-dict-decomp-tokenfilter.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Shapefile to data lake</title>
          <pubDate>Fri, 23 Apr 2021 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2021/04/shapefile-to-data-lake/</link>
          <guid>https://karnwong.me/posts/2021/04/shapefile-to-data-lake/</guid>
          <description xml:base="https://karnwong.me/posts/2021/04/shapefile-to-data-lake/">&lt;p&gt;&lt;strong&gt;Background&lt;&#x2F;strong&gt;: we use spark to read&#x2F;write to data lake. For dealing with spatial data &amp;amp; analysis, we use &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;sedona.apache.org&quot;&gt;sedona&lt;&#x2F;a&gt;. Shapefile is converted to TSV then read by spark for further processing &amp;amp; archival.&lt;&#x2F;p&gt;
&lt;p&gt;Recently I had to archive shapefiles in our data lake. It wasn&#x27;t rosy for the following reasons:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;invalid-geometries&quot;&gt;Invalid geometries&lt;a class=&quot;zola-anchor&quot; href=&quot;#invalid-geometries&quot; aria-label=&quot;Anchor link for: invalid-geometries&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Sedona (and geopandas too) whines if it encounters &lt;code&gt;invalid geometry&lt;&#x2F;code&gt; during geometry casting. The invalid geometries could be from many reasons, one of them being unclean polygon clipping.&lt;&#x2F;p&gt;
&lt;p&gt;Solution: use &lt;code&gt;gdal&lt;&#x2F;code&gt; to filter out invalid geometries.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;spatial-projection&quot;&gt;Spatial projection&lt;a class=&quot;zola-anchor&quot; href=&quot;#spatial-projection&quot; aria-label=&quot;Anchor link for: spatial-projection&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Geometric projections requires &lt;code&gt;projection&lt;&#x2F;code&gt;, otherwise you could be on the wrong side of the globe. This matters because by default, the worldwide-coverage projection is &lt;code&gt;EPSG:4326&lt;&#x2F;code&gt;, but the unit is in &lt;code&gt;degrees&lt;&#x2F;code&gt;, so sometimes for analysis the data is converted to a local projection which covers a smaller geographical region, but uses &lt;code&gt;meter&lt;&#x2F;code&gt; as the unit.&lt;&#x2F;p&gt;
&lt;p&gt;This means that if the source projection is in &lt;code&gt;A&lt;&#x2F;code&gt;, and you didn&#x27;t cast it to &lt;code&gt;EPSG:4326&lt;&#x2F;code&gt;, spark would mistakenly think it&#x27;s on &lt;code&gt;EPSG:4326&lt;&#x2F;code&gt; by default. Something like seeing the entirely of the UK in Africa.&lt;&#x2F;p&gt;
&lt;p&gt;Solution: verify the source projection and cast to &lt;code&gt;EPSG:4326&lt;&#x2F;code&gt; before writing to data lake.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;extra-new-line-character&quot;&gt;Extra new line character&lt;a class=&quot;zola-anchor&quot; href=&quot;#extra-new-line-character&quot; aria-label=&quot;Anchor link for: extra-new-line-character&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Sometimes when editing shapefile data by hand using applications like ArcGIS or QGIS, you could copy a text which might contain &quot;new line&quot; character, and set it as a cell value. Spark doesn&#x27;t play nice with &quot;new line&quot; characters in a middle of a record.&lt;&#x2F;p&gt;
&lt;p&gt;Solution: strip new line characters by hand.&lt;&#x2F;p&gt;
&lt;p&gt;Yes, I really did that 😶. Thankfully it was a very small shapefile that has the issue.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Takeaways&lt;&#x2F;strong&gt;: count yourself lucky if you never have to deal with spatial data.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Spark join OOM fix</title>
          <pubDate>Sun, 11 Apr 2021 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2021/04/spark-join-oom-fix/</link>
          <guid>https://karnwong.me/posts/2021/04/spark-join-oom-fix/</guid>
          <description xml:base="https://karnwong.me/posts/2021/04/spark-join-oom-fix/">&lt;p&gt;I have a big pipelines where one step performs crossjoin on &lt;code&gt;130K x 7K&lt;&#x2F;code&gt;. It fails quite often, and I have to pray to the Rice God for it to pass. Today I found the solution: &lt;code&gt;repartition&lt;&#x2F;code&gt; before crossjoin.&lt;&#x2F;p&gt;
&lt;p&gt;The root cause is that the dataframe with 130K records has 6 partitions, so when I perform crossjoin (one-to-many) it&#x27;s working against those 6 partitions. Total output in parquet is around 350MB, which means my computer (8 cores, 10GB RAM provisioned for spark) needs to be able to hold all uncompressed data in memory. It couldn&#x27;t hence the frequent OOM.&lt;&#x2F;p&gt;
&lt;p&gt;So by increasing the partition size from 6 to 24, the current working dataframe size is smaller, which means things could pass along faster while not filling up my machine&#x27;s RAM.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Add Ghost content to Hugo</title>
          <pubDate>Wed, 31 Mar 2021 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2021/03/create-static-site-from-ghost-blog/</link>
          <guid>https://karnwong.me/posts/2021/03/create-static-site-from-ghost-blog/</guid>
          <description xml:base="https://karnwong.me/posts/2021/03/create-static-site-from-ghost-blog/">&lt;p&gt;Ghost CMS is very easy to use, but the deployment overhead (maintaining db, ghost version, updates and etc) might be too much for some. Luckily, there&#x27;s a way to convert a Ghost site to static pages, which you can later host on Github pages or something similar.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;setup&quot;&gt;Setup&lt;a class=&quot;zola-anchor&quot; href=&quot;#setup&quot; aria-label=&quot;Anchor link for: setup&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;static site engine: Hugo&lt;&#x2F;li&gt;
&lt;li&gt;a Ghost instance&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;usage&quot;&gt;Usage&lt;a class=&quot;zola-anchor&quot; href=&quot;#usage&quot; aria-label=&quot;Anchor link for: usage&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Install &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Fried-Chicken&#x2F;ghost-static-site-generator&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;Fried-Chicken&#x2F;ghost-static-site-generator&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;cd&lt;&#x2F;code&gt; to &lt;code&gt;static&lt;&#x2F;code&gt; directory in your Hugo folder&lt;&#x2F;li&gt;
&lt;li&gt;run&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;gssg&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-domain&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt; $&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;YOUR_GHOST_INSTANCE_URL&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-dest&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; posts&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-url&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt; $&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;YOUR_STATIC_SITE_DOMAIN_WITHOUT_TRAILING_SLASH&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-subDir&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; posts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;Update your hugo config to link to the above folder:&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;toml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[[&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-section&quot;&gt;menu&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-section&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;]]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    identifier&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;posts&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;       =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Posts&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable&quot;&gt;    url&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value&quot;&gt;        =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;posts&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;All done! 🎉🎉🎉&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Hello Caddy</title>
          <pubDate>Sun, 07 Mar 2021 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2021/03/hello-caddy/</link>
          <guid>https://karnwong.me/posts/2021/03/hello-caddy/</guid>
          <description xml:base="https://karnwong.me/posts/2021/03/hello-caddy/">&lt;p&gt;Since starting self-hosting back in 2017, I&#x27;ve always used apache2 since it&#x27;s the first webserver I came across. Over time adding more services and managing separate vhost config is a bit tiresome.&lt;&#x2F;p&gt;
&lt;p&gt;Enter Caddy. It&#x27;s very simple to set up and configure. Some services where I have trouble setting up in apache2 do not need extra config at all, even TLS is set up by default. Starting from Caddy2 it works with CNAME by default without extra setups.&lt;&#x2F;p&gt;
&lt;p&gt;You can set it up using a Caddy docker container, but some containers I use also expose port 443, so I have to install Caddy natively instead.&lt;&#x2F;p&gt;
&lt;p&gt;For multiple sites config setup:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# &#x2F;etc&#x2F;caddy&#x2F;Caddyfile&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SUBDOMAIN1.DOMAIN.com {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    reverse_proxy 127.0.0.1:${PORT}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SUBDOMAIN2.DOMAIN.com {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    reverse_proxy 127.0.0.1:${PORT}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For basic authentication, it&#x27;s very, very simple (to the point I regret time researching it in apache2):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# generate password hash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;caddy hash-password --algorithm bcrypt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# add basicauth to Caddyfile&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SUBDOMAIN1.DOMAIN.com {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    basicauth * {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ${USERNAME} ${CADDY_PASSWORD_HASH}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    reverse_proxy 127.0.0.1:${PORT}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And run &lt;code&gt;systemctl reload caddy&lt;&#x2F;code&gt;. You&#x27;re all set!&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Password auth with apache2 reverse-proxy</title>
          <pubDate>Mon, 22 Feb 2021 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2021/02/setting-up-password-auth-with-apache2-reverse-proxy/</link>
          <guid>https://karnwong.me/posts/2021/02/setting-up-password-auth-with-apache2-reverse-proxy/</guid>
          <description xml:base="https://karnwong.me/posts/2021/02/setting-up-password-auth-with-apache2-reverse-proxy/">&lt;p&gt;EDIT: see &lt;a href=&quot;&#x2F;posts&#x2F;2021&#x2F;03&#x2F;hello-caddy&quot;&gt;here&lt;&#x2F;a&gt; for Caddy, also easier to set up too.&lt;&#x2F;p&gt;
&lt;p&gt;Sometimes you found an interesting project to self-hosted, but it doesn&#x27;t have password authentication built-in. Luckily, we need to reverse-proxy them anyway and apache2&#x2F; nginx &#x2F; httpd happen to provide password auth with reverse-proxy by default.&lt;&#x2F;p&gt;
&lt;p&gt;To set up password auth with apache2 via reverse-proxy:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;echo &quot;${PASSWORD}&quot; | htpasswd -c -i &#x2F;etc&#x2F;apache2&#x2F;.htpasswd ${USER}&lt;&#x2F;code&gt; on your host machine which has apache2 installed.&lt;&#x2F;li&gt;
&lt;li&gt;create a vhost config:&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;VirtualHost&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt; *:80&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ProxyPreserveHost On&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ProxyPass &#x2F; http:&#x2F;&#x2F;localhost:${EXPOSED_CONTAINER_PORT}&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ProxyPassReverse &#x2F; http:&#x2F;&#x2F;localhost:${EXPOSED_CONTAINER_PORT}&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ServerName ${YOUR_DOMAIN}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;Proxy&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        Order deny,allow&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        Allow from all&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        Authtype Basic&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        Authname &amp;quot;Password Required&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        AuthUserFile &#x2F;etc&#x2F;apache2&#x2F;.htpasswd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        Require valid-user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;    &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;Proxy&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;virtualhost&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That&#x27;s it!&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Buying tea when you have Celiac</title>
          <pubDate>Sun, 14 Feb 2021 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2021/02/buying-tea-when-you-have-celiac/</link>
          <guid>https://karnwong.me/posts/2021/02/buying-tea-when-you-have-celiac/</guid>
          <description xml:base="https://karnwong.me/posts/2021/02/buying-tea-when-you-have-celiac/">&lt;p&gt;Might come as a surprise to some of you, but tea &lt;em&gt;can&lt;&#x2F;em&gt; contain gluten from additives &amp;amp; cross-contamination, in which barley or malt is added for flavorings. Teavana is known for adding such additives in their tea (and I got glutented from it one time).&lt;&#x2F;p&gt;
&lt;p&gt;Say, I&#x27;m interested in some tea. I first need to look up its country of origin, because that tells me about how good the food labeling laws is. If it&#x27;s from Australia &#x2F; New Zealand, this means the label will always state gluten. If it&#x27;s from EU (not pan-Europe) it&#x27;s also good, except they allow products with &amp;lt; 20 PPM to be labeled gluten-free. But this is still good. If it&#x27;s from USA, a lot of scrutiny is called because the US FDA does not enforce gluten labeling, only wheat is required. But not all gluten-y stuff is wheat :&#x2F;&lt;&#x2F;p&gt;
&lt;p&gt;In this case, I&#x27;m interested in Turkish tea. So I asked a Turkish friend to do some digging for me on the manufacturer&#x27;s website, since I couldn&#x27;t find the info in English. He reported that he didn&#x27;t find any info about gluten on the website, but he send me a photo of the package where the ingredients are listed. I spotted German on the labels, this is a good sign because it means this product is also sold in Germany, and food labels have to comply with the country it&#x27;s being sold in too*.&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s pretty much end of story. Ordered the tea and brew it. Tastes very good!&lt;&#x2F;p&gt;
&lt;p&gt;*Thank you a local Thai QA who told me about this 🙏&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Workarounds for archiving large shapefile in data lake</title>
          <pubDate>Sun, 31 Jan 2021 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2021/01/workarounds-for-archiving-large-shapefile-in-data-lake/</link>
          <guid>https://karnwong.me/posts/2021/01/workarounds-for-archiving-large-shapefile-in-data-lake/</guid>
          <description xml:base="https://karnwong.me/posts/2021/01/workarounds-for-archiving-large-shapefile-in-data-lake/">&lt;p&gt;If you work with spatial data, chances are you are familiar with &lt;code&gt;shapefile&lt;&#x2F;code&gt;, a file format for viewing &#x2F; editing spatial data.&lt;&#x2F;p&gt;
&lt;p&gt;Essentially, shapefile is just a tabular data like &lt;code&gt;csv&lt;&#x2F;code&gt;, but it does thingamajig with &lt;code&gt;geometry&lt;&#x2F;code&gt; data type, where any gis tools like &lt;code&gt;qgis&lt;&#x2F;code&gt; or &lt;code&gt;arcgis&lt;&#x2F;code&gt; can understand right away. If you have a csv file with geometry column in &lt;code&gt;wkt&lt;&#x2F;code&gt; format (something like &lt;code&gt;POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))&lt;&#x2F;code&gt;), you&#x27;ll have to specify which column is to be used for geometry.&lt;&#x2F;p&gt;
&lt;p&gt;If you want to store shapefile in data lake, it&#x27;s best to store it as parquet or any format you normally use, since it&#x27;s faster to read and filter. For comparison, parsing a 5GB+ shapefile and filter takes &lt;em&gt;longer&lt;&#x2F;em&gt; than reading a gzipped json, filter, and export to shapefile.&lt;&#x2F;p&gt;
&lt;p&gt;Normally I would use &lt;code&gt;geopandas&lt;&#x2F;code&gt; to read spatial data and convert it to pandas dataframe, then send it to spark. But since the shapefile is very large, it takes forever to read in geopandas. This tells me that there is a parsing bottleneck going on. And geopandas can&#x27;t read shapefile with multiple geometry types (this shouldn&#x27;t happen, but sometimes during editing, clipping this here and there can cause invalid geometry).&lt;&#x2F;p&gt;
&lt;p&gt;Qgis has a tool to fix invalid geometries, so I tried exporting shapefile to csv, but qgis went OOM. But both qgis and geopandas use &lt;code&gt;gdal&lt;&#x2F;code&gt; for backend, and it has a CLI interface, so I look up how to export shapefile to tsv (&lt;code&gt;tab&lt;&#x2F;code&gt; as a separator makes it faster to parse since it rarely occurs).&lt;&#x2F;p&gt;
&lt;p&gt;Now things work perfectly. As a bonus, gdal also skip invalid geometries by default (unlike in geopandas where it will throw an error and there&#x27;s no way to ignore it and tell the parser to keep going).&lt;&#x2F;p&gt;
&lt;p&gt;At this point I have a nice tsv file, and reading &amp;amp; archiving via spark is now a breeze. Yay!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;takeaway&quot;&gt;Takeaway&lt;a class=&quot;zola-anchor&quot; href=&quot;#takeaway&quot; aria-label=&quot;Anchor link for: takeaway&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;If it takes too long to read, maybe it&#x27;s a parsing bottleneck. Find a way to convert it to another format so it&#x27;s easier to parse.&lt;&#x2F;li&gt;
&lt;li&gt;Sometimes your initial tools of choice might have some quirks. In most cases there will be similar tools out there that can workaround the issues. (In this case, use gdal to convert to csv in lieu of geopandas because gpd can&#x27;t work with invalid geometries &amp;amp; takes longer to read compared to feeding spark a straight csv&#x2F;tsv).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</description>
      </item>
      <item>
          <title>Mongodb export woes</title>
          <pubDate>Wed, 27 Jan 2021 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2021/01/mongodb-export-woes/</link>
          <guid>https://karnwong.me/posts/2021/01/mongodb-export-woes/</guid>
          <description xml:base="https://karnwong.me/posts/2021/01/mongodb-export-woes/">&lt;p&gt;There&#x27;s a task where I need to export 4M+ records out of mongodb, total uncompressed size is &lt;del&gt;17GB+&lt;&#x2F;del&gt; 26GB&lt;&#x2F;p&gt;
&lt;h2 id=&quot;export-methods&quot;&gt;export methods&lt;a class=&quot;zola-anchor&quot; href=&quot;#export-methods&quot; aria-label=&quot;Anchor link for: export-methods&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;mongoexport&quot;&gt;mongoexport&lt;a class=&quot;zola-anchor&quot; href=&quot;#mongoexport&quot; aria-label=&quot;Anchor link for: mongoexport&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;The recommended way to export is using &lt;code&gt;mongoexport&lt;&#x2F;code&gt; utility, but you have to specify the output attributes, which doesn&#x27;t work for me because the schema from older set of records are less than the newer set&lt;&#x2F;p&gt;
&lt;h3 id=&quot;diy-python-script&quot;&gt;DIY python script&lt;a class=&quot;zola-anchor&quot; href=&quot;#diy-python-script&quot; aria-label=&quot;Anchor link for: diy-python-script&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;the-vanilla-way&quot;&gt;the vanilla way&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-vanilla-way&quot; aria-label=&quot;Anchor link for: the-vanilla-way&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h4&gt;
&lt;p&gt;But you can interact with mongodb from python, and if you read from it it&#x27;ll return a dict, which is perfect for this because you don&#x27;t have to specify the required attributes beforehand. So what I do is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cursor&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; collection&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;find&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;total_records&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; collection&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;estimated_document_count&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;with&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; open&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;filename&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;w&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; f&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; tqdm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;cursor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; total&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;total_records&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;write&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;json&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;dumps&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; default&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;myconverter&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; ensure_ascii&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;False&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;write&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The cons for this solution is it needs a lot of hdd space since it&#x27;s uncompressed. But it &lt;strong&gt;works best if you need to export a collection with mismatched schema&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;the-incremental-export-way&quot;&gt;the incremental export way&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-incremental-export-way&quot; aria-label=&quot;Anchor link for: the-incremental-export-way&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h4&gt;
&lt;p&gt;You can also incrementally export your collection from mongodb using &lt;code&gt;.skip($START_INDEX).limit($INCREMENT_SIZE)&lt;&#x2F;code&gt; , but it &lt;strong&gt;performs worse than the vanilla way&lt;&#x2F;strong&gt;, since what mongodb does is just iterating through everything all over again to get to your specified &lt;code&gt;start:end&lt;&#x2F;code&gt; index.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;performance-comparison&quot;&gt;Performance comparison&lt;a class=&quot;zola-anchor&quot; href=&quot;#performance-comparison&quot; aria-label=&quot;Anchor link for: performance-comparison&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;On my local machine (&amp;lt;10 MB&#x2F;s transfer speed) I could export a collection with around 4.5M records within 1 hour, but on a VPS with incremental export it takes 9 hours and counting.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;takeaway&quot;&gt;Takeaway&lt;a class=&quot;zola-anchor&quot; href=&quot;#takeaway&quot; aria-label=&quot;Anchor link for: takeaway&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Please do not store a large dataset in mongodb where you need to dump everything out, especially if you use it as a raw data source. It&#x27;s fine if you store prepped output for API to be queried via &lt;code&gt;_id&lt;&#x2F;code&gt; (primary key).&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>CPU upgrade is a breeze, only if you know how</title>
          <pubDate>Sun, 20 Dec 2020 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2020/12/upgrading-cpu-is-hard/</link>
          <guid>https://karnwong.me/posts/2020/12/upgrading-cpu-is-hard/</guid>
          <description xml:base="https://karnwong.me/posts/2020/12/upgrading-cpu-is-hard/">&lt;p&gt;I want to update my pc config to use a more powerful cpu (from Ryzen 1300x --&amp;gt; Ryzen 3600). Watched a few videos and it didn&#x27;t look complicated enough, so I order the new CPU and plan to install it myself. Things didn&#x27;t go exactly to plan. To sum up relevant things I didn&#x27;t know from watching &quot;how to install AM4 CPU&quot; videos:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;on some motherboard, you need to &quot;support&quot; the backplate from under the motherboard so the socket would protrude far up enough to &quot;lock&quot; the CPU fan.&lt;&#x2F;li&gt;
&lt;li&gt;even if ab350 says it supports Ryzen 3rd generation CPUs after flashing the supported BIOS version, it  is &lt;em&gt;not&lt;&#x2F;em&gt; a given that it will work --&amp;gt; I end up upgrading my motherboard to b450&lt;&#x2F;li&gt;
&lt;li&gt;if you boot Windows after changing CPU &#x2F; GPU, it won&#x27;t boot --&amp;gt; have to reset CMOS&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Of course, I didn&#x27;t figure all this out myself. I took the pc to a local repair shop to install the CPU fan but it didn&#x27;t POST. We thought it&#x27;s the from the CPU pins I accidentally bent and maybe I screw it up when I straighten it back.&lt;&#x2F;p&gt;
&lt;p&gt;But it&#x27;s still within 7 days of purchase, so I took it to the retailer for a claim, only to find out that it works. The tech ask me which motherboard I have, only then it hit them that I need to upgrade the motherboard.&lt;&#x2F;p&gt;
&lt;p&gt;Then I took it back to a repair shop to install the new motherboard + CPU, but it still doesn&#x27;t POST. Figured it out later that you need to reset CMOS.&lt;&#x2F;p&gt;
&lt;p&gt;The &quot;how to install AM4 CPU&quot; didn&#x27;t lie or anything, it&#x27;s just that all the above points are &quot;basic knowledge&quot; for everyone who works on pc hardware should know. It&#x27;s the same as &quot;try a newly installed CLI from a new terminal session&quot; &amp;lt;– because your shell pre-index executables when it inits a session.&lt;&#x2F;p&gt;
&lt;p&gt;Takeaway: don&#x27;t underestimate domain knowledge basics.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>There are caveats behind every statement</title>
          <pubDate>Tue, 01 Dec 2020 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2020/12/there-are-caveats-behind-every-statement/</link>
          <guid>https://karnwong.me/posts/2020/12/there-are-caveats-behind-every-statement/</guid>
          <description xml:base="https://karnwong.me/posts/2020/12/there-are-caveats-behind-every-statement/">&lt;p&gt;You may have come across news headlines with something like &quot;woman diagnoses herself with rare disease.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;If you take this statement at face value, you might think &quot;hmmm so this woman, out of the blue, just diagnose herself with a rare disease.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;What most people don&#x27;t often realize is that for a rare disease to be considered, she must have gone through many different doctors who diagnosed her with various diseases, but she feels that neither of them accurately describe her symptoms. She might do some research, and came across a rare disease that perfectly describe her symptoms.&lt;&#x2F;p&gt;
&lt;p&gt;A more accurate (but more verbose) headline would be &quot;doctors failed to accurately diagnose woman with rare disease&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;Takeaway? Think twice before taking anything at face value.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Visualizing map region prefix&#x2F;suffix</title>
          <pubDate>Thu, 03 Sep 2020 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2020/09/visualizing-map-region-prefix-suffix/</link>
          <guid>https://karnwong.me/posts/2020/09/visualizing-map-region-prefix-suffix/</guid>
          <description xml:base="https://karnwong.me/posts/2020/09/visualizing-map-region-prefix-suffix/">&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; geopandas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; gpd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; geoplot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; gplt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; matplotlib&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;pyplot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; plt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; numpy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; np&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; pandas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; pd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; geoplot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; polyplot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; pythainlp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tokenize&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; syllable_tokenize&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; word_tokenize&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;data-structure&quot;&gt;Data structure&lt;a class=&quot;zola-anchor&quot; href=&quot;#data-structure&quot; aria-label=&quot;Anchor link for: data-structure&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;name&lt;&#x2F;strong&gt;: target region name&lt;&#x2F;li&gt;
&lt;li&gt;geometry: spatial column&lt;&#x2F;li&gt;
&lt;li&gt;*: parent region name, e.g. in &quot;district&quot; dataset it would have a &quot;province&quot; column&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;dissolving-dataset-in-case-you-have-multiple-region-level-in-the-same-file&quot;&gt;Dissolving dataset in case you have multiple region level in the same file&lt;a class=&quot;zola-anchor&quot; href=&quot;#dissolving-dataset-in-case-you-have-multiple-region-level-in-the-same-file&quot; aria-label=&quot;Anchor link for: dissolving-dataset-in-case-you-have-multiple-region-level-in-the-same-file&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# assuming you have a district dataset and want to dissolve to province only&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;district_filename&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;FILE_PATH_HERE&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gdf&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; gpd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;read_file&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;district_filename&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;used_columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;province&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;district&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gdf&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; gdf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;rename&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;    columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;prov_namt&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;upper&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;province&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; change to dummy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;amp_namt&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;upper&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;district&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gdf&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; gdf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;used_columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;geometry&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# desired data 🛎🛎🛎 please do create a datasest with outermost region, so we can use it as boundary for visualization&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;province&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; gdf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;dissolve&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;by&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;province&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;province&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    province&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;reset_index&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;rename&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;province&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;drop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;district&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;province&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;div&gt;
&lt;style scoped&gt;
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.dataframe tbody tr th {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    vertical-align: top;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.dataframe thead th {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    text-align: right;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;style&gt;
&lt;table border=&quot;1&quot; class=&quot;dataframe&quot;&gt;
  &lt;thead&gt;
    &lt;tr style=&quot;text-align: right;&quot;&gt;
      &lt;th&gt;&lt;&#x2F;th&gt;
      &lt;th&gt;name&lt;&#x2F;th&gt;
      &lt;th&gt;geometry&lt;&#x2F;th&gt;
    &lt;&#x2F;tr&gt;
  &lt;&#x2F;thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;th&gt;0&lt;&#x2F;th&gt;
      &lt;td&gt;กระบี่&lt;&#x2F;td&gt;
      &lt;td&gt;MULTIPOLYGON (((99.14285 7.57282, 99.14256 7.5...&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;1&lt;&#x2F;th&gt;
      &lt;td&gt;กรุงเทพมหานคร&lt;&#x2F;td&gt;
      &lt;td&gt;POLYGON ((100.51756 13.66185, 100.51754 13.661...&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;2&lt;&#x2F;th&gt;
      &lt;td&gt;กาญจนบุรี&lt;&#x2F;td&gt;
      &lt;td&gt;POLYGON ((99.76845 14.09449, 99.76898 14.09458...&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;3&lt;&#x2F;th&gt;
      &lt;td&gt;กาฬสินธุ์&lt;&#x2F;td&gt;
      &lt;td&gt;POLYGON ((103.54900 16.21370, 103.54763 16.213...&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;4&lt;&#x2F;th&gt;
      &lt;td&gt;กำแพงเพชร&lt;&#x2F;td&gt;
      &lt;td&gt;POLYGON ((99.97734 16.11070, 99.97546 16.10861...&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;...&lt;&#x2F;th&gt;
      &lt;td&gt;...&lt;&#x2F;td&gt;
      &lt;td&gt;...&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;71&lt;&#x2F;th&gt;
      &lt;td&gt;เพชรบุรี&lt;&#x2F;td&gt;
      &lt;td&gt;POLYGON ((100.02689 12.91666, 100.02690 12.916...&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;72&lt;&#x2F;th&gt;
      &lt;td&gt;เพชรบูรณ์&lt;&#x2F;td&gt;
      &lt;td&gt;POLYGON ((101.30859 15.57351, 101.30821 15.566...&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;73&lt;&#x2F;th&gt;
      &lt;td&gt;เลย&lt;&#x2F;td&gt;
      &lt;td&gt;POLYGON ((102.01428 17.14017, 102.01439 17.140...&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;74&lt;&#x2F;th&gt;
      &lt;td&gt;แพร่&lt;&#x2F;td&gt;
      &lt;td&gt;POLYGON ((99.64157 18.05575, 99.64237 18.05561...&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;75&lt;&#x2F;th&gt;
      &lt;td&gt;แม่ฮ่องสอน&lt;&#x2F;td&gt;
      &lt;td&gt;POLYGON ((98.16045 18.15059, 98.16069 18.15037...&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
  &lt;&#x2F;tbody&gt;
&lt;&#x2F;table&gt;
&lt;p&gt;76 rows × 2 columns&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# declare dummy variable so it can be reused with other region type&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; province&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;eda-tokenize-region-name-use-other-tokenizer-for-your-target-language&quot;&gt;EDA: tokenize region name. Use other tokenizer for your target language&lt;a class=&quot;zola-anchor&quot; href=&quot;#eda-tokenize-region-name-use-other-tokenizer-for-your-target-language&quot; aria-label=&quot;Anchor link for: eda-tokenize-region-name-use-other-tokenizer-for-your-target-language&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; tokenize&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable z-parameter z-function z-language z-python&quot;&gt;unique_region_values&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    input: unique values of region type&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    return: dataframe with token columns&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;DataFrame&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;Series&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;unique_region_values&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;token&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;apply&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt;lambda&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable z-parameter z-function z-language z-python&quot;&gt; x&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; syllable_tokenize&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Thai doesn&amp;#39;t use space to separate words, so it&amp;#39;s a bit wonky&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; when I tell it to do such, that&amp;#39;s why I need to see the results&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; manually, and in some cases it may &amp;quot;clip&amp;quot; a token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;token_1-1&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;token&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;str&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;token_1-2&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;token&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;str&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;token_1_full&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;token_1-1&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;token_1-2&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;token_2-1&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;token&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;str&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;token_2-2&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;token&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;str&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;token_2_full&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;token_2-1&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;token_2-2&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; temp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Don&#x27;t forget to look through the results and pick tokens you think are &quot;correct&quot;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;tokenize&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;unique&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;div&gt;
&lt;style scoped&gt;
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.dataframe tbody tr th {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    vertical-align: top;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.dataframe thead th {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    text-align: right;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;style&gt;
&lt;table border=&quot;1&quot; class=&quot;dataframe&quot;&gt;
  &lt;thead&gt;
    &lt;tr style=&quot;text-align: right;&quot;&gt;
      &lt;th&gt;&lt;&#x2F;th&gt;
      &lt;th&gt;name&lt;&#x2F;th&gt;
      &lt;th&gt;token&lt;&#x2F;th&gt;
      &lt;th&gt;token_1-1&lt;&#x2F;th&gt;
      &lt;th&gt;token_1-2&lt;&#x2F;th&gt;
      &lt;th&gt;token_1_full&lt;&#x2F;th&gt;
      &lt;th&gt;token_2-1&lt;&#x2F;th&gt;
      &lt;th&gt;token_2-2&lt;&#x2F;th&gt;
      &lt;th&gt;token_2_full&lt;&#x2F;th&gt;
    &lt;&#x2F;tr&gt;
  &lt;&#x2F;thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;th&gt;0&lt;&#x2F;th&gt;
      &lt;td&gt;กระบี่&lt;&#x2F;td&gt;
      &lt;td&gt;[กระ, บี่]&lt;&#x2F;td&gt;
      &lt;td&gt;กระ&lt;&#x2F;td&gt;
      &lt;td&gt;บี่&lt;&#x2F;td&gt;
      &lt;td&gt;กระบี่&lt;&#x2F;td&gt;
      &lt;td&gt;กระ&lt;&#x2F;td&gt;
      &lt;td&gt;บี่&lt;&#x2F;td&gt;
      &lt;td&gt;กระบี่&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;1&lt;&#x2F;th&gt;
      &lt;td&gt;กรุงเทพมหานคร&lt;&#x2F;td&gt;
      &lt;td&gt;[กรุง, เทพ, มหา, นคร]&lt;&#x2F;td&gt;
      &lt;td&gt;กรุง&lt;&#x2F;td&gt;
      &lt;td&gt;เทพ&lt;&#x2F;td&gt;
      &lt;td&gt;กรุงเทพ&lt;&#x2F;td&gt;
      &lt;td&gt;มหา&lt;&#x2F;td&gt;
      &lt;td&gt;นคร&lt;&#x2F;td&gt;
      &lt;td&gt;มหานคร&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;2&lt;&#x2F;th&gt;
      &lt;td&gt;กาญจนบุรี&lt;&#x2F;td&gt;
      &lt;td&gt;[กาญ, จน, บุ, รี]&lt;&#x2F;td&gt;
      &lt;td&gt;กาญ&lt;&#x2F;td&gt;
      &lt;td&gt;จน&lt;&#x2F;td&gt;
      &lt;td&gt;กาญจน&lt;&#x2F;td&gt;
      &lt;td&gt;บุ&lt;&#x2F;td&gt;
      &lt;td&gt;รี&lt;&#x2F;td&gt;
      &lt;td&gt;บุรี&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;3&lt;&#x2F;th&gt;
      &lt;td&gt;กาฬสินธุ์&lt;&#x2F;td&gt;
      &lt;td&gt;[กาฬ, สินธุ์]&lt;&#x2F;td&gt;
      &lt;td&gt;กาฬ&lt;&#x2F;td&gt;
      &lt;td&gt;สินธุ์&lt;&#x2F;td&gt;
      &lt;td&gt;กาฬสินธุ์&lt;&#x2F;td&gt;
      &lt;td&gt;กาฬ&lt;&#x2F;td&gt;
      &lt;td&gt;สินธุ์&lt;&#x2F;td&gt;
      &lt;td&gt;กาฬสินธุ์&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;4&lt;&#x2F;th&gt;
      &lt;td&gt;กำแพงเพชร&lt;&#x2F;td&gt;
      &lt;td&gt;[กำ, แพง, เพชร]&lt;&#x2F;td&gt;
      &lt;td&gt;กำ&lt;&#x2F;td&gt;
      &lt;td&gt;แพง&lt;&#x2F;td&gt;
      &lt;td&gt;กำแพง&lt;&#x2F;td&gt;
      &lt;td&gt;แพง&lt;&#x2F;td&gt;
      &lt;td&gt;เพชร&lt;&#x2F;td&gt;
      &lt;td&gt;แพงเพชร&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;...&lt;&#x2F;th&gt;
      &lt;td&gt;...&lt;&#x2F;td&gt;
      &lt;td&gt;...&lt;&#x2F;td&gt;
      &lt;td&gt;...&lt;&#x2F;td&gt;
      &lt;td&gt;...&lt;&#x2F;td&gt;
      &lt;td&gt;...&lt;&#x2F;td&gt;
      &lt;td&gt;...&lt;&#x2F;td&gt;
      &lt;td&gt;...&lt;&#x2F;td&gt;
      &lt;td&gt;...&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;71&lt;&#x2F;th&gt;
      &lt;td&gt;เพชรบุรี&lt;&#x2F;td&gt;
      &lt;td&gt;[เพชร, บุ, รี]&lt;&#x2F;td&gt;
      &lt;td&gt;เพชร&lt;&#x2F;td&gt;
      &lt;td&gt;บุ&lt;&#x2F;td&gt;
      &lt;td&gt;เพชรบุ&lt;&#x2F;td&gt;
      &lt;td&gt;บุ&lt;&#x2F;td&gt;
      &lt;td&gt;รี&lt;&#x2F;td&gt;
      &lt;td&gt;บุรี&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;72&lt;&#x2F;th&gt;
      &lt;td&gt;เพชรบูรณ์&lt;&#x2F;td&gt;
      &lt;td&gt;[เพชร, บูรณ์]&lt;&#x2F;td&gt;
      &lt;td&gt;เพชร&lt;&#x2F;td&gt;
      &lt;td&gt;บูรณ์&lt;&#x2F;td&gt;
      &lt;td&gt;เพชรบูรณ์&lt;&#x2F;td&gt;
      &lt;td&gt;เพชร&lt;&#x2F;td&gt;
      &lt;td&gt;บูรณ์&lt;&#x2F;td&gt;
      &lt;td&gt;เพชรบูรณ์&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;73&lt;&#x2F;th&gt;
      &lt;td&gt;เลย&lt;&#x2F;td&gt;
      &lt;td&gt;[เลย]&lt;&#x2F;td&gt;
      &lt;td&gt;เลย&lt;&#x2F;td&gt;
      &lt;td&gt;NaN&lt;&#x2F;td&gt;
      &lt;td&gt;NaN&lt;&#x2F;td&gt;
      &lt;td&gt;NaN&lt;&#x2F;td&gt;
      &lt;td&gt;เลย&lt;&#x2F;td&gt;
      &lt;td&gt;NaN&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;74&lt;&#x2F;th&gt;
      &lt;td&gt;แพร่&lt;&#x2F;td&gt;
      &lt;td&gt;[แพร่]&lt;&#x2F;td&gt;
      &lt;td&gt;แพร่&lt;&#x2F;td&gt;
      &lt;td&gt;NaN&lt;&#x2F;td&gt;
      &lt;td&gt;NaN&lt;&#x2F;td&gt;
      &lt;td&gt;NaN&lt;&#x2F;td&gt;
      &lt;td&gt;แพร่&lt;&#x2F;td&gt;
      &lt;td&gt;NaN&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;75&lt;&#x2F;th&gt;
      &lt;td&gt;แม่ฮ่องสอน&lt;&#x2F;td&gt;
      &lt;td&gt;[แม่, ฮ่อง, สอน]&lt;&#x2F;td&gt;
      &lt;td&gt;แม่&lt;&#x2F;td&gt;
      &lt;td&gt;ฮ่อง&lt;&#x2F;td&gt;
      &lt;td&gt;แม่ฮ่อง&lt;&#x2F;td&gt;
      &lt;td&gt;ฮ่อง&lt;&#x2F;td&gt;
      &lt;td&gt;สอน&lt;&#x2F;td&gt;
      &lt;td&gt;ฮ่องสอน&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
  &lt;&#x2F;tbody&gt;
&lt;&#x2F;table&gt;
&lt;p&gt;76 rows × 8 columns&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h2 id=&quot;tokenize-with-selected-slugs&quot;&gt;Tokenize with selected slugs&lt;a class=&quot;zola-anchor&quot; href=&quot;#tokenize-with-selected-slugs&quot; aria-label=&quot;Anchor link for: tokenize-with-selected-slugs&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# replace with your slugs here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;slugs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;นคร&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;สุ&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;สมุทร&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ธานี&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;นคร&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;slugs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; sorted&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-support z-type z-python&quot;&gt;list&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-support z-type z-python&quot;&gt;set&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;slugs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;slugs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; slugs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; for longest matching&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# get prefix and suffix&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; get_slug_1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable z-parameter z-function z-language z-python&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; slugs&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;startswith&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; get_slug_2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable z-parameter z-function z-language z-python&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; slugs&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;endswith&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;prefix&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;apply&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt;lambda&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable z-parameter z-function z-language z-python&quot;&gt; x&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; get_slug_1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;suffix&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;apply&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt;lambda&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable z-parameter z-function z-language z-python&quot;&gt; x&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; get_slug_2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;div&gt;
&lt;style scoped&gt;
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.dataframe tbody tr th {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    vertical-align: top;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.dataframe thead th {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    text-align: right;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;style&gt;
&lt;table border=&quot;1&quot; class=&quot;dataframe&quot;&gt;
  &lt;thead&gt;
    &lt;tr style=&quot;text-align: right;&quot;&gt;
      &lt;th&gt;&lt;&#x2F;th&gt;
      &lt;th&gt;name&lt;&#x2F;th&gt;
      &lt;th&gt;geometry&lt;&#x2F;th&gt;
      &lt;th&gt;prefix&lt;&#x2F;th&gt;
      &lt;th&gt;suffix&lt;&#x2F;th&gt;
      &lt;th&gt;class&lt;&#x2F;th&gt;
    &lt;&#x2F;tr&gt;
  &lt;&#x2F;thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;th&gt;0&lt;&#x2F;th&gt;
      &lt;td&gt;กระบี่&lt;&#x2F;td&gt;
      &lt;td&gt;MULTIPOLYGON (((99.14285 7.57282, 99.14256 7.5...&lt;&#x2F;td&gt;
      &lt;td&gt;None&lt;&#x2F;td&gt;
      &lt;td&gt;None&lt;&#x2F;td&gt;
      &lt;td&gt;class&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;1&lt;&#x2F;th&gt;
      &lt;td&gt;กรุงเทพมหานคร&lt;&#x2F;td&gt;
      &lt;td&gt;POLYGON ((100.51756 13.66185, 100.51754 13.661...&lt;&#x2F;td&gt;
      &lt;td&gt;None&lt;&#x2F;td&gt;
      &lt;td&gt;นคร&lt;&#x2F;td&gt;
      &lt;td&gt;class&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;2&lt;&#x2F;th&gt;
      &lt;td&gt;กาญจนบุรี&lt;&#x2F;td&gt;
      &lt;td&gt;POLYGON ((99.76845 14.09449, 99.76898 14.09458...&lt;&#x2F;td&gt;
      &lt;td&gt;None&lt;&#x2F;td&gt;
      &lt;td&gt;None&lt;&#x2F;td&gt;
      &lt;td&gt;class&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;3&lt;&#x2F;th&gt;
      &lt;td&gt;กาฬสินธุ์&lt;&#x2F;td&gt;
      &lt;td&gt;POLYGON ((103.54900 16.21370, 103.54763 16.213...&lt;&#x2F;td&gt;
      &lt;td&gt;None&lt;&#x2F;td&gt;
      &lt;td&gt;None&lt;&#x2F;td&gt;
      &lt;td&gt;class&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;4&lt;&#x2F;th&gt;
      &lt;td&gt;กำแพงเพชร&lt;&#x2F;td&gt;
      &lt;td&gt;POLYGON ((99.97734 16.11070, 99.97546 16.10861...&lt;&#x2F;td&gt;
      &lt;td&gt;None&lt;&#x2F;td&gt;
      &lt;td&gt;None&lt;&#x2F;td&gt;
      &lt;td&gt;class&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;...&lt;&#x2F;th&gt;
      &lt;td&gt;...&lt;&#x2F;td&gt;
      &lt;td&gt;...&lt;&#x2F;td&gt;
      &lt;td&gt;...&lt;&#x2F;td&gt;
      &lt;td&gt;...&lt;&#x2F;td&gt;
      &lt;td&gt;...&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;71&lt;&#x2F;th&gt;
      &lt;td&gt;เพชรบุรี&lt;&#x2F;td&gt;
      &lt;td&gt;POLYGON ((100.02689 12.91666, 100.02690 12.916...&lt;&#x2F;td&gt;
      &lt;td&gt;None&lt;&#x2F;td&gt;
      &lt;td&gt;None&lt;&#x2F;td&gt;
      &lt;td&gt;class&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;72&lt;&#x2F;th&gt;
      &lt;td&gt;เพชรบูรณ์&lt;&#x2F;td&gt;
      &lt;td&gt;POLYGON ((101.30859 15.57351, 101.30821 15.566...&lt;&#x2F;td&gt;
      &lt;td&gt;None&lt;&#x2F;td&gt;
      &lt;td&gt;None&lt;&#x2F;td&gt;
      &lt;td&gt;class&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;73&lt;&#x2F;th&gt;
      &lt;td&gt;เลย&lt;&#x2F;td&gt;
      &lt;td&gt;POLYGON ((102.01428 17.14017, 102.01439 17.140...&lt;&#x2F;td&gt;
      &lt;td&gt;None&lt;&#x2F;td&gt;
      &lt;td&gt;None&lt;&#x2F;td&gt;
      &lt;td&gt;class&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;74&lt;&#x2F;th&gt;
      &lt;td&gt;แพร่&lt;&#x2F;td&gt;
      &lt;td&gt;POLYGON ((99.64157 18.05575, 99.64237 18.05561...&lt;&#x2F;td&gt;
      &lt;td&gt;None&lt;&#x2F;td&gt;
      &lt;td&gt;None&lt;&#x2F;td&gt;
      &lt;td&gt;class&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;75&lt;&#x2F;th&gt;
      &lt;td&gt;แม่ฮ่องสอน&lt;&#x2F;td&gt;
      &lt;td&gt;POLYGON ((98.16045 18.15059, 98.16069 18.15037...&lt;&#x2F;td&gt;
      &lt;td&gt;None&lt;&#x2F;td&gt;
      &lt;td&gt;None&lt;&#x2F;td&gt;
      &lt;td&gt;class&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
  &lt;&#x2F;tbody&gt;
&lt;&#x2F;table&gt;
&lt;p&gt;76 rows × 5 columns&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h2 id=&quot;viz-prep&quot;&gt;Viz prep&lt;a class=&quot;zola-anchor&quot; href=&quot;#viz-prep&quot; aria-label=&quot;Anchor link for: viz-prep&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# make total_bound (background outline)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# and extend (so the canvas would center at the same point)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# also, remember the PROVINCE dataset from the start? we&amp;#39;re going to use that&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;province&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; a dummy column so it would dissolve the whole dataset&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;boundary&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; province&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;dissolve&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;by&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;extent&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; boundary&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;total_bounds&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# set font (default matplotlib font can&amp;#39;t render Thai)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;plt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;rcParams&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;font.family&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Tahoma&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;cleaning-it-up&quot;&gt;Cleaning it up&lt;a class=&quot;zola-anchor&quot; href=&quot;#cleaning-it-up&quot; aria-label=&quot;Anchor link for: cleaning-it-up&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;There are some degree of Pali-Sanskrit influence in Thai, in which the word order is different, so it is possible for a certain *fix to appear as either prefix or suffix. it&#x27;s like &lt;strong&gt;re&lt;&#x2F;strong&gt;peat and do&lt;strong&gt;re&lt;&#x2F;strong&gt; (for redo)&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# ⛩⛩⛩ rerun from this cell onward if you want to change *fix ⛩⛩⛩&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# filter null *fix&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;_fix_column&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;suffix&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ⛩⛩⛩ change here ⛩⛩⛩&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df_temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df_temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df_temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;df_temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_fix_column&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;notnull&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# get count&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df_temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_count&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;format&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_fix_column&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df_temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_fix_column&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;map&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    df_temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;_fix_column&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;value_counts&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;to_dict&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# at the largest region level it won&amp;#39;t be much, but at a smaller level like subdistrict&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# having a single *fix for the entire dataset can happen, hence we should filter it out&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# filter for a *fix you want to visualize&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;viz_categ_count_column&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_count&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;format&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_fix_column&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# ⛩⛩⛩ use the second line if you want to set the threshold with median ⛩⛩⛩&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;threshold&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# threshold = df_temp[viz_categ_count_column].median()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df_temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df_temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;df_temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;viz_categ_count_column&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span&gt; threshold&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df_temp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;div&gt;
&lt;style scoped&gt;
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.dataframe tbody tr th {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    vertical-align: top;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.dataframe thead th {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    text-align: right;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;style&gt;
&lt;table border=&quot;1&quot; class=&quot;dataframe&quot;&gt;
  &lt;thead&gt;
    &lt;tr style=&quot;text-align: right;&quot;&gt;
      &lt;th&gt;&lt;&#x2F;th&gt;
      &lt;th&gt;name&lt;&#x2F;th&gt;
      &lt;th&gt;geometry&lt;&#x2F;th&gt;
      &lt;th&gt;prefix&lt;&#x2F;th&gt;
      &lt;th&gt;suffix&lt;&#x2F;th&gt;
      &lt;th&gt;class&lt;&#x2F;th&gt;
      &lt;th&gt;suffix_count&lt;&#x2F;th&gt;
    &lt;&#x2F;tr&gt;
  &lt;&#x2F;thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;th&gt;1&lt;&#x2F;th&gt;
      &lt;td&gt;กรุงเทพมหานคร&lt;&#x2F;td&gt;
      &lt;td&gt;POLYGON ((100.51756 13.66185, 100.51754 13.661...&lt;&#x2F;td&gt;
      &lt;td&gt;None&lt;&#x2F;td&gt;
      &lt;td&gt;นคร&lt;&#x2F;td&gt;
      &lt;td&gt;class&lt;&#x2F;td&gt;
      &lt;td&gt;2&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;25&lt;&#x2F;th&gt;
      &lt;td&gt;ปทุมธานี&lt;&#x2F;td&gt;
      &lt;td&gt;POLYGON ((100.91417 13.95445, 100.91415 13.952...&lt;&#x2F;td&gt;
      &lt;td&gt;None&lt;&#x2F;td&gt;
      &lt;td&gt;ธานี&lt;&#x2F;td&gt;
      &lt;td&gt;class&lt;&#x2F;td&gt;
      &lt;td&gt;5&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;48&lt;&#x2F;th&gt;
      &lt;td&gt;สกลนคร&lt;&#x2F;td&gt;
      &lt;td&gt;POLYGON ((104.36246 17.09941, 104.36248 17.099...&lt;&#x2F;td&gt;
      &lt;td&gt;None&lt;&#x2F;td&gt;
      &lt;td&gt;นคร&lt;&#x2F;td&gt;
      &lt;td&gt;class&lt;&#x2F;td&gt;
      &lt;td&gt;2&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;58&lt;&#x2F;th&gt;
      &lt;td&gt;สุราษฎร์ธานี&lt;&#x2F;td&gt;
      &lt;td&gt;MULTIPOLYGON (((99.20865 8.33715, 99.20647 8.3...&lt;&#x2F;td&gt;
      &lt;td&gt;สุ&lt;&#x2F;td&gt;
      &lt;td&gt;ธานี&lt;&#x2F;td&gt;
      &lt;td&gt;class&lt;&#x2F;td&gt;
      &lt;td&gt;5&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;64&lt;&#x2F;th&gt;
      &lt;td&gt;อุดรธานี&lt;&#x2F;td&gt;
      &lt;td&gt;POLYGON ((103.44196 17.21428, 103.44246 17.214...&lt;&#x2F;td&gt;
      &lt;td&gt;None&lt;&#x2F;td&gt;
      &lt;td&gt;ธานี&lt;&#x2F;td&gt;
      &lt;td&gt;class&lt;&#x2F;td&gt;
      &lt;td&gt;5&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;66&lt;&#x2F;th&gt;
      &lt;td&gt;อุทัยธานี&lt;&#x2F;td&gt;
      &lt;td&gt;POLYGON ((100.04080 15.29612, 100.04067 15.296...&lt;&#x2F;td&gt;
      &lt;td&gt;None&lt;&#x2F;td&gt;
      &lt;td&gt;ธานี&lt;&#x2F;td&gt;
      &lt;td&gt;class&lt;&#x2F;td&gt;
      &lt;td&gt;5&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr&gt;
      &lt;th&gt;67&lt;&#x2F;th&gt;
      &lt;td&gt;อุบลราชธานี&lt;&#x2F;td&gt;
      &lt;td&gt;POLYGON ((105.55486 14.95406, 105.55414 14.953...&lt;&#x2F;td&gt;
      &lt;td&gt;None&lt;&#x2F;td&gt;
      &lt;td&gt;ธานี&lt;&#x2F;td&gt;
      &lt;td&gt;class&lt;&#x2F;td&gt;
      &lt;td&gt;5&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
  &lt;&#x2F;tbody&gt;
&lt;&#x2F;table&gt;
&lt;&#x2F;div&gt;
&lt;h2 id=&quot;viz&quot;&gt;Viz&lt;a class=&quot;zola-anchor&quot; href=&quot;#viz&quot; aria-label=&quot;Anchor link for: viz&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; os&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;key_column&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; _fix_column&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;key_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;province&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; ⛩⛩⛩ set region type here #&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;key_count_column&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_count&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;format&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;key_column&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;out_dir&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;plot&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;format&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;key_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; key_column&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;os&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;makedirs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;out_dir&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; exist_ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;True&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gdf&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df_temp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; gdf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;key_column&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;unique&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ax&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; gplt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;polyplot&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;boundary&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; figsize&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;10&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    query&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; gdf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;gdf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;key_column&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; key&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    total_records&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-support z-type z-python&quot;&gt; str&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-support z-type z-python&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;query&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;key_count_column&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;tolist&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    gplt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;polyplot&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;query&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; ax&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;ax&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; extent&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;extent&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; edgecolor&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;black&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; facecolor&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;green&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    plt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;: &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; records&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;format&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;key&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; total_records&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    plt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;savefig&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.png&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;format&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;out_dir&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-support z-type z-python&quot;&gt; str&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;total_records&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;zfill&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; key&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;#     break&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;output-structure&quot;&gt;Output structure&lt;a class=&quot;zola-anchor&quot; href=&quot;#output-structure&quot; aria-label=&quot;Anchor link for: output-structure&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2020&#x2F;09&#x2F;visualizing-map-region-prefix-suffix&#x2F;images&#x2F;2021-08-18-19-12-14.webp&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;some-interesting-outputs-at-subdistrict-level&quot;&gt;Some interesting outputs (at subdistrict level)&lt;a class=&quot;zola-anchor&quot; href=&quot;#some-interesting-outputs-at-subdistrict-level&quot; aria-label=&quot;Anchor link for: some-interesting-outputs-at-subdistrict-level&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;northern-region&quot;&gt;Northern region&lt;a class=&quot;zola-anchor&quot; href=&quot;#northern-region&quot; aria-label=&quot;Anchor link for: northern-region&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;You can see that the prefix &quot;แม่&quot; concentrates around the northern region.
&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2020&#x2F;09&#x2F;visualizing-map-region-prefix-suffix&#x2F;images&#x2F;2021-08-18-19-12-05.webp&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;eastern-region&quot;&gt;Eastern region&lt;a class=&quot;zola-anchor&quot; href=&quot;#eastern-region&quot; aria-label=&quot;Anchor link for: eastern-region&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;&quot;โนน&quot; seems to be specific to the eastern seeing it&#x27;s clustered around the eastern part of the country.
&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2020&#x2F;09&#x2F;visualizing-map-region-prefix-suffix&#x2F;images&#x2F;2021-08-18-19-12-22.webp&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;multi-region&quot;&gt;Multi-region&lt;a class=&quot;zola-anchor&quot; href=&quot;#multi-region&quot; aria-label=&quot;Anchor link for: multi-region&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;As expected, &quot;บาง&quot; is clustered around the central region, no surprise here since the old name of Thailand&#x27;s capital (it&#x27;s located in the central region) is &quot;บางกอก.&quot; But you can see that it&#x27;s clustered around the southern parts as well.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2020&#x2F;09&#x2F;visualizing-map-region-prefix-suffix&#x2F;images&#x2F;2021-08-18-19-12-35.webp&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Impute pipelines</title>
          <pubDate>Fri, 22 May 2020 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2020/05/impute-pipelines/</link>
          <guid>https://karnwong.me/posts/2020/05/impute-pipelines/</guid>
          <description xml:base="https://karnwong.me/posts/2020/05/impute-pipelines/">&lt;p&gt;Imagine having a dataset that you need to use for training a prediction model, but some of the features are missing. The good news is you don&#x27;t need to throw some data away, just have to impute them. Below are steps you can take in order to create an imputation pipeline.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; random&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; randint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; matplotlib&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;pyplot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; plt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; mlflow&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; numpy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; np&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; pandas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; pd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; seaborn&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; sns&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; hyperopt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; fmin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; hp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-constant&quot;&gt; STATUS_OK&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tpe&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; Trials&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; sklearn&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;compose&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; ColumnTransformer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; sklearn&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ensemble&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; import&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ExtraTreesRegressor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    GradientBoostingRegressor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    RandomForestRegressor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; sklearn&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;impute&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; SimpleImputer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; sklearn&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;metrics&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; mean_squared_error&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; median_absolute_error&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; sklearn&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;pipeline&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; Pipeline&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; sklearn&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;preprocessing&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; OneHotEncoder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; StandardScaler&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; sklearn&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tree&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; DecisionTreeRegressor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;set&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;generate-data&quot;&gt;Generate data&lt;a class=&quot;zola-anchor&quot; href=&quot;#generate-data&quot; aria-label=&quot;Anchor link for: generate-data&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Since this is an example and I don&#x27;t want to get sued by using my company&#x27;s data, synthetic data it is :)
This simulates a dataset from different pseudo-regions, with different characteristics. Real data will be much more varied, but I make it more obvious so it&#x27;s easy to see the differences.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; generate_array_with_random_nan&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable z-parameter z-function z-language z-python&quot;&gt;lower_bound&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-parameters z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable z-parameter z-function z-language z-python&quot;&gt; upper_bound&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-parameters z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable z-parameter z-function z-language z-python&quot;&gt; size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;random&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;randint&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;lower_bound&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; upper_bound&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;astype&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-support z-type z-python&quot;&gt;float&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mask&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;random&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;choice&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;shape&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0.1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0.9&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;astype&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-support z-type z-python&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;mask&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;nan&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 6000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df_cbd&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;DataFrame&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df_cbd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bed&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; generate_array_with_random_nan&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df_cbd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bath&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; generate_array_with_random_nan&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df_cbd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;area_usable&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;random&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;randint&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;20&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 40&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df_cbd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;region&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;cbd&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df_suburb&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;DataFrame&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df_suburb&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bed&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; generate_array_with_random_nan&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df_suburb&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bath&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; generate_array_with_random_nan&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df_suburb&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;area_usable&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;random&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;randint&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;30&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 200&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df_suburb&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;region&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;suburb&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;concat&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;df_cbd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; df_suburb&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: right&quot;&gt;&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: right&quot;&gt;bed&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: right&quot;&gt;bath&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: right&quot;&gt;area_usable&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;region&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;0&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;2&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;1&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;33&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;cbd&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;1&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;1&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;2&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;23&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;cbd&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;2&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;1&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;2&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;33&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;cbd&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;3&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;2&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;1&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;26&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;cbd&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;4&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;2&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;1&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;28&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;cbd&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;5&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;2&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;2&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;36&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;cbd&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;6&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;1&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;2&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;38&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;cbd&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;7&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;2&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;1&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;23&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;cbd&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;8&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;2&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;1&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;36&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;cbd&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;9&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;nan&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;2&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;29&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;cbd&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;report-missing-values&quot;&gt;Report missing values&lt;a class=&quot;zola-anchor&quot; href=&quot;#report-missing-values&quot; aria-label=&quot;Anchor link for: report-missing-values&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;I also randomly remove some values to mimic real-world data (read: they are never ready to use), here we will visualize the missing rate of each column.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; report_missing&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable z-parameter z-function z-language z-python&quot;&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cnts&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cnt_total&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; len&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; col&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;columns&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cnt_missing&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; sum&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;pd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;isnull&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;col&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-bitwise&quot;&gt; |&lt;&#x2F;span&gt;&lt;span&gt; pd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;isna&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;col&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;col: &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;, missing: &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;format&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;col&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 100.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; cnt_missing&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span&gt; cnt_total&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cnts&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;append&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;column&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; col&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;missing&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 100.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; cnt_missing&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span&gt; cnt_total&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cnts_df&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;DataFrame&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;cnts&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    sns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;barplot&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;        x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;cnts_df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;missing&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;        y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;cnts_df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;column&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;             palette=[&amp;#39;r&amp;#39;,&amp;#39;b&amp;#39;],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;             data=cnts_df&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;    )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; sns&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;report_missing&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;col: bed, missing: 10.266666666666667%&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;col: bath, missing: 9.616666666666667%&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;col: area_usable, missing: 0.0%&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;col: region, missing: 0.0%&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2020&#x2F;05&#x2F;impute-pipelines&#x2F;images&#x2F;2021-08-18-19-05-52.webp&quot; alt=&quot;2021 08 18 19 05 52 image&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;data-exploration&quot;&gt;Data exploration&lt;a class=&quot;zola-anchor&quot; href=&quot;#data-exploration&quot; aria-label=&quot;Anchor link for: data-exploration&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Knowing the missing rate isn&#x27;t everything, thus it is also a good idea to explore data in other areas too.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# missing bed per region&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;bed&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;isna&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;region&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;value_counts&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;dropna&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;False&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cbd       634&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;suburb    598&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Name: region, dtype: int64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# missing bath per region&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;bath&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;isna&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;region&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;value_counts&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;dropna&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;False&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;suburb    588&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cbd       566&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Name: region, dtype: int64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# explore region&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;region&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;value_counts&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;suburb    6000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cbd       6000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Name: region, dtype: int64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# explore bed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;bed&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;value_counts&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2.0    4050&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1.0    4009&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4.0    1393&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;3.0    1316&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Name: bed, dtype: int64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# explore bath&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;bath&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;value_counts&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1.0    4142&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2.0    4022&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;3.0    1393&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4.0    1289&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Name: bath, dtype: int64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;remove-outliers&quot;&gt;Remove outliers&lt;a class=&quot;zola-anchor&quot; href=&quot;#remove-outliers&quot; aria-label=&quot;Anchor link for: remove-outliers&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;(wouldn&#x27;t want your model to have a sub-par performance from skewed data :-P)&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# remove outliers here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;create-synthetic-columns&quot;&gt;Create synthetic columns&lt;a class=&quot;zola-anchor&quot; href=&quot;#create-synthetic-columns&quot; aria-label=&quot;Anchor link for: create-synthetic-columns&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;In this step, we create percentile, mean and rank columns to add more data points, so the model can perform better :D&lt;&#x2F;p&gt;
&lt;p&gt;First, we find aggregate percentiles for each groupby set, then add mean and rank columns.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;synth_columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bed&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;region_bath&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;region&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bath&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bath&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;region_bed&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;region&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bed&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; column&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; groupby_levels&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; synth_columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;items&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; groupby_level_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; groupby_columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; groupby_levels&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;items&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; percentile aggregates&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; pctl&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;20&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 50&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 80&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 90&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            col_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;format&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;pctl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; groupby_level_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; column&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;            print&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;calculating -- &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;format&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;col_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;col_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;groupby_columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt; [&lt;&#x2F;span&gt;&lt;span&gt;column&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;                .&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;fillna&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;                .&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;groupby&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;groupby_columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;column&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;                .&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;transform&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt;lambda&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable z-parameter z-function z-language z-python&quot;&gt; x&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;quantile&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;pctl&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 100.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;            )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; mean impute&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        mean_impute&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;mean|&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;format&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;groupby_level_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; column&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;calculating -- &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;format&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;mean_impute&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;mean_impute&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;groupby&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;groupby_columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;column&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;transform&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;mean&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; bed&#x2F;bath rank&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        rank_impute&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; column_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;rank|&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;format&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;groupby_level_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; column&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;calculating -- &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;format&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;rank_impute&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;rank_impute&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;groupby&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;groupby_columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;column&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;rank&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;            method&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;dense&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; na_option&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bottom&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;        )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;calculating -- p20|region_bath|bed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;calculating -- p50|region_bath|bed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;calculating -- p80|region_bath|bed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;calculating -- p90|region_bath|bed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;calculating -- mean|region_bath|bed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;calculating -- rank|region_bath|bed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;calculating -- p20|region_bed|bath&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;calculating -- p50|region_bed|bath&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;calculating -- p80|region_bed|bath&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;calculating -- p90|region_bed|bath&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;calculating -- mean|region_bed|bath&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;calculating -- rank|region_bed|bath&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;coalesce-values&quot;&gt;Coalesce values&lt;a class=&quot;zola-anchor&quot; href=&quot;#coalesce-values&quot; aria-label=&quot;Anchor link for: coalesce-values&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;In this step we fill in values obtained from the previous step -- impute time!!&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; coalesce&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable z-parameter z-function z-language z-python&quot;&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-parameters z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable z-parameter z-function z-language z-python&quot;&gt; columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    Implement coalesce of function in columns.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    Inputs:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    df: reference dataframe&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    columns: columns to perform coalesce&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    Returns:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    df_tmp: pd.Series that is coalesced&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    Example:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    df_tmp = pd.DataFrame({&amp;#39;a&amp;#39;: [1,2,None,None,None,None],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                            &amp;#39;b&amp;#39;: [None,6,None,8,9,None],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                            &amp;#39;c&amp;#39;: [None,10,None,12,None,13]})&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    df_tmp[&amp;#39;new&amp;#39;] = coalesce(df_tmp, [&amp;#39;a&amp;#39;,&amp;#39;b&amp;#39;,&amp;#39;c&amp;#39;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    print(df_tmp)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    df_tmp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        df_tmp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df_tmp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;fillna&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;c&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; df_tmp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;coalesce_columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bed&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;p50|region_bath|bed&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; p50|GROUPBY_LESSER_WEIGHT|bed, ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bed_imputed&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; coalesce&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; coalesce_columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;coalesce_columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bath&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;p50|region_bed|bath&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; p50|GROUPBY_LESSER_WEIGHT|bath, ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bath_imputed&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; coalesce&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; coalesce_columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;report-missing-values-again&quot;&gt;Report missing values (again)&lt;a class=&quot;zola-anchor&quot; href=&quot;#report-missing-values-again&quot; aria-label=&quot;Anchor link for: report-missing-values-again&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;After we impute the values, let&#x27;s see how much we are doing better!&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;report_missing&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;col: bed, missing: 10.266666666666667%&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;col: bath, missing: 9.616666666666667%&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;col: area_usable, missing: 0.0%&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;col: region, missing: 0.0%&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;col: p20|region_bath|bed, missing: 0.0%&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;col: p50|region_bath|bed, missing: 0.0%&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;col: p80|region_bath|bed, missing: 0.0%&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;col: p90|region_bath|bed, missing: 0.0%&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;col: mean|region_bath|bed, missing: 9.616666666666667%&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;col: rank|region_bath|bed, missing: 0.0%&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;col: p20|region_bed|bath, missing: 0.0%&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;col: p50|region_bed|bath, missing: 0.0%&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;col: p80|region_bed|bath, missing: 0.0%&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;col: p90|region_bed|bath, missing: 0.0%&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;col: mean|region_bed|bath, missing: 10.266666666666667%&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;col: rank|region_bed|bath, missing: 0.0%&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;col: bed_imputed, missing: 0.0%&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;col: bath_imputed, missing: 0.0%&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2020&#x2F;05&#x2F;impute-pipelines&#x2F;images&#x2F;2021-08-18-19-08-00.webp&quot; alt=&quot;2021 08 18 19 08 00 image&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Notice that the imputed columns there are no missing values. Yay!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;assign-partition&quot;&gt;Assign partition&lt;a class=&quot;zola-anchor&quot; href=&quot;#assign-partition&quot; aria-label=&quot;Anchor link for: assign-partition&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;In this step, we partition the data into three sets: train, dev and test. Normally we only split into train and test set, but the additional &quot;dev&quot; set is there so we can make sure it&#x27;s not too overfit or underfit.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# assign partition&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; assign_partition&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable z-parameter z-function z-language z-python&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    elif&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;6&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    else&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# assign random id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;listing_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;randint&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1000000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 9999999&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;len&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# hashing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;hash_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;listing_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;apply&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt;lambda&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable z-parameter z-function z-language z-python&quot;&gt; x&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# assign partition&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;partition_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;hash_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;apply&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt;lambda&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable z-parameter z-function z-language z-python&quot;&gt; x&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; assign_partition&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# define columns group&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;y_column&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;area_usable&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;categ_columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;region&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;numer_columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bed_imputed&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bath_imputed&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;p20|region_bath|bed&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;p50|region_bath|bed&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;p80|region_bath|bed&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;p90|region_bath|bed&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;mean|region_bath|bed&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;rank|region_bath|bed&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;p20|region_bed|bath&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;p50|region_bed|bath&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;p80|region_bed|bath&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;p90|region_bed|bath&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;mean|region_bed|bath&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;rank|region_bed|bath&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;id_columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;listing_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;hash_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;partition_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# remove missing y&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;dropna&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;subset&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;y_column&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# split into train-dev-test&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df_train&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;partition_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df_dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;partition_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df_test&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;partition_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# split each set into x and y&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;y_train&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df_train&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;y_column&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;values&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df_train&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df_train&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;numer_columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; categ_columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;y_dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df_dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;y_column&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;values&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df_dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df_dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;numer_columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; categ_columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;y_test&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df_test&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;y_column&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;values&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df_test&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df_test&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;numer_columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; categ_columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;create-sklearn-pipelines&quot;&gt;Create sklearn pipelines&lt;a class=&quot;zola-anchor&quot; href=&quot;#create-sklearn-pipelines&quot; aria-label=&quot;Anchor link for: create-sklearn-pipelines&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;In this step, we chain a few pipelines together to process the dataset for the final time. In this example, we use median followed by standard scalar for numeric columns, and mode followed by encoding labels for categorical columns.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# define pipelines&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;impute_median&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; SimpleImputer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;strategy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;median&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;impute_mode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; SimpleImputer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;strategy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;most_frequent&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;num_pipeline&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; Pipeline&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt;    [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt;        (&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;impute_median&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; impute_median&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt;        (&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;std_scaler&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; StandardScaler&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;    ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;categ_pipeline&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; Pipeline&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt;    [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt;        (&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;impute_mode&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; impute_mode&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt;        (&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;categ_1hot&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; OneHotEncoder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;handle_unknown&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ignore&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;    ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;full_pipeline&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; ColumnTransformer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt;    [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt;        (&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;num&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; num_pipeline&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; numer_columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt;        (&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;cat&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; categ_pipeline&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; categ_columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;    ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# fit and transform&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;X_train&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; full_pipeline&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;fit_transform&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;df_train&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;X_dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; full_pipeline&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;transform&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;df_dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;X_test&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; full_pipeline&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;transform&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;df_test&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;X_train&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;array([[ 0.04673184,  0.06391404,  0.        , ..., -0.16000115,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;         1.        ,  0.        ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       [-0.97000929, -0.97263688,  0.        , ..., -1.01065389,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;         1.        ,  0.        ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       [ 0.04673184,  0.06391404,  0.        , ..., -0.16000115,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;         1.        ,  0.        ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       ...,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       [-0.97000929,  1.10046497,  0.        , ...,  0.69065159,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;         0.        ,  1.        ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       [ 0.04673184,  1.10046497,  0.        , ...,  0.69065159,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;         0.        ,  1.        ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       [ 1.06347297,  2.13701589,  0.        , ...,  1.54130432,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;         0.        ,  1.        ]])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;hyperparameter-tuning&quot;&gt;Hyperparameter tuning&lt;a class=&quot;zola-anchor&quot; href=&quot;#hyperparameter-tuning&quot; aria-label=&quot;Anchor link for: hyperparameter-tuning&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;In this step, we try to use different models and parameters to see which performs the best. We utilize mlflow for logging and hyperopt to help with tuning. In this example, we run the trials for 40 iterations, each using a different combination of model and parameters.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# mlflow + hyperopt combo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; objective&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable z-parameter z-function z-language z-python&quot;&gt;params&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    regressor_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; params&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    del&lt;&#x2F;span&gt;&lt;span&gt; params&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; regressor_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;gradient_boosting_regression&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        estimator&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; GradientBoostingRegressor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;**&lt;&#x2F;span&gt;&lt;span&gt;params&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    elif&lt;&#x2F;span&gt;&lt;span&gt; regressor_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;random_forest_regression&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        estimator&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; RandomForestRegressor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;**&lt;&#x2F;span&gt;&lt;span&gt;params&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    elif&lt;&#x2F;span&gt;&lt;span&gt; regressor_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;extra_trees_regression&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        estimator&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; ExtraTreesRegressor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;**&lt;&#x2F;span&gt;&lt;span&gt;params&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    elif&lt;&#x2F;span&gt;&lt;span&gt; regressor_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;decision_tree_regression&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        estimator&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; DecisionTreeRegressor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;**&lt;&#x2F;span&gt;&lt;span&gt;params&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    else&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    estimator&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;fit&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;X_train&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; y_train&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; mae&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    y_dev_hat&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; estimator&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;predict&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;X_dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mae&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; median_absolute_error&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;y_dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; y_dev_hat&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; logging&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    with&lt;&#x2F;span&gt;&lt;span&gt; mlflow&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;start_run&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        mlflow&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;log_param&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;regressor&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; estimator&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-variable z-magic z-python&quot;&gt;__class__&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-variable z-magic z-python&quot;&gt;__name__&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; mlflow.log_param(&amp;quot;params&amp;quot;, params)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        mlflow&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;log_param&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;n_estimators&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; params&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;n_estimators&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        mlflow&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;log_param&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;max_depth&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; params&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;max_depth&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        mlflow&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;log_metric&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;median_absolute_error&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; mae&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;loss&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; mae&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;status&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-constant&quot;&gt; STATUS_OK&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;space&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; hp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;choice&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;regressor_type&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt;    [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;gradient_boosting_regression&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;n_estimators&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; hp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;choice&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;n_estimators1&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;100&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 200&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 50&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;max_depth&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; hp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;choice&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;max_depth1&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;10&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 13&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;random_forest_regression&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;n_estimators&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; hp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;choice&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;n_estimators2&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;100&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 200&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 50&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;max_depth&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; hp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;choice&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;max_depth2&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 25&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;n_jobs&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;extra_trees_regression&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;n_estimators&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; hp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;choice&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;n_estimators3&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;100&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 200&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 50&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;max_depth&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; hp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;choice&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;max_depth3&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;type&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;decision_tree_regression&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;max_depth&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; hp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;choice&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;max_depth4&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;    ]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;trials&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; Trials&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;max_evals&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 40&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;best&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; fmin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;objective&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; space&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;space&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; algo&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;tpe&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;suggest&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; max_evals&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;max_evals&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; trials&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;trials&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;print&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Found minimum after &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; trials:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;format&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;max_evals&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; pprint&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; pprint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;pprint&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;best&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;100%|██████████| 40&#x2F;40 [00:19&amp;lt;00:00,  2.11trial&#x2F;s, best loss: 8.569474762575908]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Found minimum after 40 trials:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&amp;#39;max_depth2&amp;#39;: 1, &amp;#39;n_estimators2&amp;#39;: 1, &amp;#39;regressor_type&amp;#39;: 1}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;evaluate-performance&quot;&gt;Evaluate performance&lt;a class=&quot;zola-anchor&quot; href=&quot;#evaluate-performance&quot; aria-label=&quot;Anchor link for: evaluate-performance&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Run &quot;mlflow server&quot; to see the login dashboard. There, we can see that RandomForestRegressor has the best performance (the less MAE the better) when using max_depth=4 and n_estimators=150, to test the model&#x27;s performance against another test set:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# use best params on TEST set&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;estimator&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; RandomForestRegressor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;max_depth&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;4&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; n_estimators&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;150&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;estimator&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;fit&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;X_train&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; y_train&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;y_train_hat&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; estimator&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;predict&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;X_train&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;train_mae&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; median_absolute_error&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;y_train&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; y_train_hat&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;y_dev_hat&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; estimator&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;predict&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;X_dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dev_mae&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; median_absolute_error&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;y_dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; y_dev_hat&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;y_test_hat&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; estimator&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;predict&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;X_test&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;test_mae&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; median_absolute_error&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;y_test&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; y_test_hat&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mae&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; estimator&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-variable z-magic z-python&quot;&gt;__class__&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-variable z-magic z-python&quot;&gt;__name__&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;train_mae&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; train_mae&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;dev_mae&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; dev_mae&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;test_mae&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; test_mae&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mae&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;DataFrame&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;mae&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;set_index&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mae&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: left&quot;&gt;name&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: right&quot;&gt;train_mae&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: right&quot;&gt;dev_mae&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: right&quot;&gt;test_mae&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;DecisionTreeRegressor&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;8.930245&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;8.592484&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;8.729826&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;You&#x27;ll notice that we use &quot;median absolute error&quot; to measure performance. There are other metrics available, such as mean squared error, but in some cases it&#x27;s more meaningful to use a metric that measure the performance in actual data&#x27;s unit, in this case the error on dev and test set are around 8 units away from its correct value. Since normally we use square meter for area, it means the prediction will be off by about 8 square meters in most cases.&lt;&#x2F;p&gt;
&lt;p&gt;PS: We applied the same process to data from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;baania.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;baania.com&#x2F;&lt;&#x2F;a&gt; and it was a success!&lt;&#x2F;p&gt;
&lt;p&gt;Update 2022-07-14: Baania now has opendata! Check it out at &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gobestimate.com&#x2F;data&quot;&gt;https:&#x2F;&#x2F;gobestimate.com&#x2F;data&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Word-based analysis with song lyrics</title>
          <pubDate>Wed, 15 Apr 2020 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2020/04/word-based-analysis-with-song-lyrics/</link>
          <guid>https://karnwong.me/posts/2020/04/word-based-analysis-with-song-lyrics/</guid>
          <description xml:base="https://karnwong.me/posts/2020/04/word-based-analysis-with-song-lyrics/">&lt;h2 id=&quot;2023-version-https-github-com-kahnwong-lyrics-analysis&quot;&gt;2023 version: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kahnwong&#x2F;lyrics-analysis&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;kahnwong&#x2F;lyrics-analysis&lt;&#x2F;a&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#2023-version-https-github-com-kahnwong-lyrics-analysis&quot; aria-label=&quot;Anchor link for: 2023-version-https-github-com-kahnwong-lyrics-analysis&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;I listen to a lot of music, mostly symphonic heavy metal. What&#x27;s interesting is that in this genre, each album often has different themes, also each band focus on different topics in terms of lyrics. For instance, Nightwish focuses on nature, and their Imaginaerum album focuses on evolution. So I thought it would be interesting if I apply various text analysis methods to the lyrics, which resulted in this article. Github link &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kahnwong&#x2F;lyrics_visualization&quot;&gt;here&lt;&#x2F;a&gt;!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;techniques-used&quot;&gt;Techniques used&lt;a class=&quot;zola-anchor&quot; href=&quot;#techniques-used&quot; aria-label=&quot;Anchor link for: techniques-used&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;tokenization&lt;&#x2F;li&gt;
&lt;li&gt;stemming and lemming&lt;&#x2F;li&gt;
&lt;li&gt;topic modeling&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;import-modules&quot;&gt;Import modules&lt;a class=&quot;zola-anchor&quot; href=&quot;#import-modules&quot; aria-label=&quot;Anchor link for: import-modules&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; collections&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; Counter&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; matplotlib&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;colors&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; colors&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; matplotlib&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;pyplot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; plt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; numpy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; np&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; pandas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; pd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; seaborn&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; sns&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; nltk&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; word_tokenize&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# from nltk.corpus import stopwords&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; nltk&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;stem&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; PorterStemmer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; sklearn&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;decomposition&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; LatentDirichletAllocation&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-constant&quot;&gt; NMF&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; sklearn&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;feature_extraction&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;text&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; CountVectorizer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; TfidfVectorizer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;set&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;import-data-generated-from-01-get-data-py&quot;&gt;Import data generated from 01_get_data.py&lt;a class=&quot;zola-anchor&quot; href=&quot;#import-data-generated-from-01-get-data-py&quot; aria-label=&quot;Anchor link for: import-data-generated-from-01-get-data-py&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;In this step, I import raw data and convert raw year into a decade, for instance 1993 is in 1990s. I won&#x27;t be doing analysis by decades, because in heavy metal it doesn&#x27;t follow the trend much. But I include it here in case you are working on pop artists. In addition, the differences by year may not be that large, so it makes sense to see it in terms of decades.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;read_csv&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;lyrics.csv&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# dop song duplicates from the same artist&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;drop_duplicates&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;subset&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;artist&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; inplace&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;True&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# tokenize, remove stopwords, stemming and lemming&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# stop_words = set(stopwords.words(&amp;#39;english&amp;#39;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;with&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; open&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;english.txt&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; f&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    stop_words&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt; [&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;strip&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;readlines&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ps&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; PorterStemmer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;tokens&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;lyrics&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;apply&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;    lambda&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable z-parameter z-function z-language z-python&quot;&gt; x&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ps&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;stem&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;w&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; w&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; word_tokenize&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;lower&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt;not&lt;&#x2F;span&gt;&lt;span&gt; w&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; stop_words&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; and&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt;not&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; w&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; and&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;len&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;w&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;    ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# count words&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;word_count&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tokens&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;apply&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt;lambda&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable z-parameter z-function z-language z-python&quot;&gt; x&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; len&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# count unique words&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unique_word_count&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tokens&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;apply&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt;lambda&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable z-parameter z-function z-language z-python&quot;&gt; x&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; len&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-support z-type z-python&quot;&gt;set&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# remove outliers&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;word_count&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# set decade&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;year&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;year&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;astype&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-support z-type z-python&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;1990s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;where&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1990&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;year&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-bitwise&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;year&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1999&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;1990s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; None&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;2000s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;where&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2000&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;year&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-bitwise&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;year&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2009&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;2000s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; None&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;2010s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;where&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2010&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;year&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-bitwise&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;year&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2019&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;2010s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; None&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;2020s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;where&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2020&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;year&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-bitwise&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;year&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2029&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;2020s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; None&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;decade&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;1990s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;combine_first&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;2000s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;combine_first&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;2010s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;combine_first&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;2020s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# drop unused columns&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;drop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;1990s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;2000s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;2010s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;2020s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: right&quot;&gt;&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;artist&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;album&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;title&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;lyrics&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: right&quot;&gt;year&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;tokens&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: right&quot;&gt;word_count&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: right&quot;&gt;unique_word_count&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;decade&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;0&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Nightwish&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Angels Fall First&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Elvenpath&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;(In the sh&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;1996&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;[&#x27;shelter&#x27;, &#x27;shade&#x27;, &#x27;forest&#x27;, ...]&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;121&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;90&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;1990s&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;1&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Nightwish&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Angels Fall First&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Beauty And The Beast&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Remember t&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;1996&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;[&#x27;rememb&#x27;, &#x27;danc&#x27;, &#x27;share&#x27;, ...]&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;74&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;56&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;1990s&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;2&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Nightwish&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Angels Fall First&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;The Carpenter&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Who are yo&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;1996&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;[&#x27;condemn&#x27;, &#x27;shine&#x27;, &#x27;salvat&#x27;, ...]&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;74&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;42&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;1990s&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;3&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Nightwish&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Angels Fall First&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Astral Romance&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;A nocturna&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;1996&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;[&#x27;nocturn&#x27;, &#x27;concerto&#x27;, &#x27;candlelight&#x27;, ...]&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;69&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;68&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;1990s&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;4&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Nightwish&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Angels Fall First&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Angels Fall First&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;An angelfa&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;1996&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;[&#x27;angelfac&#x27;, &#x27;smile&#x27;, &#x27;headlin&#x27;, ...]&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;68&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;49&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;1990s&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;5&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Nightwish&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Angels Fall First&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Tutankhamen&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;As the sun&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;1996&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;[&#x27;sun&#x27;, &#x27;set&#x27;, &#x27;pyramid&#x27;, ...]&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;67&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;41&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;1990s&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;6&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Nightwish&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Angels Fall First&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Nymphomaniac Fantasia&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;The scent&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;1996&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;[&#x27;scent&#x27;, &#x27;woman&#x27;, &#x27;...&#x27;]&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;29&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;28&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;1990s&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;7&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Nightwish&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Angels Fall First&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Know Why The Nightingale Sings&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;What does&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;1996&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;[&#x27;fall&#x27;, &#x27;feel&#x27;, &#x27;boy&#x27;, ...]&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;49&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;47&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;1990s&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;8&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Nightwish&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Angels Fall First&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Lappi (Lapland)&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Part 1: Er&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;1996&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;[&#x27;erämaajärvi&#x27;, &#x27;kautta&#x27;, &#x27;erämaajärven&#x27;, ...]&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;63&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;54&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;1990s&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: right&quot;&gt;9&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Nightwish&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Angels Fall First&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Once Upon A Troubadour&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;A lonely b&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;1996&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;[&#x27;lone&#x27;, &#x27;bard&#x27;, &#x27;wander&#x27;, ...]&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;91&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: right&quot;&gt;62&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;1990s&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;explore-relationship&quot;&gt;Explore relationship&lt;a class=&quot;zola-anchor&quot; href=&quot;#explore-relationship&quot; aria-label=&quot;Anchor link for: explore-relationship&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;From this plot, I can see that there is a correlation between &lt;code&gt;word_count&lt;&#x2F;code&gt; and &lt;code&gt;unique_word_count&lt;&#x2F;code&gt;, that is, they go in the same direction. The higher the word_count, the higher unique_word_count and vice versa.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;g&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;PairGrid&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;word_count&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unique_word_count&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;g&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;map&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;plt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;scatter&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2020&#x2F;04&#x2F;word-based-analysis-with-song-lyrics&#x2F;images&#x2F;2021-08-18-19-02-25.webp&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;boxplot&quot;&gt;Boxplot&lt;a class=&quot;zola-anchor&quot; href=&quot;#boxplot&quot; aria-label=&quot;Anchor link for: boxplot&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;We can use either &lt;code&gt;word_count&lt;&#x2F;code&gt; or &lt;code&gt;unique_word_count&lt;&#x2F;code&gt;, since they go in the same direction, except the values from &lt;code&gt;unique_word_count&lt;&#x2F;code&gt; will be higher, but it is proportional to &lt;code&gt;word_count&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Boxplot represents data distribution in quartiles, in which the the box-y area is in middle of the distribution (think of a bell curve, the box-y area is right around the peak, padded a bit to left and right),  and the line-y area is the left&#x2F;right edge of the curve. The scattered points are outliers, meaning they are too different from the rest of the dataset.&lt;&#x2F;p&gt;
&lt;p&gt;From this figure, I can see that Nightwish has a very large outlier, seeing one data point is in 350 range. Myrath has the least words, and Linkin Park has the most. For Linkin Park, it can be attributed to the fact that their lyrics contain rap verses. As for Nightwish outliers, some of their songs contain very lengthy spoken parts.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;plt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;figure&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;figsize&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;10&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;boxplot&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;word_count&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;artist&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; orient&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2020&#x2F;04&#x2F;word-based-analysis-with-song-lyrics&#x2F;images&#x2F;2021-08-18-19-02-38.webp&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;most-common-words&quot;&gt;Most common words&lt;a class=&quot;zola-anchor&quot; href=&quot;#most-common-words&quot; aria-label=&quot;Anchor link for: most-common-words&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;In this step, I count how many times a word occur per dataset, then plot a bar graph for each. For the bands I usually listen to, each album has a theme, so it&#x27;s very probable that each album would have different set of most common words.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; word_vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable z-parameter z-function z-language z-python&quot;&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;######### make a list of all unique words&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    all_words&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tokens&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        all_words&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;extend&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-support z-type z-python&quot;&gt;set&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    all_words&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-support z-type z-python&quot;&gt; set&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;all_words&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;######### make tf&#x2F;idf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    word_count&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tokens&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;apply&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage&quot;&gt;lambda&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable z-parameter z-function z-language z-python&quot;&gt; x&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; Counter&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    word_count&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;DataFrame&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;word_count&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;to_list&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;######### get sum for each unique word&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    wordcount_sum&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; word_count&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;columns&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        wordcount_sum&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;append&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;word&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;count&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; word_count&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    wordcount_sum&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;DataFrame&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;wordcount_sum&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    wordcount_sum&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; wordcount_sum&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;wordcount_sum&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;count&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    wordcount_sum&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;sort_values&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;by&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;count&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; ascending&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;False&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; inplace&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;True&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;#########&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; wordcount_sum&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;head&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;10&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# get wordcount for each group, this way the word_vector function is not getting messy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;wordcount_group&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;################# adjust filters here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;artist&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Epica&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;group&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;album&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; album, decade&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;#################&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df_temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;artist&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; artist&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; df_temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;group&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;unique&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    chunk&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; word_vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;df_temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;group&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    chunk&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;group&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    wordcount_group&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;append&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;chunk&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;wordcount_group&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;concat&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;wordcount_group&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# plot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fig&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; axs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; plt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;subplots&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;    len&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;wordcount_group&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;group&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;unique&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; figsize&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;13&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 53&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; adjust figure size here if it&amp;#39;s too cramped&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; index&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; enumerate&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;wordcount_group&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;group&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;unique&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; wordcount_group&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;wordcount_group&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;group&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    axs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;index&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;bar&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;word&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;count&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    axs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;index&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;set_title&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2020&#x2F;04&#x2F;word-based-analysis-with-song-lyrics&#x2F;images&#x2F;2021-08-18-19-02-53.webp&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;From the above image, you can see that the top words don&#x27;t vary much between albums. So I can conclude that Epica have a consistent lyric themes, but if you listen you can hear that their melody changes every album. For instance, in The Divine Conspiracy, it&#x27;s very classical and oriental oriented, but in The Holographic Principle it gets heavier.&lt;&#x2F;p&gt;
&lt;p&gt;But that&#x27;s only variations between albums from one artist. What if we do the same but with each artist instead?&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;wordcount_group&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df_temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;group&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;artist&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; df_temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;group&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;unique&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    chunk&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; word_vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;df_temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;group&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    chunk&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;group&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    wordcount_group&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;append&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;chunk&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;wordcount_group&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;concat&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;wordcount_group&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fig&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; axs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; plt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;subplots&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;    len&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;wordcount_group&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;group&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;unique&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; figsize&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;13&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 80&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; adjust figure size here if it&amp;#39;s too cramped&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; index&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; enumerate&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;wordcount_group&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;group&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;unique&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; wordcount_group&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;wordcount_group&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;group&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    axs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;index&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;bar&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;word&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;count&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    axs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;index&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;set_title&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2020&#x2F;04&#x2F;word-based-analysis-with-song-lyrics&#x2F;images&#x2F;2021-08-18-19-03-11.webp&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Whoops. Still more or less the same. But if you look carefully, Powerwolf stands out because their lyrical themes are werewolves and myths.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;topic-modeling&quot;&gt;Topic modeling&lt;a class=&quot;zola-anchor&quot; href=&quot;#topic-modeling&quot; aria-label=&quot;Anchor link for: topic-modeling&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;So I change the tactics a bit by using topic modeling instead of seeing just the top words count. This way, the model and extract group of words that said to be the essence belonging to each cluster. I use both NMF and LDA here for comparison. Here, I tell the model to read lyrics from four artists, then try to group into clusters and finding main words from each, but I&#x27;m not telling it which document belongs to which artist.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; display_topics&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable z-parameter z-function z-language z-python&quot;&gt;model&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-parameters z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable z-parameter z-function z-language z-python&quot;&gt; feature_names&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-parameters z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable z-parameter z-function z-language z-python&quot;&gt; no_top_words&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    topic_words&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; topic_idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; topic&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; enumerate&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;model&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;components_&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Topic &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;%d&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; %&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;topic_idx&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        topic&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;join&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt;            [&lt;&#x2F;span&gt;&lt;span&gt;feature_names&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; topic&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;argsort&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;no_top_words&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;        )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; topic&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        topic_words&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;append&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;topic&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; topic_words&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# define temp dataframe here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;query&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;artist == &amp;quot;Visions of Atlantis&amp;quot; or&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                artist == &amp;quot;Lacuna Coil&amp;quot; or&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                artist == &amp;quot;Epica&amp;quot; or&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;\&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;                artist == &amp;quot;Nightwish&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# define parameters&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;no_features&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;no_topics&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; len&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;artist&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;unique&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; set album count as number of topics&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;no_top_words&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 15&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# create word matrix&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tfidf_vectorizer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; TfidfVectorizer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;    max_df&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0.95&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; min_df&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; max_features&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;no_features&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; stop_words&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;english&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tfidf&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tfidf_vectorizer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;fit_transform&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;temp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;lyrics&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tfidf_feature_names&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tfidf_vectorizer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;get_feature_names&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;print&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;========== NMF ==========&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nmf&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; NMF&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;    n_components&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;no_topics&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; random_state&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; alpha&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0.1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; l1_ratio&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0.5&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; init&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;nndsvd&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;fit&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tfidf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;topic_words&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; display_topics&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;nmf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tfidf_feature_names&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; no_top_words&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;========== NMF ==========&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Topic 0:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; ll time life way light come live free just feel inside ve day let world&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Topic 1:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; love heart night wish forever hate soul dream oh art rest heaven need kiss lust&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Topic 2:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; away run far stay inside journey dream fade just wash felt destruction escape falling walked&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Topic 3:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; don know wanna want just feel say care hate goes cause liar let look reason&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function&quot;&gt;print&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;========== LDA ==========&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lda&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; LatentDirichletAllocation&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;    n_components&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;no_topics&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;    max_iter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;5&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;    learning_method&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;online&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;    learning_offset&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;50.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;    random_state&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;fit&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tfidf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;topic_words&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; display_topics&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;lda&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; tfidf_feature_names&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; no_top_words&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;========== LDA ==========&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Topic 0:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; distance don beautiful let today cold look guide read world way faith wish mind heart&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Topic 1:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; est tale feels talking drives wall wishmaster disciple bone mad searching free master apprentice sing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Topic 2:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; love heart ll hearts time world fight let come night know shadows try eyes mind&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Topic 3:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; leaving ll healing endless sed died walk desire life nos ne moment die nostra like&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;From NMF, I can tell that:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Topic 0 is Epica&lt;&#x2F;li&gt;
&lt;li&gt;Topic 1 is Nightwish&lt;&#x2F;li&gt;
&lt;li&gt;Topic 2 is Visions of Atlantis&lt;&#x2F;li&gt;
&lt;li&gt;Topic 3 is Lacuna Coil&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I think NMF performs better in this case 😆&lt;&#x2F;p&gt;
&lt;p&gt;There are some instances LDA performs better, but generally unless it&#x27;s very obvious from the start, sometimes you use different models and see which performs best for a given dataset.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>ความน่าปวดหัวของการถอดอักษรไทยเป็นตัวโรมัน</title>
          <pubDate>Mon, 06 Jan 2020 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2020/01/khwaamnaapwdhawkh-ngkaarth-d-aksraithyepntaworman/</link>
          <guid>https://karnwong.me/posts/2020/01/khwaamnaapwdhawkh-ngkaarth-d-aksraithyepntaworman/</guid>
          <description xml:base="https://karnwong.me/posts/2020/01/khwaamnaapwdhawkh-ngkaarth-d-aksraithyepntaworman/">&lt;p&gt;*ตัวโรมัน = a b c d e f g ...&lt;&#x2F;p&gt;
&lt;p&gt;วันดีคืนดีชาวต่างชาติอยากมาเมืองไทย แต่จะมาเพราะอะไรนี่ก็ไม่ขอยุ่ง ไม่ได้สู่รู้เบอร์นั้น อนุมานว่ามาจากแถบยุโรป อเมริกาอะไรเทือกนี้ก็น่าจะเครื่องลงที่สุวรรณภูมิ ปัญหาที่จะเจออย่างแรกเลยก็คือ ชื่อป้ายชื่ออะไรไม่ได้ออกเสียงเหมือนที่ตัวโรมันเขียนไว้ เรื่องของเรื่องคือป้ายชื่อในไทยจะใช้ระบบ Royal Thai General System of Transcription ของ ราชบัณฑิตยสถาน แล้วปัญหาหลักๆ เลยก็คือมันไม่ได้สื่อว่าจริงๆ แล้วคำมันควรออกเสียงยังไง เช่น:&lt;&#x2F;p&gt;
&lt;style&gt;.my-black-bordered-table table, th, td { border: 1px solid black; border-collapse: collapse; }&lt;&#x2F;style&gt;
&lt;div class=&quot;ox-hugo-table my-black-bordered-table&quot;&gt;
&lt;div&gt;&lt;&#x2F;div&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Thai&lt;&#x2F;th&gt;&lt;th&gt;Romanization&lt;&#x2F;th&gt;&lt;th&gt;Romanization System&lt;&#x2F;th&gt;&lt;th&gt;Pronunciation&lt;&#x2F;th&gt;&lt;th&gt;Source&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;เทเวศ&lt;&#x2F;td&gt;&lt;td&gt;The-wet&lt;&#x2F;td&gt;&lt;td&gt;RTGS&lt;&#x2F;td&gt;&lt;td&gt;Tae-wet&lt;&#x2F;td&gt;&lt;td&gt;Pali-Sanskrit&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;สุวรรณภูมิ&lt;&#x2F;td&gt;&lt;td&gt;Suvarnabhumi&lt;&#x2F;td&gt;&lt;td&gt;Devanagari transliteration&lt;&#x2F;td&gt;&lt;td&gt;Su-wan*-na-poom &lt;br&gt;*&#x27;a&#x27; as in father&lt;&#x2F;td&gt;&lt;td&gt;Pali-Sanskrit&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;ดินแดง&lt;&#x2F;td&gt;&lt;td&gt;Din-daeng&lt;&#x2F;td&gt;&lt;td&gt;RTGS&lt;&#x2F;td&gt;&lt;td&gt;Din-daeng&lt;&#x2F;td&gt;&lt;td&gt;Thai&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;ศรีราชา&lt;&#x2F;td&gt;&lt;td&gt;Sri Racha&lt;&#x2F;td&gt;&lt;td&gt;Mixed:&lt;br&gt;&lt;strong&gt;Sri&lt;&#x2F;strong&gt; - Devanagari transliteration&lt;br&gt;&lt;strong&gt;Racha&lt;&#x2F;strong&gt; - RTGS&lt;&#x2F;td&gt;&lt;td&gt;See-ra-cha&lt;&#x2F;td&gt;&lt;td&gt;Pali-Sanskrit&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;จะเห็นได้ว่าคำที่ต้นทางมาจากภาษาเดียวกันยังใช้คนละระบบในการถอดอักษรซะงั้น ที่เหนือกว่านั้นคือคำที่มาจาก บาลี-สันสกฤต นี่ก็ดันใช้ทั้งสองระบบถอดเสียงดื้อๆ โดยที่ไม่แคร์ว่าต่างชาติจะงงเบอร์ไหน&lt;&#x2F;p&gt;
&lt;h3 id=&quot;y-n-diitnidnueng&quot;&gt;ย้อนอดีตนิดนึง&lt;a class=&quot;zola-anchor&quot; href=&quot;#y-n-diitnidnueng&quot; aria-label=&quot;Anchor link for: y-n-diitnidnueng&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;คำบาลี-สันสกฤตมีการนำมาใช้ในภาษาไทยเมื่อนานมาแล้ว ผ่านการเผยแพร่ของศาสนาพราหมณ์-ฮินดูในอุษาอาคเนย์&lt;&#x2F;p&gt;
&lt;h3 id=&quot;trngniierimnaaebuue-la-aet-aanhn-ykdii&quot;&gt;ตรงนี้เริ่มน่าเบื่อล่ะ แต่อ่านหน่อยก็ดี&lt;a class=&quot;zola-anchor&quot; href=&quot;#trngniierimnaaebuue-la-aet-aanhn-ykdii&quot; aria-label=&quot;Anchor link for: trngniierimnaaebuue-la-aet-aanhn-ykdii&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;คนบางกลุ่มพอใจที่จะใช้การถอดอักษรแบบราชบัณฑิตกับคำที่มาจาก บาลี-สันสกฤต แต่ต้องเน้นย้ำว่าการถอดอักษรแบบเทวนาครี สามารถแปลงกลับเป็นอักขระไทยได้แบบ 100% ในขณะที่การถอดอักษรแบบราชบัณฑิตจะไม่สามารถแปลงที่ถอดเป็นตัวโรมันกลับเป็นตัวไทยได้อย่างสมบูรณ์ ยกเว้นเสียแต่ว่ารู้กันอยู่แล้วว่ามันคือคำอะไร ก็เลยเขียนเป็นตัวไทยถูก&lt;&#x2F;p&gt;
&lt;p&gt;เพราะฉะนั้น มันเลยกลายเป็นว่าการถอดแบบราชบัณฑิตเป็นความพยายามที่จะเก็บรูปแบบการสะกดคำไทยเอาไว้ แต่มันไม่ได้สอดคล้องกับการออกเสียงของคำนั้นจริงๆ&lt;&#x2F;p&gt;
&lt;h3 id=&quot;srup&quot;&gt;สรุป&lt;a class=&quot;zola-anchor&quot; href=&quot;#srup&quot; aria-label=&quot;Anchor link for: srup&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;ไทยใช้ระบบราชบัณฑิตยสถานในการถอดอักขระเป็นโรมัน แต่ปัญหาคือมันไม่สามารถแปลงกลับเป็นตัวไทยได้อย่างสมบูรณ์ แต่ถ้าถอดอักษรคำที่มาจากบาลี-สันสกฤตโดยใช้ระบบเทวนาครีก็ติดประเด็นเดิมคือมันไม่ได้สอดคล้องกับการออกเสียงจริงๆ&lt;&#x2F;p&gt;
&lt;h3 id=&quot;kh-ngaethm&quot;&gt;ของแถม&lt;a class=&quot;zola-anchor&quot; href=&quot;#kh-ngaethm&quot; aria-label=&quot;Anchor link for: kh-ngaethm&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;จะลืมพูดถึงระบบการถอดอักษรอีกแบบไม่ได้ นั่นก็คือ: ฉันจะสะกดตามใจฉัน&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Loanwords are okay</title>
          <pubDate>Wed, 06 Nov 2019 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2019/11/loanwords-are-okay/</link>
          <guid>https://karnwong.me/posts/2019/11/loanwords-are-okay/</guid>
          <description xml:base="https://karnwong.me/posts/2019/11/loanwords-are-okay/">&lt;p&gt;Does it matter if you language has a lot of loanwords? To be considered a loan, it has to be of foreign origin, and speakers from the borrowing end can understand and use in various contexts. It&#x27;s perfectly okay for the meaning to shift on the borrowing end, as semantic shift happens naturally. It does not make the word &quot;unpure&quot; or anything, it&#x27;s just how things happen. The borrowing language may have different point of view or context, so not all properties from the source can be carried over. This phenomenon has been going on since antiquity, where people from different groups interacting with each other. Consider the following loan:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Freshy&lt;&#x2F;strong&gt; - &lt;em&gt;n&lt;&#x2F;em&gt;. a college freshman&lt;&#x2F;p&gt;
&lt;p&gt;In English, a first year college student is known as a freshman. In Thailand, the term freshy is used instead. Does it deteriorate English in any way? No, because English does the same to many loans. Thai is not the only guilty party. Not that I&#x27;m implying there&#x27;s anything wrong with it.&lt;&#x2F;p&gt;
&lt;p&gt;Loanwords also enrich a language by providing new concepts and ideas. Loanwords are not evil. But some people would have you believe that loanwords must be eradicated to keep a language pure. French tries to do this and fail miserably. Influx of new loans through mass media and internet are coming through faster than The Académie française can process and dissimenate the French version to the public.&lt;&#x2F;p&gt;
&lt;p&gt;Who are they to think they can curb the wax and wane of French language. People speak however they want. What is correct and standard then sound foreign to our modern-day ears. What sounds natural to us today may be ancient history to a few generations later. Languages always change. It doesn&#x27;t only when no one uses it anymore - like Latin.&lt;&#x2F;p&gt;
&lt;p&gt;Just like food, many people like Japanese food - sushi, gyoza, to name a few. Foreign doesn&#x27;t mean bad. Just that some people want you to think it is.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Indic name mistransliteration in Thai version of Harry Potter</title>
          <pubDate>Wed, 10 Oct 2018 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2018/10/indic-name-mistransliteration-in-thai-version-of-harry-potter/</link>
          <guid>https://karnwong.me/posts/2018/10/indic-name-mistransliteration-in-thai-version-of-harry-potter/</guid>
          <description xml:base="https://karnwong.me/posts/2018/10/indic-name-mistransliteration-in-thai-version-of-harry-potter/">&lt;p&gt;I read Harry Potter as a kid, and I couldn&#x27;t shake the feeling that one character&#x27;s name is a bit off. I couldn&#x27;t quite pinpoint exactly why. Turns out, my hunch was right – the Thai translator used the wrong transliteration.&lt;&#x2F;p&gt;
&lt;p&gt;In Thai, &quot;Parvati Patil&quot; is &quot;ปาราวตี พาติล.&quot; This doesn&#x27;t even match the English transliteration (from Indic), as seen by a completely messed up second syllable on the first name. Because Thai language has a lot of influences from Indic, we also have our own system of transliterating Indic to Thai. Using this system, the correct transliteration for &quot;Parvati&quot; is &quot;ปารวตี&quot; (the second &lt;em&gt;a&lt;&#x2F;em&gt; is a schwa). As for the last name &quot;Patil,&quot; it&#x27;s &quot;ปาฏีล.&quot;&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Romanization&lt;&#x2F;th&gt;&lt;th&gt;Devanagari&lt;&#x2F;th&gt;&lt;th&gt;Thai (wrong)&lt;&#x2F;th&gt;&lt;th&gt;Thai (correct)&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Parvati&lt;&#x2F;td&gt;&lt;td&gt;पार्वती&lt;&#x2F;td&gt;&lt;td&gt;ปาราวตี&lt;&#x2F;td&gt;&lt;td&gt;ปารวตี&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Patil&lt;&#x2F;td&gt;&lt;td&gt;पाटील&lt;&#x2F;td&gt;&lt;td&gt;พาติล&lt;&#x2F;td&gt;&lt;td&gt;ปาฏีล&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Notice that the first character from the first name in Devanagari are the same, which means the Thai transliteration is wrong (ป in first name and พ in last name).&lt;&#x2F;p&gt;
&lt;p&gt;What a far cry from the kosher transliteration. But how could you blame the Thai translator? She specializes in English after all, not Indic. To me, she tried her best to get around transliterating a name she isn&#x27;t even familiar with, let alone know of an existing system to transliterate it.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Definition of &#x27;a Word&#x27;</title>
          <pubDate>Mon, 30 Jul 2018 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2018/07/definition-of-a-word/</link>
          <guid>https://karnwong.me/posts/2018/07/definition-of-a-word/</guid>
          <description xml:base="https://karnwong.me/posts/2018/07/definition-of-a-word/">&lt;p&gt;You often hear people say &quot;you need to know x words in y language to be able to understand basic conversations.&quot;. This is a bit misleading, since the definition of &quot;word&quot; is varied. For example, in Chinese (yes, I know, Chinese as a language doesn&#x27;t exist, but I digress) one character (one block) is one word. So this is easy. Then you have Japanese, where the same kanji (Hanzi, Chinese characters) can be pronounced differently, each with different meaning. You would assume Korean is the same way, right? That one &quot;block&quot; is one character. It is not the case, however. Korean is agglutinative language, which means you can stack suffixes just like Finnish and Turkish to morph a word.&lt;&#x2F;p&gt;
&lt;p&gt;Then you have English, which is quite clear how a word can be counted because it has space. What about languages that write words together without space? One could argue that Thai is like Chinese, that it has no conjugations and you can append a bunch of words together to form a sentence. The difference is in Thai, you would have to mentally break up each word. For example, the &quot;word&quot; &quot;ตากลม&quot; can be separated two ways: &quot;ตาก-ลม&quot; and &quot;ตา-กลม,&quot; again, with different meaning.&lt;&#x2F;p&gt;
&lt;p&gt;And in Semitic languages, words are based on tri-root system, where you put consonants into a vowel pattern to conjugate. Speaking of conjugations, run, running and runner are from the same root, but would you consider them different words?&lt;&#x2F;p&gt;
&lt;p&gt;As you can see, how a word is defined is different. Some may argue different conjugations is enough to make it a new word. So if you know basic conjugations, say, five of them, and you know five root words. Now you know 25 words. Yay! Right?&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Resettled refugees in Sweden</title>
          <pubDate>Mon, 30 Jul 2018 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2018/07/resettled-refugees-in-sweden/</link>
          <guid>https://karnwong.me/posts/2018/07/resettled-refugees-in-sweden/</guid>
          <description xml:base="https://karnwong.me/posts/2018/07/resettled-refugees-in-sweden/">&lt;p&gt;One of my friends is a Syrian refugee, who was granted asylum in Sweden last year. I also want to try data analysis, so it fits that I should analyze something that&#x27;s relevant to my friend. This is my first ever analysis in pandas, apologies for code abomination in advance.&lt;&#x2F;p&gt;
&lt;p&gt;In this analysis, I use pandas for dataframe, numpy for dealing with numbers (because I need to count and do some math with it) and matplotlib for plotting graphs.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; numpy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; np&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; pandas&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; pd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; matplotlib&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;pyplot&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; plt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt;%&lt;&#x2F;span&gt;&lt;span&gt;matplotlib&lt;&#x2F;span&gt;&lt;span&gt; inline&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The next step is to clean up the dataframe for further analysis. The steps are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Read csv&lt;&#x2F;li&gt;
&lt;li&gt;Group by origin country and year resettled&lt;&#x2F;li&gt;
&lt;li&gt;Remove destination country column (because it&#x27;s the same value)&lt;&#x2F;li&gt;
&lt;li&gt;Remove non-integer values (because you can&#x27;t do math magic with it)&lt;&#x2F;li&gt;
&lt;li&gt;Convert year and value to integer (hello, math magic)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# data prep&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;read_csv&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;unhcr_resettlement_residence_swe.csv&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;groupby&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Origin&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Year&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; as_index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;False&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; group by two columns&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;drop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Country &#x2F; territory of asylum&#x2F;residence&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; axis&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; drop destination country column&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;all&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; remove any rows that has &amp;#39;*&amp;#39; value&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Year&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Year&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;astype&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;int64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; convert year to int&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;astype&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;int64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; convert value to int&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;style&gt;.my-black-bordered-table table, th, td { border: 1px solid black; border-collapse: collapse; }&lt;&#x2F;style&gt;
&lt;div class=&quot;ox-hugo-table my-black-bordered-table&quot;&gt;
&lt;div&gt;&lt;&#x2F;div&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;&#x2F;th&gt;&lt;th&gt;Origin&lt;&#x2F;th&gt;&lt;th&gt;Year&lt;&#x2F;th&gt;&lt;th&gt;Value&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;Afghanistan&lt;&#x2F;td&gt;&lt;td&gt;1984&lt;&#x2F;td&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;Afghanistan&lt;&#x2F;td&gt;&lt;td&gt;1985&lt;&#x2F;td&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;Afghanistan&lt;&#x2F;td&gt;&lt;td&gt;1986&lt;&#x2F;td&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;Afghanistan&lt;&#x2F;td&gt;&lt;td&gt;1987&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;Afghanistan&lt;&#x2F;td&gt;&lt;td&gt;1988&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;Afghanistan&lt;&#x2F;td&gt;&lt;td&gt;1991&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;Afghanistan&lt;&#x2F;td&gt;&lt;td&gt;1992&lt;&#x2F;td&gt;&lt;td&gt;18&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;Afghanistan&lt;&#x2F;td&gt;&lt;td&gt;1997&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;Afghanistan&lt;&#x2F;td&gt;&lt;td&gt;1998&lt;&#x2F;td&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;td&gt;Afghanistan&lt;&#x2F;td&gt;&lt;td&gt;1999&lt;&#x2F;td&gt;&lt;td&gt;16&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;td&gt;Afghanistan&lt;&#x2F;td&gt;&lt;td&gt;2000&lt;&#x2F;td&gt;&lt;td&gt;339&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;11&lt;&#x2F;td&gt;&lt;td&gt;Afghanistan&lt;&#x2F;td&gt;&lt;td&gt;2001&lt;&#x2F;td&gt;&lt;td&gt;270&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;12&lt;&#x2F;td&gt;&lt;td&gt;Afghanistan&lt;&#x2F;td&gt;&lt;td&gt;2002&lt;&#x2F;td&gt;&lt;td&gt;156&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;13&lt;&#x2F;td&gt;&lt;td&gt;Afghanistan&lt;&#x2F;td&gt;&lt;td&gt;2003&lt;&#x2F;td&gt;&lt;td&gt;244&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;14&lt;&#x2F;td&gt;&lt;td&gt;Afghanistan&lt;&#x2F;td&gt;&lt;td&gt;2004&lt;&#x2F;td&gt;&lt;td&gt;314&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;15&lt;&#x2F;td&gt;&lt;td&gt;Afghanistan&lt;&#x2F;td&gt;&lt;td&gt;2005&lt;&#x2F;td&gt;&lt;td&gt;183&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;16&lt;&#x2F;td&gt;&lt;td&gt;Afghanistan&lt;&#x2F;td&gt;&lt;td&gt;2006&lt;&#x2F;td&gt;&lt;td&gt;353&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;17&lt;&#x2F;td&gt;&lt;td&gt;Afghanistan&lt;&#x2F;td&gt;&lt;td&gt;2007&lt;&#x2F;td&gt;&lt;td&gt;185&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;18&lt;&#x2F;td&gt;&lt;td&gt;Afghanistan&lt;&#x2F;td&gt;&lt;td&gt;2008&lt;&#x2F;td&gt;&lt;td&gt;414&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;19&lt;&#x2F;td&gt;&lt;td&gt;Afghanistan&lt;&#x2F;td&gt;&lt;td&gt;2009&lt;&#x2F;td&gt;&lt;td&gt;318&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;20&lt;&#x2F;td&gt;&lt;td&gt;Afghanistan&lt;&#x2F;td&gt;&lt;td&gt;2010&lt;&#x2F;td&gt;&lt;td&gt;336&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;21&lt;&#x2F;td&gt;&lt;td&gt;Afghanistan&lt;&#x2F;td&gt;&lt;td&gt;2011&lt;&#x2F;td&gt;&lt;td&gt;404&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;22&lt;&#x2F;td&gt;&lt;td&gt;Afghanistan&lt;&#x2F;td&gt;&lt;td&gt;2012&lt;&#x2F;td&gt;&lt;td&gt;438&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;23&lt;&#x2F;td&gt;&lt;td&gt;Afghanistan&lt;&#x2F;td&gt;&lt;td&gt;2013&lt;&#x2F;td&gt;&lt;td&gt;219&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;24&lt;&#x2F;td&gt;&lt;td&gt;Afghanistan&lt;&#x2F;td&gt;&lt;td&gt;2014&lt;&#x2F;td&gt;&lt;td&gt;328&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;25&lt;&#x2F;td&gt;&lt;td&gt;Afghanistan&lt;&#x2F;td&gt;&lt;td&gt;2015&lt;&#x2F;td&gt;&lt;td&gt;222&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;26&lt;&#x2F;td&gt;&lt;td&gt;Afghanistan&lt;&#x2F;td&gt;&lt;td&gt;2016&lt;&#x2F;td&gt;&lt;td&gt;20&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;27&lt;&#x2F;td&gt;&lt;td&gt;Albania&lt;&#x2F;td&gt;&lt;td&gt;1991&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;28&lt;&#x2F;td&gt;&lt;td&gt;Albania&lt;&#x2F;td&gt;&lt;td&gt;1992&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;29&lt;&#x2F;td&gt;&lt;td&gt;Albania&lt;&#x2F;td&gt;&lt;td&gt;2003&lt;&#x2F;td&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;...&lt;&#x2F;td&gt;&lt;td&gt;...&lt;&#x2F;td&gt;&lt;td&gt;...&lt;&#x2F;td&gt;&lt;td&gt;...&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;705&lt;&#x2F;td&gt;&lt;td&gt;Various&#x2F;unknown&lt;&#x2F;td&gt;&lt;td&gt;2009&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;706&lt;&#x2F;td&gt;&lt;td&gt;Various&#x2F;unknown&lt;&#x2F;td&gt;&lt;td&gt;2013&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;707&lt;&#x2F;td&gt;&lt;td&gt;Venezuela (Bolivarian Republic of)&lt;&#x2F;td&gt;&lt;td&gt;2015&lt;&#x2F;td&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;708&lt;&#x2F;td&gt;&lt;td&gt;Viet Nam&lt;&#x2F;td&gt;&lt;td&gt;1984&lt;&#x2F;td&gt;&lt;td&gt;76&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;709&lt;&#x2F;td&gt;&lt;td&gt;Viet Nam&lt;&#x2F;td&gt;&lt;td&gt;1985&lt;&#x2F;td&gt;&lt;td&gt;48&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;710&lt;&#x2F;td&gt;&lt;td&gt;Viet Nam&lt;&#x2F;td&gt;&lt;td&gt;1986&lt;&#x2F;td&gt;&lt;td&gt;171&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;711&lt;&#x2F;td&gt;&lt;td&gt;Viet Nam&lt;&#x2F;td&gt;&lt;td&gt;1987&lt;&#x2F;td&gt;&lt;td&gt;232&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;712&lt;&#x2F;td&gt;&lt;td&gt;Viet Nam&lt;&#x2F;td&gt;&lt;td&gt;1988&lt;&#x2F;td&gt;&lt;td&gt;94&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;713&lt;&#x2F;td&gt;&lt;td&gt;Viet Nam&lt;&#x2F;td&gt;&lt;td&gt;1990&lt;&#x2F;td&gt;&lt;td&gt;939&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;714&lt;&#x2F;td&gt;&lt;td&gt;Viet Nam&lt;&#x2F;td&gt;&lt;td&gt;1991&lt;&#x2F;td&gt;&lt;td&gt;656&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;715&lt;&#x2F;td&gt;&lt;td&gt;Viet Nam&lt;&#x2F;td&gt;&lt;td&gt;1992&lt;&#x2F;td&gt;&lt;td&gt;474&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;716&lt;&#x2F;td&gt;&lt;td&gt;Viet Nam&lt;&#x2F;td&gt;&lt;td&gt;1993&lt;&#x2F;td&gt;&lt;td&gt;197&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;717&lt;&#x2F;td&gt;&lt;td&gt;Viet Nam&lt;&#x2F;td&gt;&lt;td&gt;1994&lt;&#x2F;td&gt;&lt;td&gt;32&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;718&lt;&#x2F;td&gt;&lt;td&gt;Viet Nam&lt;&#x2F;td&gt;&lt;td&gt;1995&lt;&#x2F;td&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;719&lt;&#x2F;td&gt;&lt;td&gt;Viet Nam&lt;&#x2F;td&gt;&lt;td&gt;1997&lt;&#x2F;td&gt;&lt;td&gt;21&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;720&lt;&#x2F;td&gt;&lt;td&gt;Viet Nam&lt;&#x2F;td&gt;&lt;td&gt;2002&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;721&lt;&#x2F;td&gt;&lt;td&gt;Viet Nam&lt;&#x2F;td&gt;&lt;td&gt;2004&lt;&#x2F;td&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;722&lt;&#x2F;td&gt;&lt;td&gt;Viet Nam&lt;&#x2F;td&gt;&lt;td&gt;2006&lt;&#x2F;td&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;723&lt;&#x2F;td&gt;&lt;td&gt;Viet Nam&lt;&#x2F;td&gt;&lt;td&gt;2009&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;724&lt;&#x2F;td&gt;&lt;td&gt;Viet Nam&lt;&#x2F;td&gt;&lt;td&gt;2010&lt;&#x2F;td&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;726&lt;&#x2F;td&gt;&lt;td&gt;Yemen&lt;&#x2F;td&gt;&lt;td&gt;1992&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;727&lt;&#x2F;td&gt;&lt;td&gt;Yemen&lt;&#x2F;td&gt;&lt;td&gt;2004&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;728&lt;&#x2F;td&gt;&lt;td&gt;Yemen&lt;&#x2F;td&gt;&lt;td&gt;2005&lt;&#x2F;td&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;729&lt;&#x2F;td&gt;&lt;td&gt;Yemen&lt;&#x2F;td&gt;&lt;td&gt;2006&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;730&lt;&#x2F;td&gt;&lt;td&gt;Zimbabwe&lt;&#x2F;td&gt;&lt;td&gt;2006&lt;&#x2F;td&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;731&lt;&#x2F;td&gt;&lt;td&gt;Zimbabwe&lt;&#x2F;td&gt;&lt;td&gt;2008&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;732&lt;&#x2F;td&gt;&lt;td&gt;Zimbabwe&lt;&#x2F;td&gt;&lt;td&gt;2011&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;733&lt;&#x2F;td&gt;&lt;td&gt;Zimbabwe&lt;&#x2F;td&gt;&lt;td&gt;2014&lt;&#x2F;td&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;734&lt;&#x2F;td&gt;&lt;td&gt;Zimbabwe&lt;&#x2F;td&gt;&lt;td&gt;2015&lt;&#x2F;td&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;735&lt;&#x2F;td&gt;&lt;td&gt;Zimbabwe&lt;&#x2F;td&gt;&lt;td&gt;2016&lt;&#x2F;td&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;725 rows × 3 columns&lt;&#x2F;p&gt;
&lt;p&gt;Since I want to plot a multiple line graph, I need to supply one dataframe per each line. This step is to create one dataframe per source country and clean it up. For example, if there is one year where no refugees are resettled, that year doesn&#x27;t exist in the dataframe, so I have to check whether the years are missing or not, and if missing, create it and set the value to 0.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# create one dataframe per one origin country&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;UniqueNames&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Origin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;unique&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;DataFrameDict&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span&gt;elem&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; pd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;DataFrame&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; elem&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; UniqueNames&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; key&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; DataFrameDict&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;keys&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    DataFrameDict&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;key&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Origin&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-comparison&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; key&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; clean_up_dataframe&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable z-parameter z-function z-language z-python&quot;&gt;df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    country&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Origin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;unique&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    df&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;drop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Origin&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; axis&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Year&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    df&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;drop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Year&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt; axis&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    df&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;rename&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; country&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    df2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;DataFrame&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Year&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1983&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2016&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-arithmetic&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; country&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; dummy dataframe&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    df2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;index&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Year&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    df2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;country&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;country&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    df2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;fillna&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    df2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;country&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; df2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And because Syria is in the Middle East, I want to focus in the MENA region (Middle East and North Africa). However, the list is too big, and I&#x27;ve yet to figure out how to make it look pretty. What I do instead is group countries into each subregion and plot them.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# original MENA, too big&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;UniqueNames_og_mena&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Algeria&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Bahrain&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Djibouti&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Egypt&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Iran&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Iraq&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Israel&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Jordan&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Kuwait&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Lebanon&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Libya&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Mauritania&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Morocco&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Oman&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Palestine&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Qatar&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Sahrawi Arab Democratic Republic&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Saudi Arabia&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Somalia&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Sudan&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Syria&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Tunisia&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;United Arab Emirates&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Yemen&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Afghanistan&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Armenia&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Azerbaijan&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Chad&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Comoros&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Cyprus&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Eritrea&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Georgia&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Mali&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Niger&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Pakistan&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Turkey&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# MENA&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;UniqueNames_mena&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Algeria&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Bahrain&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Djibouti&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Egypt&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Iran (Islamic Rep. of)&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Iraq&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Jordan&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Kuwait&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Lebanon&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Libya&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Mauritania&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Saudi Arabia&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Somalia&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Sudan&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Syrian Arab Rep.&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Tunisia&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Yemen&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Afghanistan&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Armenia&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Azerbaijan&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Chad&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Eritrea&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Georgia&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Pakistan&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Turkey&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# LEVANT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;UniqueNames_levant&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Iraq&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Jordan&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Lebanon&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Syrian Arab Rep.&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# NORTH AFRICA&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;UniqueNames_north_africa&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-begin z-python&quot;&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Algeria&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Djibouti&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Egypt&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Libya&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Mauritania&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Somalia&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Sudan&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Tunisia&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Chad&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Eritrea&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-list z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; plot&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable z-parameter z-function z-language z-python&quot;&gt;region_name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-parameters z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable z-parameter z-function z-language z-python&quot;&gt; region_list&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    df1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; clean_up_dataframe&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;DataFrameDict&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;region_list&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ax&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; df1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;plot&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;figsize&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;15&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-element z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-parenthesis z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; region_list&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        df&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt; clean_up_dataframe&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;DataFrameDict&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        df&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;plot&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-variable&quot;&gt;ax&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;ax&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    plt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;xlabel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Year&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    plt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;ylabel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    plt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Resettled Refugees in Sweden from &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; Region Between 1983-2016&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;format&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            region_name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;        )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;    )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ax&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;legend&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    plt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-period z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;show&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;# plot(&amp;#39;All MENA&amp;#39;, UniqueNames_og_mena) # list is too big&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;plot&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;MENA&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; UniqueNames_mena&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2018&#x2F;07&#x2F;resettled-refugees-in-sweden&#x2F;images&#x2F;2021-08-18-18-49-07.webp&quot; alt=&quot;2021 08 18 18 49 07 image&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You can see that a lot of Iraqi refugees resettled between 1990-1995, which coincides with the Gulf War (1990-1).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;plot&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Levant&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; UniqueNames_levant&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2018&#x2F;07&#x2F;resettled-refugees-in-sweden&#x2F;images&#x2F;2021-08-18-18-51-31.webp&quot; alt=&quot;2021 08 18 18 51 31 image&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This graph shows only refugees from the Levant region. As expected, a lot of Iraqis sought asylum during the 90&#x27;s, but Syrian refugees spiked up after 2010, which coincides with Arab Spring (2010-2).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-generic z-python&quot;&gt;plot&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;North Africa&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; UniqueNames_north_africa&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;karnwong.me&#x2F;posts&#x2F;2018&#x2F;07&#x2F;resettled-refugees-in-sweden&#x2F;images&#x2F;2021-08-18-18-51-58.webp&quot; alt=&quot;2021 08 18 18 51 58 image&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In North Africa, Somalian refugees spiked up around 2010, which is the result from non-functioning government, which resulted in rising clan wars. Additionally, you can see that there are a lot of Eritrean refugees too, from indefinite conscription. Families of those who fled the military are also targeted.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>How angur became องุ่น</title>
          <pubDate>Thu, 23 Nov 2017 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2017/11/how-angur-became-ngun/</link>
          <guid>https://karnwong.me/posts/2017/11/how-angur-became-ngun/</guid>
          <description xml:base="https://karnwong.me/posts/2017/11/how-angur-became-ngun/">&lt;p&gt;More often than not, Thai loanwords are of Indic, Khmer, English or Chinese origin. Although loans from other languages do exist. For instance, องุ่น (grape). This word is of Persian origin (read: Iran), which is انگور, literally angur. In Thai it&#x27;s angun. Notice that it&#x27;s &lt;strong&gt;n&lt;&#x2F;strong&gt; at the end instead of the original &lt;strong&gt;r&lt;&#x2F;strong&gt;. The reason is because in Thai &lt;strong&gt;r&lt;&#x2F;strong&gt; as &lt;strong&gt;end consonant&lt;&#x2F;strong&gt; doesn&#x27;t exist, instead substituted with &lt;strong&gt;n&lt;&#x2F;strong&gt;. For example, the Sanskrit loanword &lt;strong&gt;ahar&lt;&#x2F;strong&gt; is pronounced as &lt;strong&gt;aha[n]&lt;&#x2F;strong&gt; in Thai.&lt;&#x2F;p&gt;
&lt;p&gt;Rose is also borrowed from Persian –  گلاب‏, literally gulab. Same in Thai except for some reason they make &lt;strong&gt;lab&lt;&#x2F;strong&gt; a rising tone. Which is a step up from Persian pronunciation (which is in high tone).&lt;&#x2F;p&gt;
&lt;p&gt;Cigarette is also borrowed from Persian - بوری‏, literally Bure (e as in see). I&#x27;m sure in Thai they changed the tone as well, and I&#x27;m yet to find out its Persian pronunciation.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ll update when I know how they really pronounce بوری‏.&lt;&#x2F;p&gt;
&lt;p&gt;Edit: apparently Thai short vowel is longer than Persian. So for Thais to pronounce gulab the Persian way they would have to pronounce the &quot;gu&quot; shorter and decrease the tone associated with &quot;lab&quot; down a notch.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>The confusing case of Thai romanization system</title>
          <pubDate>Thu, 14 Sep 2017 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://karnwong.me/posts/2017/09/the-confusing-case-of-thai-romanization-system/</link>
          <guid>https://karnwong.me/posts/2017/09/the-confusing-case-of-thai-romanization-system/</guid>
          <description xml:base="https://karnwong.me/posts/2017/09/the-confusing-case-of-thai-romanization-system/">&lt;p&gt;You decided to visit Thailand for whatever reason I don&#x27;t want to know. (It&#x27;s not my business.) Assuming you&#x27;re in from outside of Asia, you&#x27;ll land at Suvarnabhumi Airport. The problem? The locals don&#x27;t pronounce it that way. All the names and signs here are romanized using the Royal Thai General System of Transcription (RTGS). The big problem with this is that it is light years away of what Thais actually pronounce. For example:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Thai&lt;&#x2F;th&gt;&lt;th&gt;Romanization&lt;&#x2F;th&gt;&lt;th&gt;Romanization System&lt;&#x2F;th&gt;&lt;th&gt;Pronunciation&lt;&#x2F;th&gt;&lt;th&gt;Source&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;เทเวศ&lt;&#x2F;td&gt;&lt;td&gt;The-wet&lt;&#x2F;td&gt;&lt;td&gt;RTGS&lt;&#x2F;td&gt;&lt;td&gt;Tae-wet&lt;&#x2F;td&gt;&lt;td&gt;Pali-Sanskrit&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;สุวรรณภูมิ&lt;&#x2F;td&gt;&lt;td&gt;Suvarnabhumi&lt;&#x2F;td&gt;&lt;td&gt;Devanagari transliteration&lt;&#x2F;td&gt;&lt;td&gt;Su-wan*-na-poom &lt;br&gt;*&#x27;a&#x27; as in father&lt;&#x2F;td&gt;&lt;td&gt;Pali-Sanskrit&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;ดินแดง&lt;&#x2F;td&gt;&lt;td&gt;Din-daeng&lt;&#x2F;td&gt;&lt;td&gt;RTGS&lt;&#x2F;td&gt;&lt;td&gt;Din-daeng&lt;&#x2F;td&gt;&lt;td&gt;Thai&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;ศรีราชา&lt;&#x2F;td&gt;&lt;td&gt;Sri Racha&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;Sri&lt;&#x2F;strong&gt; - Devanagari transliteration,&lt;br&gt; &lt;strong&gt;Racha&lt;&#x2F;strong&gt; - RTGS&lt;&#x2F;td&gt;&lt;td&gt;See-ra-cha&lt;&#x2F;td&gt;&lt;td&gt;Pali-Sanskrit&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;As you can see, even words from the same source still use different romanization system. The best of all is a word of Pali-Sanskrit origin can also use both systems to romanize. In the same word. Gott hilf mir.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;some-history&quot;&gt;Some history&lt;a class=&quot;zola-anchor&quot; href=&quot;#some-history&quot; aria-label=&quot;Anchor link for: some-history&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h4&gt;
&lt;p&gt;A lot of words from Pali-Sanskrit entered the Thai language some time before 1500&#x27;s. (Can&#x27;t even find a source as to how it got into Thai and what it was used for.)&lt;&#x2F;p&gt;
&lt;h3 id=&quot;boring-bits-that-you-should-read&quot;&gt;Boring bits (that you should read)&lt;a class=&quot;zola-anchor&quot; href=&quot;#boring-bits-that-you-should-read&quot; aria-label=&quot;Anchor link for: boring-bits-that-you-should-read&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Some people prefer words of Pali-Sanskrit origin to be romanized using Devanagari transliteration. I should note that Devanagari transliteration is &lt;em&gt;lossless&lt;&#x2F;em&gt; whereas RTGS is &lt;em&gt;lossy&lt;&#x2F;em&gt;. It means that transliteration via the Devanagari system can be transliterate back and forth without mutating the characters whereas RTGS transliteration can&#x27;t be transliterate back to Thai unless you already know how it&#x27;s spelled in Thai.&lt;&#x2F;p&gt;
&lt;p&gt;Hence all the problems. RTGS is trying to represent how Thai words are spelled but it does not represent how it&#x27;s pronounced.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary-in-case-you-still-don-t-get-it&quot;&gt;Summary in case you still don&#x27;t get it&lt;a class=&quot;zola-anchor&quot; href=&quot;#summary-in-case-you-still-don-t-get-it&quot; aria-label=&quot;Anchor link for: summary-in-case-you-still-don-t-get-it&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Thai uses RTGS to romanize but the problem is that you can&#x27;t convert it back to Thai and it does not represent how a word is pronounced by Thais. However, words of Pali-Sanskrit origin can sometimes be romanized using Devanagari transliteration, which again is not even close to what Thais pronounce.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;bonus&quot;&gt;Bonus&lt;a class=&quot;zola-anchor&quot; href=&quot;#bonus&quot; aria-label=&quot;Anchor link for: bonus&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;There&#x27;s another romanization system called &quot;whatever I damn well please use to romanize.&quot;&lt;&#x2F;p&gt;
</description>
      </item>
    </channel>
</rss>
