<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Varun D</title>
    <description>The latest articles on DEV Community by Varun D (@vee_atnameless).</description>
    <link>https://dev.to/vee_atnameless</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1176247%2F7f886fd1-fb23-4f9f-ba44-83b0376cd9bc.jpeg</url>
      <title>DEV Community: Varun D</title>
      <link>https://dev.to/vee_atnameless</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vee_atnameless"/>
    <language>en</language>
    <item>
      <title>[Claude Code] Super Simple Statusline</title>
      <dc:creator>Varun D</dc:creator>
      <pubDate>Wed, 04 Mar 2026 08:15:41 +0000</pubDate>
      <link>https://dev.to/vee_atnameless/claude-code-super-simple-statusline-1lbp</link>
      <guid>https://dev.to/vee_atnameless/claude-code-super-simple-statusline-1lbp</guid>
      <description>&lt;p&gt;&lt;a href="https://code.claude.com/docs/en/statusline" rel="noopener noreferrer"&gt;Official documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1jy83o5j57jtylqjdc19.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1jy83o5j57jtylqjdc19.png" alt="Super Simple Statusline for Claude Code" width="800" height="227"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tested on Mac&lt;/p&gt;

&lt;p&gt;This Super Simple Statusline shows Model Name, input token count, output token count, context progress bar + % and git status if available.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Install jq command line tool
&lt;/h2&gt;

&lt;p&gt;JQ makes json parsing easier&lt;/p&gt;

&lt;p&gt;&lt;a href="https://jqlang.org/download/" rel="noopener noreferrer"&gt;JQ installation&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Enable statusline in Claude Code settings
&lt;/h2&gt;

&lt;p&gt;Modify your settings.json file found in top level .claude folder ~/.claude/settings.json.&lt;br&gt;
If the file doesn't exist, &lt;strong&gt;create it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Enable statusline&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"statusLine"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"~/.claude/statusline.sh"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"padding"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Create statusline file and make it executable
&lt;/h2&gt;

&lt;p&gt;Create statusline.sh file in the same folder&lt;/p&gt;

&lt;p&gt;You can name it anything but make sure file path is the same in "command" in the settings.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;touch ~/.claude/statusline.sh&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Make it executable
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;chmod +x ~/.claude/statusline.sh&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Write the statusline script to statusline.sh
&lt;/h3&gt;

&lt;p&gt;This Super Simple Statusline file shows Model Name, input token count, output token count and context % progress bar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# Read JSON data that Claude Code sends to stdin&lt;/span&gt;
&lt;span class="c"&gt;# Remember to install jq to extract data from json string, makes it easier&lt;/span&gt;
&lt;span class="c"&gt;# You can piple json in text format to test the script&lt;/span&gt;
&lt;span class="nv"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Set color variables. Escape sequences can vary by system, bash, zsh, etc.&lt;/span&gt;
&lt;span class="nv"&gt;GREEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;$'&lt;/span&gt;&lt;span class="se"&gt;\0&lt;/span&gt;&lt;span class="s1"&gt;33[32m'&lt;/span&gt;
&lt;span class="nv"&gt;YELLOW&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;$'&lt;/span&gt;&lt;span class="se"&gt;\0&lt;/span&gt;&lt;span class="s1"&gt;33[33m'&lt;/span&gt;
&lt;span class="nv"&gt;RED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;$'&lt;/span&gt;&lt;span class="se"&gt;\0&lt;/span&gt;&lt;span class="s1"&gt;33[91m'&lt;/span&gt;
&lt;span class="nv"&gt;RESET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;$'&lt;/span&gt;&lt;span class="se"&gt;\0&lt;/span&gt;&lt;span class="s1"&gt;33[0m'&lt;/span&gt;

&lt;span class="c"&gt;# Extract fields using jq. Remember to install jq&lt;/span&gt;
&lt;span class="c"&gt;# Get Model Name&lt;/span&gt;
&lt;span class="nv"&gt;MODEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$input&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.model.display_name'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="c"&gt;# Get Used Percentage, Total Outout Tokens and Total Input Tokens, save to variables&lt;/span&gt;
&lt;span class="c"&gt;# The "// 0" provides a fallback if the field is null&lt;/span&gt;
&lt;span class="nv"&gt;PCT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$input&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.context_window.used_percentage // 0'&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-f1&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;OTOK&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$input&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.context_window.total_output_tokens // 0'&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-f1&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;ITOK&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$input&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.context_window.total_input_tokens // 0'&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-f1&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Context progress bar, yey&lt;/span&gt;
&lt;span class="nv"&gt;BAR_WIDTH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;10
&lt;span class="nv"&gt;FILLED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;PCT &lt;span class="o"&gt;*&lt;/span&gt; BAR_WIDTH &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="k"&gt;))&lt;/span&gt;
&lt;span class="nv"&gt;EMPTY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;BAR_WIDTH &lt;span class="o"&gt;-&lt;/span&gt; FILLED&lt;span class="k"&gt;))&lt;/span&gt;
&lt;span class="nv"&gt;BAR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$FILLED&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; 0 &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;BAR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"%&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;FILLED&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;s"&lt;/span&gt; | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt; &lt;span class="s1"&gt;'▓'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$EMPTY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; 0 &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;BAR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BAR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"%&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;EMPTY&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;s"&lt;/span&gt; | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt; &lt;span class="s1"&gt;'░'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# Pick bar color based on usage. &amp;lt; 50 green, &amp;lt; 80 yello, otherwise red&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PCT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-lt&lt;/span&gt; 50 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nv"&gt;BAR_COLOR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$GREEN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PCT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-lt&lt;/span&gt; 80 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nv"&gt;BAR_COLOR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$YELLOW&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;else
    &lt;/span&gt;&lt;span class="nv"&gt;BAR_COLOR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$RED&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;  &lt;span class="c"&gt;# bright red&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# Git status for folder, if available&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;git rev-parse &lt;span class="nt"&gt;--git-dir&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null 2&amp;gt;&amp;amp;1&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nv"&gt;BRANCH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git branch &lt;span class="nt"&gt;--show-current&lt;/span&gt; 2&amp;gt;/dev/null&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="nv"&gt;STAGED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git diff &lt;span class="nt"&gt;--cached&lt;/span&gt; &lt;span class="nt"&gt;--numstat&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="nv"&gt;MODIFIED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git diff &lt;span class="nt"&gt;--numstat&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

    &lt;span class="nv"&gt;GIT_STATUS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;
    &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$STAGED&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; 0 &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;GIT_STATUS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GREEN&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;+&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;STAGED&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;RESET&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$MODIFIED&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; 0 &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;GIT_STATUS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GIT_STATUS&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;YELLOW&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;~&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;MODIFIED&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;RESET&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

    &lt;span class="c"&gt;# Show statusline with git status if available&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$MODEL&lt;/span&gt;&lt;span class="s2"&gt; | i&lt;/span&gt;&lt;span class="nv"&gt;$ITOK&lt;/span&gt;&lt;span class="s2"&gt;, o&lt;/span&gt;&lt;span class="nv"&gt;$OTOK&lt;/span&gt;&lt;span class="s2"&gt; | cntxt &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BAR_COLOR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="nv"&gt;$BAR&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RESET&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PCT&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;% |⎇  &lt;/span&gt;&lt;span class="nv"&gt;$BRANCH&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$GIT_STATUS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="c"&gt;# Else show statusline without git status&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$MODEL&lt;/span&gt;&lt;span class="s2"&gt; | i&lt;/span&gt;&lt;span class="nv"&gt;$ITOK&lt;/span&gt;&lt;span class="s2"&gt;, o&lt;/span&gt;&lt;span class="nv"&gt;$OTOK&lt;/span&gt;&lt;span class="s2"&gt; | cntxt &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BAR_COLOR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="nv"&gt;$BAR&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RESET&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PCT&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;%"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Troubleshooting
&lt;/h2&gt;

&lt;p&gt;a. If statusline isn't loading, check folder structure&lt;br&gt;
b. Make sure statusline.sh file is executable, &lt;code&gt;chmod +x ~/.claude/statusline.sh&lt;/code&gt;&lt;br&gt;
c. Bash scripting is flaky, check quotes and escape characters&lt;/p&gt;

</description>
      <category>claude</category>
      <category>code</category>
      <category>ai</category>
      <category>programming</category>
    </item>
    <item>
      <title>NotebookLM to learn about Canadian Parliament</title>
      <dc:creator>Varun D</dc:creator>
      <pubDate>Thu, 23 Jan 2025 16:31:33 +0000</pubDate>
      <link>https://dev.to/vee_atnameless/notebooklm-to-learn-about-canadian-parliament-46d0</link>
      <guid>https://dev.to/vee_atnameless/notebooklm-to-learn-about-canadian-parliament-46d0</guid>
      <description>&lt;h2&gt;
  
  
  Using NotebookLM to learn about the Canadian Parliament
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://notebooklm.google.com/notebook/29f868f9-fc42-4f88-9070-4804b4f13f62/audio" rel="noopener noreferrer"&gt;Listen to the Podcast here!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I would like to learn about the Canadian Parliament and the best way to do this would be to write down the content in NotebookLM, create a podcast and ask questions.&lt;/p&gt;

&lt;p&gt;The following content is used to create the podcast. I've made it public. Next I would create a short YouTube video with visuals to gain deeper understanding and share this knowledge with others.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://lop.parl.ca/sites/Learn/default/en_CA/ParliamentaryPrimer" rel="noopener noreferrer"&gt;All content taken from this source.&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Canada’s Parliament
&lt;/h2&gt;

&lt;p&gt;Canada is a federation of 10 provinces and 3 territories that share a common federal government. In Parliament, Senators and Members of Parliament work together to represent Canadians from across the country.&lt;/p&gt;

&lt;p&gt;Parliament passes laws that affect all Canadians, in areas like foreign policy and national defence. Each province makes its own laws in other domains, such as education and health care.&lt;/p&gt;

&lt;p&gt;Canada is also a constitutional monarchy. This means that the Monarch is the Head of State and the Prime Minister is the Head of Government. Bills are created and passed by Parliament and signed into law by the Governor General (the Monarch’s representative in Canada).&lt;/p&gt;

&lt;p&gt;There are three parts of Parliament, which all work together to create new laws.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Work of the Senate
&lt;/h2&gt;

&lt;p&gt;The Senate is Parliament’s Upper Chamber.&lt;/p&gt;

&lt;p&gt;Senators are appointed by the Governor General, on the advice of the Prime Minister, to represent Canada’s regions, provinces and territories. The Senate’s 105 seats are distributed by region to ensure equal representation across the country. Senators are Canadians of accomplishment and experience from various professional backgrounds. Senators refine legislation, suggest amendments, introduce bills and debate on current issues. Much of the Senate’s work is done in committee, where Senators use their expertise and hear from witnesses to study bills.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Speaker
&lt;/h3&gt;

&lt;p&gt;The Speaker of the Senate is in charge of debates in the Senate Chamber and oversees the Senate’s operations. The Speaker ensures that the rules, procedures and traditions of the Senate are followed. The thrones behind the Speaker’s Chair are used by the Monarch or Governor General and their spouse.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Senators
&lt;/h3&gt;

&lt;p&gt;Senators are appointed by the Governor General on the advice of the Prime Minister to represent Canada’s provinces and territories. The Senate’s 105 seats are distributed by region to ensure equal representation across the country. Senators are accomplished Canadians from various professional backgrounds. They introduce bills, work to improve legislation passed by the House of Commons, suggest amendments, and debate issues.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Government Representative
&lt;/h3&gt;

&lt;p&gt;The Government Representative in the Senate (who used to be called the Government Leader) is a senator who is appointed by the Prime Minister to represent the Government’s bills and ideas in the Senate. This individual can attend Cabinet meetings and is responsible for answering questions about the Government’s bills.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Government Liaison
&lt;/h3&gt;

&lt;p&gt;The Government Liaison (who used to be called the Whip) ensures that the other senators have the information they need to vote on a bill. This senator also helps organize the timing of votes in the Senate Chamber.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Leader of the Opposition
&lt;/h3&gt;

&lt;p&gt;The Leader of the Opposition in the Senate is a senator who belongs to the same party as the Official Opposition in the House of Commons. This individual is chosen by the Leader of the Opposition in the House of Commons to help organize opposition to bills being discussed in the Senate Chamber and committees.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Clerk of the Senate and Clerk of the Parliaments
&lt;/h3&gt;

&lt;p&gt;The Clerk of the Senate and the Clerk of the Parliaments are two positions typically held by one person, who is the chief administrative officer of the Senate. The Clerk of the Senate advises the Speaker on procedural matters, supports the legislative process and has many duties related to the overall management of the Senate. The Clerk of the Parliaments is the keeper of all original acts (bills that have received Royal Assent) and is responsible for certifying true copies of these acts.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Usher of the Black Rod
&lt;/h3&gt;

&lt;p&gt;The Usher of the Black Rod has many ceremonial and administrative duties, including leading the Speaker’s Parade to start the day and overseeing the security of the Chamber. The Usher of the Black Rod organizes the Speech from the Throne as well as the Royal Assent ceremonies when the Governor General signs bills into law. The Black Rod itself is an ebony cane used to knock on the House of Commons doors to request access to the Chamber.&lt;/p&gt;

&lt;h3&gt;
  
  
  The table officers
&lt;/h3&gt;

&lt;p&gt;The table officers are clerks who advise the Speaker and other senators on procedural matters. They also record proceedings and decisions in the official record of the Senate. They sit at the Clerk’s Table in the Chamber.&lt;/p&gt;

&lt;h3&gt;
  
  
  The stenographers
&lt;/h3&gt;

&lt;p&gt;The stenographers produce the official record of the debates, discussions and decisions in the Senate. This record, commonly known as Hansard, is published in English and French after each sitting day.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pages
&lt;/h3&gt;

&lt;p&gt;Pages are university students from across Canada who are hired to support and assist the senators in the Chamber and in committee meetings.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Mace
&lt;/h3&gt;

&lt;p&gt;The Mace is the symbol of the Senate’s authority and the Senate cannot hold proceedings without it. When the Senate is sitting, it is carried by the Mace Bearer during the Speaker’s Parade and placed on the Clerk’s Table pointing toward the Thrones. Once the Mace is laid on the Table, the Senate is officially in session.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Work of the House of Commons
&lt;/h2&gt;

&lt;p&gt;The House of Commons is Parliament’s elected Lower Chamber.&lt;/p&gt;

&lt;p&gt;Each of the 338 Members of Parliament (MPs) represents a specific geographic area in Canada, known as a constituency. MPs bring the concerns of the people who elected them to the House of Commons. They spend much of their time debating, voting and participating in committees.&lt;/p&gt;

&lt;p&gt;Most MPs belong to a political party. Normally, the leader of the party with the most seats becomes the Prime Minister, and the second-largest party becomes the Official Opposition.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Speaker of the House
&lt;/h3&gt;

&lt;p&gt;The Speaker of the House maintains order in the Chamber and must be impartial. All questions, speeches and debates are directed to the Speaker, who ensures that the rules, procedures and traditions of the House are followed and applied to all MPs equally. The Speaker – who is an elected MP – also oversees the administration and finances of the House. The Speaker sits in the Speaker’s Chair in the centre of the Chamber.&lt;/p&gt;

&lt;h3&gt;
  
  
  Government MPs, including the Prime Minister
&lt;/h3&gt;

&lt;p&gt;Government MPs, including the Prime Minister and Cabinet ministers, form the governing party. Government MPs decide for the most part what legislation is discussed in the Chamber. They propose new laws and policies for the country, which are then debated by all the MPs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Opposition MPs challenge
&lt;/h3&gt;

&lt;p&gt;Opposition MPs challenge government policies and hold the Government accountable for its actions. When the House is sitting, opposition MPs play an important role in questioning the Government about its actions and decisions during Question Period.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Prime Minister
&lt;/h3&gt;

&lt;p&gt;The Prime Minister is the Head of Government. They have many roles including political party leader, Cabinet leader and Member of Parliament (MP). The Prime Minister guides government policy, determines its agenda and selects a Cabinet, primarily from the governing party’s elected MPs. The Prime Minister sits to the right of the Speaker in the 11th seat.&lt;/p&gt;

&lt;h3&gt;
  
  
  Leader of the Official Opposition
&lt;/h3&gt;

&lt;p&gt;The Official Opposition is the party with the second-highest number of elected MPs. The Official Opposition holds the government to account and challenges its policies. The Leader of the Official Opposition takes a lead role in debating and suggesting changes to government legislation. The Official Opposition party sits directly opposite from the Prime Minister and government members.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Clerk of the House
&lt;/h3&gt;

&lt;p&gt;The Clerk of the House and table officers sit at the table in front of the Speaker’s Chair and provide procedural advice to the Speaker and MPs. This table is called the Clerk’s Table. The Clerk is the chief administrative officer of the House and advises the Speaker on parliamentary procedure. Together, the Clerk and the table officers provide advice on the rules in the Chamber, count the votes and keep the official record of decisions made in the Chamber.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Sergeant-at-Arms
&lt;/h3&gt;

&lt;p&gt;The Sergeant-at-Arms is responsible for the security of the House and maintains order in the Chamber based on instruction from the Speaker. Each sitting day begins with the Speaker’s Parade – a ceremonial procession in which the Sergeant-at-Arms carries the Mace while escorting the Speaker to the Chamber.&lt;/p&gt;

&lt;h3&gt;
  
  
  Proceedings and verification officers
&lt;/h3&gt;

&lt;p&gt;Proceedings and verification officers create an official record of the discussions and decisions made in the Chamber. This record, commonly known as Hansard, is published in English and French after each sitting day.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pages
&lt;/h3&gt;

&lt;p&gt;Pages are first-year university students from across Canada who work for the House of Commons. They carry messages and deliver documents to MPs in the Chamber.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Mace
&lt;/h3&gt;

&lt;p&gt;The Mace is the symbol of the Speaker’s authority and the right of the House of Commons to meet and pass new laws. The Mace is carried into the Chamber by the Sergeant-at-Arms and placed on the Clerk’s Table. It is a rule that the House cannot meet without the Mace in the Chamber.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does bill become a law?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Step 1: A bill (proposed law) is introduced in either the Senate or the House of Commons.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Step 2: Parliamentarians debate the bill and vote to decide whether it should be studied further.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Step 3: If the bill passes, it is sent to a committee, which studies it in depth and may suggest changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Step 4: The bill goes back for a final debate and vote, based on the committee’s report.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Step 5: If the bill passes the vote, it is sent to the other Chamber, where it goes through the same process.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Step 6: Once the bill has been passed by both Chambers in identical form, it goes to the Governor General for Royal Assent and becomes Canadian law.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>notebooklm</category>
      <category>google</category>
      <category>ai</category>
      <category>podcast</category>
    </item>
    <item>
      <title>New DigitalOcean Droplet Setup</title>
      <dc:creator>Varun D</dc:creator>
      <pubDate>Wed, 22 Jan 2025 23:48:26 +0000</pubDate>
      <link>https://dev.to/vee_atnameless/new-digitalocean-droplet-setup-1172</link>
      <guid>https://dev.to/vee_atnameless/new-digitalocean-droplet-setup-1172</guid>
      <description>&lt;p&gt;New droplet created specifically for API hosting.&lt;br&gt;
2GB Ram 50GB storage&lt;br&gt;
Supabase as DB&lt;/p&gt;

&lt;p&gt;About CAD 16/mo&lt;/p&gt;

&lt;p&gt;Add SSH key on creation of Droplet&lt;/p&gt;


&lt;h3&gt;
  
  
  1. &lt;strong&gt;Initial Connection to Your Droplet&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Log in to your droplet using SSH:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   ssh root@your_server_ip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. &lt;strong&gt;Update the System&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Update the package lists and upgrade installed packages:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt upgrade &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Optionally, remove unnecessary packages:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   apt autoremove &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. &lt;strong&gt;Create a New User&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Add a new user (replace &lt;code&gt;your_username&lt;/code&gt; with the desired username):
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   adduser your_username
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Grant the new user sudo privileges:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;your_username
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. &lt;strong&gt;Set Up SSH for the New User&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Switch to the new user:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   su - your_username
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Create the &lt;code&gt;.ssh&lt;/code&gt; directory and set proper permissions:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ~/.ssh &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;chmod &lt;/span&gt;700 ~/.ssh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Copy your public SSH key to the new user’s &lt;code&gt;authorized_keys&lt;/code&gt; file:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   nano ~/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Paste your public key and save the file.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set proper permissions:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;chmod &lt;/span&gt;600 ~/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Exit back to the root user:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;exit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Test logging in as the new user:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   ssh your_username@your_server_ip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. &lt;strong&gt;Disable Root Login&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Edit the SSH configuration file:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/ssh/sshd_config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Find and set the following:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   PermitRootLogin no
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Optionally, disable password authentication for additional security:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   PasswordAuthentication no
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Restart the SSH service:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart ssh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  6. &lt;strong&gt;Install Docker&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If you use ufw or firewalld to manage firewall settings, be aware that when you expose container ports using Docker, these ports bypass your firewall rules. For more information, refer to &lt;a href="https://docs.docker.com/engine/network/packet-filtering-firewalls/#docker-and-ufw" rel="noopener noreferrer"&gt;Docker and ufw&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Docker is only compatible with iptables-nft and iptables-legacy. Firewall rules created with nft are not supported on a system with Docker installed. Make sure that any firewall rulesets you use are created with iptables or ip6tables, and that you add them to the DOCKER-USER chain, see Packet filtering and firewalls.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Remove old stuff if needed:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;pkg &lt;span class="k"&gt;in &lt;/span&gt;docker.io docker-doc docker-compose podman-docker containerd runc&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get remove &lt;span class="nv"&gt;$pkg&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Install prerequisites:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;ca-certificates curl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Add Docker's official GPG key:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="nb"&gt;sudo install&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; 0755 &lt;span class="nt"&gt;-d&lt;/span&gt; /etc/apt/keyrings
&lt;span class="nb"&gt;sudo &lt;/span&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://download.docker.com/linux/debian/gpg &lt;span class="nt"&gt;-o&lt;/span&gt; /etc/apt/keyrings/docker.asc
&lt;span class="nb"&gt;sudo chmod &lt;/span&gt;a+r /etc/apt/keyrings/docker.asc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Set up the Docker repository:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Add the repository to Apt sources:&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"deb [arch=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;dpkg &lt;span class="nt"&gt;--print-architecture&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
  &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; /etc/os-release &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$VERSION_CODENAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; stable"&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/apt/sources.list.d/docker.list &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Install Docker:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Add your user to the Docker group to avoid running through sudo:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; docker your_username
newgrp docker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Test run. This will not run due to permission issue.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run hello-world
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Enable and start Docker (if above didn't work):
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;docker
   &lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start docker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  For more info, check official docks on &lt;a href="https://docs.docker.com/engine/install/linux-postinstall/" rel="noopener noreferrer"&gt;linux post install&lt;/a&gt;.
&lt;/h2&gt;

&lt;h3&gt;
  
  
  7. &lt;strong&gt;Install Caddy&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Download the official Caddy installation script:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; debian-keyring debian-archive-keyring apt-transport-https curl
curl &lt;span class="nt"&gt;-1sLf&lt;/span&gt; &lt;span class="s1"&gt;'https://dl.cloudsmith.io/public/caddy/stable/gpg.key'&lt;/span&gt; | &lt;span class="nb"&gt;sudo &lt;/span&gt;gpg &lt;span class="nt"&gt;--dearmor&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl &lt;span class="nt"&gt;-1sLf&lt;/span&gt; &lt;span class="s1"&gt;'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt'&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/apt/sources.list.d/caddy-stable.list

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Install Caddy:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
   &lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; caddy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Enable and start Caddy:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;caddy
   &lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start caddy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  8. &lt;strong&gt;Secure Your Firewall&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Allow SSH, HTTP, and HTTPS through the firewall:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; ufw
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw default deny incoming
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw default allow outgoing

   &lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow OpenSSH
   &lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow 80
   &lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow 443

&lt;span class="c"&gt;# Use if keeping behind a DNS (e.g., cloudflare)&lt;/span&gt;
udo ufw allow from 203.0.X.X
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Enable the firewall:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;ufw &lt;span class="nb"&gt;enable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  9. &lt;strong&gt;Verify Installations&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Check Docker:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  docker &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Check Caddy:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  caddy version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  10. &lt;strong&gt;Optional: Set Up a Basic Caddyfile&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Edit the Caddy configuration:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/caddy/Caddyfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Example configuration for a website:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   yourdomain.com {
       root * /var/www/html
       file_server
   }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Test the Caddyfile:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;caddy validate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Reload Caddy to apply changes:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl reload caddy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






</description>
      <category>digitalocean</category>
      <category>server</category>
      <category>vps</category>
    </item>
    <item>
      <title>[Quickstart] Python FastAPI with uv</title>
      <dc:creator>Varun D</dc:creator>
      <pubDate>Mon, 13 Jan 2025 03:14:05 +0000</pubDate>
      <link>https://dev.to/vee_atnameless/using-uv-instead-of-pip-venv-433k</link>
      <guid>https://dev.to/vee_atnameless/using-uv-instead-of-pip-venv-433k</guid>
      <description>&lt;h2&gt;
  
  
  Install uv for Python package and venv manager
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.astral.sh/uv/getting-started/installation/" rel="noopener noreferrer"&gt;UV Official Docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;brew install uv&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Initialize UV and install FastAPI
&lt;/h2&gt;

&lt;p&gt;Create project folder and move into it&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mkcd myproject&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Initialize uv inside it&lt;/p&gt;

&lt;p&gt;&lt;code&gt;uv init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Add my packages, e.g., FastAPI&lt;/p&gt;

&lt;p&gt;&lt;code&gt;uv add fastapi --extra standard&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup project structure
&lt;/h2&gt;

&lt;p&gt;Create folder /app&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mkcd app&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Add file __init__.py inside /app&lt;br&gt;
Add file main.py inside /app&lt;/p&gt;

&lt;p&gt;&lt;code&gt;touch __init__.py&lt;/code&gt;&lt;br&gt;
&lt;code&gt;touch main.py&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Run fastapi&lt;/p&gt;

&lt;p&gt;&lt;code&gt;uv run fastapi dev&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://fastapi.tiangolo.com/tutorial/first-steps/" rel="noopener noreferrer"&gt;https://fastapi.tiangolo.com/tutorial/first-steps/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Sample API, GET and POST (add this to app/main.py)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Union&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pydantic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastapi.middleware.cors&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;CORSMiddleware&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;


&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Not safe! Add your own allowed domains
&lt;/span&gt;&lt;span class="n"&gt;origins&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt; 

&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_middleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;CORSMiddleware&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;allow_origins&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;origins&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;allow_credentials&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;allow_methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;allow_headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Define what you will receiving in request
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TypePayload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;

&lt;span class="c1"&gt;# Example GET route for app
&lt;/span&gt;&lt;span class="nd"&gt;@app.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;read_root&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello World! FastAPI is working.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Example POST route for app
&lt;/span&gt;&lt;span class="nd"&gt;@app.post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/getdata&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_secret&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;TypePayload&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;output_file.txt&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;formatted_date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%B %d, %Y at %I:%M %p&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;formatted_date&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  [Optional] Setting up logging
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;

&lt;span class="c1"&gt;# Get the univorn logger for the same CLI look
&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;uvicorn&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET request received at root endpoint&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;This is a test error.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>python</category>
      <category>uv</category>
      <category>fastapi</category>
    </item>
    <item>
      <title>Notes on React Typescript</title>
      <dc:creator>Varun D</dc:creator>
      <pubDate>Fri, 13 Oct 2023 14:31:16 +0000</pubDate>
      <link>https://dev.to/vee_atnameless/some-notes-on-react-typescript-1a2m</link>
      <guid>https://dev.to/vee_atnameless/some-notes-on-react-typescript-1a2m</guid>
      <description>&lt;p&gt;Creating a simple component in a new file, &lt;strong&gt;Component.tsx&lt;/strong&gt; being called from &lt;strong&gt;App.tsx&lt;/strong&gt; with props passed to it:&lt;/p&gt;

&lt;h3&gt;
  
  
  App.tsx
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//standard imports&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./Component&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;// Some state example. Array of objects - most common.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ArrayofObj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Lovelace&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;cool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}]&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;default&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
&lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="nx"&gt;mystuff&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;ArrayofObj&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Component.tsx
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Define type of props I get here.&lt;/span&gt;
&lt;span class="c1"&gt;// Any name that makes sense. Notice the [] at the end.&lt;/span&gt;
&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;propTypes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;ArrayofObj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;cool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;}[];&lt;/span&gt;
&lt;span class="c1"&gt;// Specify it's an array using [] at the end!&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Accept prop with propTypes we defined above&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;mystuff&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;propTypes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;// Create the lil pieces to put together later&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mystuff_li&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mystuff&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="sr"&gt;/&amp;gt;{item.name} is {item.age} years old.&amp;lt;/&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// Return the stuffs&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ul&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;friends_li&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ul&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some other common ones...&lt;br&gt;
Callbacks with mouse events can be found by hovering over your own function.&lt;/p&gt;

&lt;p&gt;For example, a button with &lt;code&gt;onClick={handleCancel}&lt;/code&gt; received from parent, the prop type in this case will be:&lt;br&gt;
&lt;code&gt;handleCancel: React.MouseEventHandler&amp;lt;HTMLButtonElement&amp;gt;;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/typescript-cheatsheets/react" rel="noopener noreferrer"&gt;Good resource for TypeScript cheatsheets.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>typescript</category>
    </item>
    <item>
      <title>My Buns are hot. Bun + NextJS</title>
      <dc:creator>Varun D</dc:creator>
      <pubDate>Tue, 03 Oct 2023 19:32:35 +0000</pubDate>
      <link>https://dev.to/vee_atnameless/my-buns-are-hot-bun-nextjs-47ol</link>
      <guid>https://dev.to/vee_atnameless/my-buns-are-hot-bun-nextjs-47ol</guid>
      <description>&lt;p&gt;Started to learn NextJS and thought why not start using Bun.&lt;/p&gt;

&lt;p&gt;Installed bun on my Mac:&lt;br&gt;
&lt;code&gt;curl -fsSL https://bun.sh/install | bash&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Made sure it worked:&lt;br&gt;
&lt;code&gt;bun&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Created my usual NextJS app with Typescript, Tailwind...&lt;br&gt;
&lt;code&gt;bunx create-next-app@latest myappname&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Interesting how npx is bunx. Nice.&lt;/p&gt;

&lt;p&gt;Installed shadcn for my UI needs. I like how it provides me with a boilerplate globals.css and a Tailwind config without complicating anything else. Shadcn is built over Radix UI primitives.&lt;br&gt;
&lt;code&gt;bunx shadcn-ui@latest init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;and get button styles&lt;br&gt;
&lt;code&gt;bunx shadcn-ui@latest add button&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Done! I start my dev server through&lt;br&gt;
&lt;code&gt;bun run dev&lt;/code&gt; &lt;/p&gt;

</description>
      <category>bunjs</category>
      <category>nextjs</category>
      <category>tailwindcss</category>
      <category>react</category>
    </item>
  </channel>
</rss>
